mirror of
https://github.com/2009scape/2009Scape-mobile.git
synced 2026-09-10 18:46:30 -06:00
Cleanup to prepare a new v3
This commit is contained in:
parent
7ecb14534b
commit
27b070167b
1073 changed files with 239 additions and 234570 deletions
154
README.md
154
README.md
|
|
@ -1,146 +1,20 @@
|
|||
[](https://travis-ci.com/github/PojavLauncherTeam/PojavLauncher)
|
||||
# PojavLauncher
|
||||
An open source Minecraft: Java Edition launcher for Android based from Boardwalk. Support up-to Minecraft 1.11
|
||||
(Codes has not been sorted yet, it contains ton of classes without packing to module).
|
||||
|
||||
Discord server: https://discord.gg/6RpEJda
|
||||
## This branch?
|
||||
- Attempt to run Minecraft in OpenJDK, different a bit with Boardwalk 2.
|
||||
|
||||
## iOS version?
|
||||
- Impossible for directly run. There's RoboVM but is AOT Compiler. You could also try UTM with Android-x86.
|
||||
- OpenJDK 9 and GL4ES has iOS port so maybe run in a jailbreaked device. I don't have a Mac OS X device to build one.
|
||||
## Current status
|
||||
- [ ] BinaryExecutor: execute `java` binary, no `JNIInvocation`
|
||||
- [ ] JVDroid OpenJDK 11
|
||||
- [ ] AWT/Swing for mod installer
|
||||
- [ ] OpenGL in OpenJDK environment
|
||||
- [ ] OpenAL 64-bit version
|
||||
- [ ] Input keyboard and mouse events from ART to OpenJDK environment
|
||||
- [ ] Support Minecraft 1.12 and below
|
||||
- [ ] Support Minecraft 1.13 and above
|
||||
- [ ] More...
|
||||
|
||||
## Installing OptiFine?
|
||||
Follow steps [here](https://github.com/khanhduytran0/PojavLauncher/wiki/Install-OptiFine).
|
||||
## Licenses
|
||||
- PojavLauncher is licensed under GPLv3.
|
||||
|
||||
## Installing Forge?
|
||||
Not implemented yet.
|
||||
|
||||
## Known issues
|
||||
- Some Huawei devices can't run Minecraft or OptiFine.
|
||||
- Can't run multiple versions at same time.
|
||||
|
||||
## FAQ
|
||||
### • Unable to drag item in inventory?
|
||||
Disable touchscreen mode. Open Minecraft Settings -> Controls -> Touchscreen Mode: Toggle to OFF.
|
||||
|
||||
### • Unable to install Minecraft 1.9 or above, can't convert library `net.java.dev.jna`?
|
||||
Increase max DX references. Launcher Options -> Settings -> Increase max DX references to 8k.
|
||||
|
||||
### • Other bugs or still not working?
|
||||
#### Report an issue with:
|
||||
- Full error log: press **Show more** and copy.
|
||||
#### If it isn't a Minecraft crash:
|
||||
- Device name
|
||||
- Android version
|
||||
|
||||
## Minecraft versions worked in PojavLauncher 2.4.2
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th align="center" colspan="7">Minecraft version</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Android</th>
|
||||
<th align="center">1.7.10</th>
|
||||
<th align="center">1.8</th>
|
||||
<th align="center">1.9</th>
|
||||
<th align="center">1.10</th>
|
||||
<th align="center">1.11</th>
|
||||
<th align="center">1.12</th>
|
||||
<th align="center">1.12.2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>5.x</td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center">???</td>
|
||||
<td align="center">???</td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6.0</td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center">???</td>
|
||||
<td align="center">???</td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>7.x</td>
|
||||
<td align="center">???</td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8.x</td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center">???</td>
|
||||
<td align="center">???</td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>9.0</td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><b>Yes</b></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10.0</td>
|
||||
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
|
||||
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
|
||||
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
|
||||
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
|
||||
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## OptiFine worked in PojavLauncher 2.4.2
|
||||
|Android version | 9.0 |???|???|Manually Android 10|9.0|
|
||||
|-----------------|------|---|---|-----|-----|
|
||||
|Minecraft version|1.7.10|1.8|1.9| 1.10| 1.11|
|
||||
|OptiFine |OptiFine_1.7.10_HD_U_E7|???|???|OptiFine_1.10_HD_U_H5|OptiFine_1.11_HD_U_F5|
|
||||
|Status |[Worked](https://youtu.be/In_EPebQG7Q)|???|???|[Worked (manually)](https://youtu.be/TJeJcPFgzcI)|[Worked (with 1 hack)](https://youtu.be/eIawM9UmQ88)
|
||||
|
||||
## A note about 1.12.x
|
||||
- Minecraft 1.12.x can be run on Android 8.0 and above by use d8 for desugar and dexing in the latest v2, but will crash in singleplayer.
|
||||
|
||||
## License
|
||||
- PojavLauncher is licensed under [GNU GPLv3](https://github.com/khanhduytran0/PojavLauncher/blob/master/LICENSE).
|
||||
|
||||
## Using libraries & Third party licenses
|
||||
- (v2) Boardwalk: [Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE).
|
||||
- (v2) LegacyLauncher: (unknown license).<br>
|
||||
- (all) Android Support Libraries & DX Dexer: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
|
||||
- (all) gl4es: [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).<br>
|
||||
- (v3) BusyBox: [GNU GPLv2 License](https://busybox.net/license.html).<br>
|
||||
- (v3) OpenJDK: [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html).<br>
|
||||
- (v3) PRoot: [GNU GPLv2 License](https://github.com/termux/proot/blob/master/COPYING).<br>
|
||||
- (v3) XVnc: [GNU GPLv3 License](https://github.com/theqvd/qvd-client-android/blob/master/LICENSE.txt).
|
||||
- (all) LWJGL 2: [Legacy LWJGL License](http://legacy.lwjgl.org/license.php.html).<br>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ android {
|
|||
minSdkVersion 21
|
||||
targetSdkVersion 26
|
||||
versionCode 156235
|
||||
versionName "2.5.3_6400b_20200802"
|
||||
versionName "3.2.0_6401b_20200822"
|
||||
multiDexEnabled true //important
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
app/src/main/assets/ClassWrapper.jar
Normal file
BIN
app/src/main/assets/ClassWrapper.jar
Normal file
Binary file not shown.
|
|
@ -1,18 +1,27 @@
|
|||
%s BETA (Minecraft Java launcher for Android), version %s by Tran Khanh Duy (based from "Boardwalk" app)
|
||||
Using libraries:
|
||||
• Apache Commons Codec version 1.14.
|
||||
• gl4es: OpenGL for OpenGL ES devices by lunixbochs and ptitSeb.
|
||||
• javax.sound.midi backport for Android by kshoji.
|
||||
• LegacyLauncher: Open source Minecraft LaunchWrapper by Mojang.
|
||||
• LWJGL %s.
|
||||
• openal_soft: OpenAL port for Android devices by apportable.
|
||||
• PojavDX (dx 1.16): tool to convert java bytecode to dex.
|
||||
• Android HandleView of EditText for easy resize for custom controls.
|
||||
• Java AWT Implementation includes:
|
||||
- Boardwalk's makeshift.
|
||||
- OpenJDK 7 codes implementation.
|
||||
- Developer codes (copy text, open browser,...)
|
||||
* Notes:
|
||||
- This app is under development and will not be stable.
|
||||
- This app only use LWJGL2 and didn't have a JRE8 desugar so 1.13 or above versions will not supported.
|
||||
%s BETA (Minecraft Java launcher for Android), version %s by Tran Khanh Duy (based from "Boardwalk" app)<br>
|
||||
* Using libraries:<br>
|
||||
• ClassWrapperMC: A simple wrapper to help launching Minecraft LaunchWrapper on JRE9 and later.<br>
|
||||
• gl4es: OpenGL for OpenGL ES devices by lunixbochs and ptitSeb.<br>
|
||||
• LegacyLauncher: Open source Minecraft LaunchWrapper by Mojang.<br>
|
||||
• OpenJDK JRE 10 for Android by dongfangxunlei.<br>
|
||||
• PRoot special build of Termux to bypass SECCOMP for OpenJDK run in Android 8.<br>
|
||||
• TheQVD XVnc Pro (including Android VNC Viewer).<br>
|
||||
• Some Debian libraries (X11, FreeType...)<br>
|
||||
• Busybox.<br>
|
||||
• Apache Commons Compress.<br>
|
||||
• LWJGL.<br>
|
||||
* License:<br>
|
||||
• This application and ClassWrapperMC are licensed under <a href="https://github.com/khanhduytran0/PojavLauncher/blob/master/LICENSE">Apache License 2.0</a>.<br>
|
||||
* Third party licenses:<br>
|
||||
• Apache Commons Compress (unknown or Apache License 2.0).<br>
|
||||
• gl4es: <a href="https://github.com/ptitSeb/gl4es/blob/master/LICENSE">MIT License</a>.<br>
|
||||
• LegacyLauncher: (unknown license).<br>
|
||||
• OpenJDK: <a href="https://openjdk.java.net/legal/gplv2+ce.html">GNU GPLv2 License</a>.<br>
|
||||
• PRoot: <a href="https://github.com/termux/proot/blob/master/COPYING">GNU GPLv2 License</a>.<br>
|
||||
• TheQVD XVnc Pro: <a href="https://github.com/theqvd/qvd-client-android/blob/master/LICENSE.txt">GNU GPLv3 License</a>.<br>
|
||||
• LWJGL: <a href="http://legacy.lwjgl.org/license.php.html">LWJGL 2's License</a>.<br><br>
|
||||
• Debian libraries: Multiple licenses.<br>
|
||||
• BusyBox: <a href="https://busybox.net/license.html">GNU GPL License</a><br>
|
||||
* Notes:<br>
|
||||
- This app is under development and will not be stable.<br>
|
||||
- This app is not affiliated with Minecraft, Mojang or Microsoft.
|
||||
|
|
|
|||
BIN
app/src/main/assets/busybox-arm64
Normal file
BIN
app/src/main/assets/busybox-arm64
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,133 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
<xs:element name="Configuration" type="ConfigurationType"/>
|
||||
<xs:complexType name="ConfigurationType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Properties" type="PropertiesType"/>
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="Filters" type="FiltersType"/>
|
||||
<xs:element name="Filter" type="FilterType"/>
|
||||
</xs:choice>
|
||||
<xs:element name="ThresholdFilter" type="ThresholdFilterType"/>
|
||||
<xs:element name="Appenders" type="AppendersType"/>
|
||||
<xs:element name="Loggers" type="LoggersType"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="packages" type="xs:string"/>
|
||||
<xs:attribute name="status" type="xs:string"/>
|
||||
<xs:attribute name="strict" type="xs:string"/>
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="advertiser" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="PropertiesType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Property" type="PropertyType"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AppenderType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Layout" type="LayoutType" minOccurs="0"/>
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="Filters" type="FiltersType"/>
|
||||
<xs:element name="Filter" type="FilterType"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="type" type="xs:string" use="required"/>
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
<xs:attribute name="fileName" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="RootType">
|
||||
<xs:sequence>
|
||||
<xs:element name="AppenderRef" type="AppenderRefType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="level" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="PropertyType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="KeyValuePairType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="key" type="xs:string"/>
|
||||
<xs:attribute name="value" type="xs:string"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AppendersType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Appender" type="AppenderType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AppenderRefType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="ref" type="xs:string" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="LoggerType">
|
||||
<xs:sequence>
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="Filters" type="FiltersType"/>
|
||||
<xs:element name="Filter" type="FilterType"/>
|
||||
</xs:choice>
|
||||
<xs:element name="AppenderRef" type="AppenderRefType"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
<xs:attribute name="level" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="additivity" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="FilterType" mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="KeyValuePair" type="KeyValuePairType" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="type" type="xs:string" use="required"/>
|
||||
<xs:attribute name="level" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="marker" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="onMatch" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="onMismatch" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="FiltersType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Filter" type="FilterType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="LoggersType" mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="Logger" type="LoggerType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element name="Root" type="RootType" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="LayoutType" mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="Pattern" type="xs:string" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="Type" type="xs:string" use="required"/>
|
||||
<xs:attribute name="Pattern" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="ThresholdFilterType">
|
||||
<xs:attribute name="level" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="onMatch" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="onMismatch" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!--DTD generated by XMLSpy v2011 rel. 3 sp1 (x64) (http://www.altova.com)-->
|
||||
<!--the entity declarations may be overridden in the internal subset-->
|
||||
<!--namespace prefixes-->
|
||||
<!ENTITY % log4j_prefix "log4j">
|
||||
<!--namespace prefix to namespace uri mappings-->
|
||||
<!ENTITY % log4j_prefix.. "%log4j_prefix;:">
|
||||
<!--namespaces attributes for root element-->
|
||||
<!ENTITY % documentElementAttributes " xmlns:%log4j_prefix; CDATA 'http://logging.apache.org/log4j/2.0/events'">
|
||||
<!--the declarations below should not be modified-->
|
||||
<!--element name mappings-->
|
||||
<!ENTITY % log4j..Events "%log4j_prefix..;Events">
|
||||
<!ENTITY % log4j..Event "%log4j_prefix..;Event">
|
||||
<!ENTITY % log4j..Message "%log4j_prefix..;Message">
|
||||
<!ENTITY % log4j..NDC "%log4j_prefix..;NDC">
|
||||
<!ENTITY % log4j..Throwable "%log4j_prefix..;Throwable">
|
||||
<!ENTITY % log4j..LocationInfo "%log4j_prefix..;LocationInfo">
|
||||
<!ENTITY % log4j..Properties "%log4j_prefix..;Properties">
|
||||
<!ENTITY % log4j..Data "%log4j_prefix..;Data">
|
||||
<!--element and attribute declarations-->
|
||||
<!--Log4J 2.0 XML Schema-->
|
||||
<!ELEMENT %log4j..Events; ((%log4j..Event;)*)>
|
||||
<!ATTLIST %log4j..Events;
|
||||
%documentElementAttributes;
|
||||
>
|
||||
<!ELEMENT %log4j..Event; (%log4j..Message;, (%log4j..NDC;)?, (%log4j..Throwable;)?, (%log4j..LocationInfo;)?, (%log4j..Properties;)?)>
|
||||
<!ATTLIST %log4j..Event;
|
||||
logger CDATA #REQUIRED
|
||||
timestamp NMTOKEN #REQUIRED
|
||||
level (OFF | FATAL | ERROR | WARN | INFO | DEBUG | TRACE | ALL) #REQUIRED
|
||||
thread CDATA #REQUIRED
|
||||
>
|
||||
<!ELEMENT %log4j..Message; ANY>
|
||||
<!ELEMENT %log4j..NDC; ANY>
|
||||
<!ELEMENT %log4j..Throwable; ANY>
|
||||
<!ELEMENT %log4j..LocationInfo; EMPTY>
|
||||
<!ATTLIST %log4j..LocationInfo;
|
||||
class CDATA #REQUIRED
|
||||
method CDATA #REQUIRED
|
||||
file CDATA #REQUIRED
|
||||
line NMTOKEN #REQUIRED
|
||||
>
|
||||
<!ELEMENT %log4j..Properties; ((%log4j..Data;)+)>
|
||||
<!ELEMENT %log4j..Data; EMPTY>
|
||||
<!ATTLIST %log4j..Data;
|
||||
name CDATA #REQUIRED
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- edited with XMLSpy v2011 rel. 3 sp1 (x64) (http://www.altova.com) by Gary Gregory (Rocket Software) -->
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:log4j="http://logging.apache.org/log4j/2.0/events" targetNamespace="http://logging.apache.org/log4j/2.0/events" elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
<xs:element name="Events">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Log4J 2.0 XML Schema for XML log event files.</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Event" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Message"/>
|
||||
<xs:element name="NDC" minOccurs="0"/>
|
||||
<xs:element name="Throwable" minOccurs="0"/>
|
||||
<xs:element name="LocationInfo" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="class" type="xs:string" use="required"/>
|
||||
<xs:attribute name="method" type="xs:string" use="required"/>
|
||||
<xs:attribute name="file" type="xs:string" use="required"/>
|
||||
<xs:attribute name="line" type="xs:int" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="Properties" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Data" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
<xs:attribute name="value" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="logger" type="xs:string" use="required"/>
|
||||
<xs:attribute name="timestamp" type="xs:long" use="required"/>
|
||||
<xs:attribute name="level" type="log4j:LevelEnum" use="required"/>
|
||||
<xs:attribute name="thread" type="xs:string" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:simpleType name="LevelEnum">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="OFF"/>
|
||||
<xs:enumeration value="FATAL"/>
|
||||
<xs:enumeration value="ERROR"/>
|
||||
<xs:enumeration value="WARN"/>
|
||||
<xs:enumeration value="INFO"/>
|
||||
<xs:enumeration value="DEBUG"/>
|
||||
<xs:enumeration value="TRACE"/>
|
||||
<xs:enumeration value="ALL"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.graphics;
|
||||
import java.lang.reflect.*;
|
||||
/**
|
||||
* PixelXorXfermode implements a simple pixel xor (op ^ src ^ dst).
|
||||
* This transformation does not follow premultiplied conventions, therefore
|
||||
* this mode *always* returns an opaque color (alpha == 255). Thus it is
|
||||
* not really usefull for operating on blended colors.
|
||||
*/
|
||||
@Deprecated
|
||||
public class PixelXorXfermode extends Xfermode {
|
||||
public PixelXorXfermode(int opColor) {
|
||||
try {
|
||||
Field field_nativeInstance = getClass().getDeclaredField("native_instance");
|
||||
field_nativeInstance.setAccessible(true);
|
||||
field_nativeInstance.set(null, nativeCreate(opColor));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private static native int nativeCreate(int opColor);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.3 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import com.android.internal.awt.AndroidGraphics2D;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.VolatileImage;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
||||
public class AndroidGraphicsConfiguration extends GraphicsConfiguration {
|
||||
|
||||
@Override
|
||||
public BufferedImage createCompatibleImage(int width, int height) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage createCompatibleImage(int width, int height,
|
||||
int transparency) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolatileImage createCompatibleVolatileImage(int width, int height) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolatileImage createCompatibleVolatileImage(int width, int height,
|
||||
int transparency) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds() {
|
||||
Canvas c = AndroidGraphics2D.getAndroidCanvas();
|
||||
if(c != null)
|
||||
return new Rectangle(0, 0, c.getWidth(), c.getHeight());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel(int transparency) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getDefaultTransform() {
|
||||
return new AffineTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsDevice getDevice() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getNormalizingTransform() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class AndroidGraphicsDevice extends GraphicsDevice
|
||||
{
|
||||
public GraphicsConfiguration[] mConfigurations = new GraphicsConfiguration[]{new AndroidGraphicsConfiguration()};
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration[] getConfigurations() {
|
||||
return mConfigurations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration getDefaultConfiguration() {
|
||||
return mConfigurations[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIDstring() {
|
||||
return "Android";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return TYPE_IMAGE_BUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @author Alexey A. Petrenko, Oleg V. Khaschansky
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* AndroidGraphicsEnvironment implementation
|
||||
*
|
||||
*/
|
||||
public class AndroidGraphicsEnvironment extends CommonGraphicsEnvironment
|
||||
{
|
||||
public GraphicsDevice[] mGraphicsDevices = new GraphicsDevice[]{new AndroidGraphicsDevice()};
|
||||
|
||||
@Override
|
||||
public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
|
||||
return mGraphicsDevices[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsDevice[] getScreenDevices() throws HeadlessException {
|
||||
return mGraphicsDevices;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.peer.FontPeer;
|
||||
|
||||
import org.apache.harmony.awt.gl.MultiRectArea;
|
||||
import org.apache.harmony.awt.gl.font.AndroidFont;
|
||||
import org.apache.harmony.awt.gl.font.FontManager;
|
||||
import org.apache.harmony.awt.gl.font.FontMetricsImpl;
|
||||
import org.apache.harmony.awt.gl.font.AndroidFontManager;
|
||||
import org.apache.harmony.awt.wtk.NativeWindow;
|
||||
import org.apache.harmony.awt.wtk.WindowFactory;
|
||||
import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.content.Context;
|
||||
import org.apache.harmony.awt.gl.*;
|
||||
|
||||
public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
|
||||
|
||||
public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
|
||||
return new AndroidGraphicsEnvironment();
|
||||
}
|
||||
|
||||
public Font embedFont(String fontFilePath) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public FontManager getFontManager() {
|
||||
return AndroidFontManager.inst;
|
||||
}
|
||||
|
||||
public FontMetrics getFontMetrics(Font font) {
|
||||
return new FontMetricsImpl(font);
|
||||
}
|
||||
|
||||
public FontPeer getFontPeer(Font font) {
|
||||
//return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
|
||||
return new AndroidFont(font.getName(), font.getStyle(), font.getSize());
|
||||
}
|
||||
|
||||
public Graphics2D getGraphics2D(NativeWindow win, int translateX,
|
||||
int translateY, MultiRectArea clip) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Graphics2D getGraphics2D(NativeWindow win, int translateX,
|
||||
int translateY, int width, int height) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Graphics2D getGraphics2D(Context ctx, Canvas c, Paint p) {
|
||||
return AndroidGraphics2D.getInstance(ctx, c, p);
|
||||
}
|
||||
|
||||
public Graphics2D getGraphics2D(Canvas c, Paint p) {
|
||||
throw new RuntimeException("Not supported!");
|
||||
}
|
||||
|
||||
public Graphics2D getGraphics2D() {
|
||||
return AndroidGraphics2D.getInstance();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.awt;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
//import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.apache.harmony.awt.gl.image.DecodingImageSource;
|
||||
import org.apache.harmony.awt.gl.image.ImageDecoder;
|
||||
import org.apache.harmony.awt.internal.nls.Messages;
|
||||
|
||||
public class AndroidImageDecoder extends ImageDecoder {
|
||||
|
||||
private static final int hintflags =
|
||||
ImageConsumer.SINGLEFRAME | // PNG is a static image
|
||||
ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
|
||||
ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
|
||||
|
||||
// Each pixel is a grayscale sample.
|
||||
private static final int PNG_COLOR_TYPE_GRAY = 0;
|
||||
// Each pixel is an R,G,B triple.
|
||||
private static final int PNG_COLOR_TYPE_RGB = 2;
|
||||
// Each pixel is a palette index, a PLTE chunk must appear.
|
||||
private static final int PNG_COLOR_TYPE_PLTE = 3;
|
||||
// Each pixel is a grayscale sample, followed by an alpha sample.
|
||||
private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
|
||||
// Each pixel is an R,G,B triple, followed by an alpha sample.
|
||||
private static final int PNG_COLOR_TYPE_RGBA = 6;
|
||||
|
||||
private static final int NB_OF_LINES_PER_CHUNK = 1; // 0 = full image
|
||||
|
||||
Bitmap bm; // The image as decoded by Android
|
||||
|
||||
// Header information
|
||||
int imageWidth; // Image size
|
||||
int imageHeight;
|
||||
int colorType; // One of the PNG_ constants from above
|
||||
int bitDepth; // Number of bits per color
|
||||
byte cmap[]; // The color palette for index color models
|
||||
ColorModel model; // The corresponding AWT color model
|
||||
|
||||
boolean transferInts; // Is transfer of type int or byte?
|
||||
int dataElementsPerPixel;
|
||||
|
||||
// Buffers for decoded image data
|
||||
byte byteOut[];
|
||||
int intOut[];
|
||||
|
||||
|
||||
public AndroidImageDecoder(DecodingImageSource src, InputStream is) {
|
||||
super(src, is);
|
||||
dataElementsPerPixel = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* All the decoding is done in Android
|
||||
*
|
||||
* AWT???: Method returns only once the image is completly
|
||||
* decoded; decoding is not done asynchronously
|
||||
*/
|
||||
public void decodeImage() throws IOException {
|
||||
try {
|
||||
bm = BitmapFactory.decodeStream(inputStream);
|
||||
if (bm == null) {
|
||||
throw new IOException("Input stream empty and no image cached");
|
||||
}
|
||||
|
||||
// Check size
|
||||
imageWidth = bm.getWidth();
|
||||
imageHeight = bm.getHeight();
|
||||
if (imageWidth < 0 || imageHeight < 0 ) {
|
||||
throw new RuntimeException("Illegal image size: "
|
||||
+ imageWidth + ", " + imageHeight);
|
||||
}
|
||||
|
||||
// We got the image fully decoded; now send all image data to AWT
|
||||
setDimensions(imageWidth, imageHeight);
|
||||
model = createColorModel();
|
||||
setColorModel(model);
|
||||
setHints(hintflags);
|
||||
setProperties(new Hashtable<Object, Object>()); // Empty
|
||||
sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight);
|
||||
imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
imageComplete(ImageConsumer.IMAGEERROR);
|
||||
throw e;
|
||||
} finally {
|
||||
closeStream();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the AWT color model
|
||||
*
|
||||
* ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model
|
||||
*
|
||||
* However, we leave the code here for a more powerfull decoder
|
||||
* that returns a native model, and the conversion is then handled
|
||||
* in AWT. With such a decoder, we would need to get the colorType,
|
||||
* the bitDepth, (and the color palette for an index color model)
|
||||
* from the image and construct the correct color model here.
|
||||
*/
|
||||
private ColorModel createColorModel() {
|
||||
ColorModel cm = null;
|
||||
int bmModel = 5; // TODO This doesn't exist: bm.getColorModel();
|
||||
cmap = null;
|
||||
|
||||
switch (bmModel) {
|
||||
// A1_MODEL
|
||||
case 1:
|
||||
colorType = PNG_COLOR_TYPE_GRAY;
|
||||
bitDepth = 1;
|
||||
break;
|
||||
|
||||
// A8_MODEL
|
||||
case 2:
|
||||
colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
|
||||
bitDepth = 8;
|
||||
break;
|
||||
|
||||
// INDEX8_MODEL
|
||||
// RGB_565_MODEL
|
||||
// ARGB_8888_MODEL
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
|
||||
bitDepth = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
switch (colorType) {
|
||||
|
||||
case PNG_COLOR_TYPE_GRAY: {
|
||||
if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// Create gray color model
|
||||
int numEntries = 1 << bitDepth;
|
||||
int scaleFactor = 255 / (numEntries-1);
|
||||
byte comps[] = new byte[numEntries];
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
comps[i] = (byte) (i * scaleFactor);
|
||||
}
|
||||
cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps);
|
||||
|
||||
transferInts = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNG_COLOR_TYPE_RGB: {
|
||||
if (bitDepth != 8) {
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF);
|
||||
|
||||
transferInts = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNG_COLOR_TYPE_PLTE: {
|
||||
if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
if (cmap == null) {
|
||||
throw new IllegalStateException("Palette color type is not supported");
|
||||
}
|
||||
|
||||
cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false);
|
||||
|
||||
transferInts = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA: {
|
||||
if (bitDepth != 8) {
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
|
||||
true, false,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
|
||||
transferInts = false;
|
||||
dataElementsPerPixel = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNG_COLOR_TYPE_RGBA: {
|
||||
if (bitDepth != 8) {
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
cm = ColorModel.getRGBdefault();
|
||||
|
||||
transferInts = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// awt.3C=Unknown PNG color type
|
||||
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return cm;
|
||||
}
|
||||
|
||||
private void sendPixels(int nbOfLinesPerChunk) {
|
||||
int w = imageWidth;
|
||||
int h = imageHeight;
|
||||
int n = 1;
|
||||
if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) {
|
||||
n = nbOfLinesPerChunk;
|
||||
}
|
||||
|
||||
if (transferInts) {
|
||||
// Create output buffer
|
||||
intOut = new int[w * n];
|
||||
for (int yi = 0; yi < h; yi += n) {
|
||||
// Last chunk might contain less liness
|
||||
if (n > 1 && h - yi < n ) {
|
||||
n = h - yi;
|
||||
}
|
||||
bm.getPixels(intOut, 0, w, 0, yi, w, n);
|
||||
setPixels(0, yi, w, n, model, intOut, 0, w);
|
||||
}
|
||||
} else {
|
||||
// Android bitmaps always store ints (ARGB-8888 direct model)
|
||||
throw new RuntimeException("Byte transfer not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,536 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import org.apache.harmony.awt.gl.MultiRectArea;
|
||||
import org.apache.harmony.awt.gl.Surface;
|
||||
import org.apache.harmony.awt.gl.XORComposite;
|
||||
import org.apache.harmony.awt.gl.render.Blitter;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
public class AndroidJavaBlitter implements Blitter {
|
||||
|
||||
private Canvas canvas;
|
||||
private Paint paint;
|
||||
private int colorCache;
|
||||
|
||||
public AndroidJavaBlitter(Canvas c) {
|
||||
this.canvas = c;
|
||||
this.paint = new Paint();
|
||||
this.paint.setStrokeWidth(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of multiplication and division we are using values from
|
||||
* Lookup tables.
|
||||
*/
|
||||
static byte mulLUT[][]; // Lookup table for multiplication
|
||||
static byte divLUT[][]; // Lookup table for division
|
||||
|
||||
static{
|
||||
mulLUT = new byte[256][256];
|
||||
for(int i = 0; i < 256; i++){
|
||||
for(int j = 0; j < 256; j++){
|
||||
mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
|
||||
}
|
||||
}
|
||||
divLUT = new byte[256][256];
|
||||
for(int i = 1; i < 256; i++){
|
||||
for(int j = 0; j < i; j++){
|
||||
divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
|
||||
}
|
||||
for(int j = i; j < 256; j++){
|
||||
divLUT[i][j] = (byte)255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final static int AlphaCompositeMode = 1;
|
||||
final static int XORMode = 2;
|
||||
|
||||
public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
|
||||
Surface dstSurf, int width, int height, AffineTransform sysxform,
|
||||
AffineTransform xform, Composite comp, Color bgcolor,
|
||||
MultiRectArea clip) {
|
||||
|
||||
if(xform == null){
|
||||
blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
|
||||
sysxform, comp, bgcolor, clip);
|
||||
}else{
|
||||
double scaleX = xform.getScaleX();
|
||||
double scaleY = xform.getScaleY();
|
||||
double scaledX = dstX / scaleX;
|
||||
double scaledY = dstY / scaleY;
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.setToTranslation(scaledX, scaledY);
|
||||
xform.concatenate(at);
|
||||
sysxform.concatenate(xform);
|
||||
blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
|
||||
sysxform, comp, bgcolor, clip);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
|
||||
Surface dstSurf, int width, int height, AffineTransform sysxform,
|
||||
Composite comp, Color bgcolor, MultiRectArea clip) {
|
||||
|
||||
if(sysxform == null) {
|
||||
sysxform = new AffineTransform();
|
||||
}
|
||||
int type = sysxform.getType();
|
||||
switch(type){
|
||||
case AffineTransform.TYPE_TRANSLATION:
|
||||
dstX += sysxform.getTranslateX();
|
||||
dstY += sysxform.getTranslateY();
|
||||
case AffineTransform.TYPE_IDENTITY:
|
||||
simpleBlit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
|
||||
width, height, comp, bgcolor, clip);
|
||||
break;
|
||||
default:
|
||||
int srcW = srcSurf.getWidth();
|
||||
int srcH = srcSurf.getHeight();
|
||||
|
||||
int w = srcX + width < srcW ? width : srcW - srcX;
|
||||
int h = srcY + height < srcH ? height : srcH - srcY;
|
||||
|
||||
ColorModel srcCM = srcSurf.getColorModel();
|
||||
Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
|
||||
w, h, 0, 0, null);
|
||||
|
||||
ColorModel dstCM = dstSurf.getColorModel();
|
||||
WritableRaster dstR = dstSurf.getRaster();
|
||||
|
||||
transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
|
||||
sysxform, comp, bgcolor, clip);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void simpleBlit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
|
||||
Surface dstSurf, int width, int height, Composite comp,
|
||||
Color bgcolor, MultiRectArea clip) {
|
||||
|
||||
// TODO It's possible, though unlikely that we might encounter non-int[]
|
||||
// data buffers. In this case the following code needs to have several
|
||||
// branches that take this into account.
|
||||
data = (DataBufferInt)srcSurf.getRaster().getDataBuffer();
|
||||
int[] pixels = data.getData();
|
||||
if (!srcSurf.getColorModel().hasAlpha()) {
|
||||
// This wouldn't be necessary if Android supported RGB_888.
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
pixels[i] = pixels[i] | 0xff000000;
|
||||
}
|
||||
}
|
||||
bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
|
||||
canvas.drawBitmap(bmap, dstX, dstY, paint);
|
||||
}
|
||||
|
||||
public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
|
||||
Surface dstSurf, int width, int height, Composite comp,
|
||||
Color bgcolor, MultiRectArea clip) {
|
||||
|
||||
javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
|
||||
srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
|
||||
dstSurf.getWidth(), dstSurf.getHeight(),
|
||||
dstSurf.getColorModel(), dstSurf.getRaster(),
|
||||
width, height, comp, bgcolor, clip);
|
||||
|
||||
}
|
||||
|
||||
public void javaBlt(int srcX, int srcY, int srcW, int srcH,
|
||||
ColorModel srcCM, Raster srcRast, int dstX, int dstY,
|
||||
int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
|
||||
int width, int height, Composite comp, Color bgcolor,
|
||||
MultiRectArea clip){
|
||||
|
||||
int srcX2 = srcW - 1;
|
||||
int srcY2 = srcH - 1;
|
||||
int dstX2 = dstW - 1;
|
||||
int dstY2 = dstH - 1;
|
||||
|
||||
if(srcX < 0){
|
||||
width += srcX;
|
||||
srcX = 0;
|
||||
}
|
||||
if(srcY < 0){
|
||||
height += srcY;
|
||||
srcY = 0;
|
||||
}
|
||||
|
||||
if(dstX < 0){
|
||||
width += dstX;
|
||||
srcX -= dstX;
|
||||
dstX = 0;
|
||||
}
|
||||
if(dstY < 0){
|
||||
height += dstY;
|
||||
srcY -= dstY;
|
||||
dstY = 0;
|
||||
}
|
||||
|
||||
if(srcX > srcX2 || srcY > srcY2) {
|
||||
return;
|
||||
}
|
||||
if(dstX > dstX2 || dstY > dstY2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(srcX + width > srcX2) {
|
||||
width = srcX2 - srcX + 1;
|
||||
}
|
||||
if(srcY + height > srcY2) {
|
||||
height = srcY2 - srcY + 1;
|
||||
}
|
||||
if(dstX + width > dstX2) {
|
||||
width = dstX2 - dstX + 1;
|
||||
}
|
||||
if(dstY + height > dstY2) {
|
||||
height = dstY2 - dstY + 1;
|
||||
}
|
||||
|
||||
if(width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int clipRects[];
|
||||
if(clip != null) {
|
||||
clipRects = clip.rect;
|
||||
} else {
|
||||
clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
|
||||
}
|
||||
|
||||
boolean isAlphaComp = false;
|
||||
int rule = 0;
|
||||
float alpha = 0;
|
||||
boolean isXORComp = false;
|
||||
Color xorcolor = null;
|
||||
CompositeContext cont = null;
|
||||
|
||||
if(comp instanceof AlphaComposite){
|
||||
isAlphaComp = true;
|
||||
AlphaComposite ac = (AlphaComposite) comp;
|
||||
rule = ac.getRule();
|
||||
alpha = ac.getAlpha();
|
||||
}else if(comp instanceof XORComposite){
|
||||
isXORComp = true;
|
||||
XORComposite xcomp = (XORComposite) comp;
|
||||
xorcolor = xcomp.getXORColor();
|
||||
}else{
|
||||
cont = comp.createContext(srcCM, dstCM, null);
|
||||
}
|
||||
|
||||
for(int i = 1; i < clipRects[0]; i += 4){
|
||||
int _sx = srcX;
|
||||
int _sy = srcY;
|
||||
|
||||
int _dx = dstX;
|
||||
int _dy = dstY;
|
||||
|
||||
int _w = width;
|
||||
int _h = height;
|
||||
|
||||
int cx = clipRects[i]; // Clipping left top X
|
||||
int cy = clipRects[i + 1]; // Clipping left top Y
|
||||
int cx2 = clipRects[i + 2]; // Clipping right bottom X
|
||||
int cy2 = clipRects[i + 3]; // Clipping right bottom Y
|
||||
|
||||
if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cx > _dx){
|
||||
int shx = cx - _dx;
|
||||
_w -= shx;
|
||||
_dx = cx;
|
||||
_sx += shx;
|
||||
}
|
||||
|
||||
if(cy > _dy){
|
||||
int shy = cy - _dy;
|
||||
_h -= shy;
|
||||
_dy = cy;
|
||||
_sy += shy;
|
||||
}
|
||||
|
||||
if(_dx + _w > cx2 + 1){
|
||||
_w = cx2 - _dx + 1;
|
||||
}
|
||||
|
||||
if(_dy + _h > cy2 + 1){
|
||||
_h = cy2 - _dy + 1;
|
||||
}
|
||||
|
||||
if(_sx > srcX2 || _sy > srcY2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isAlphaComp){
|
||||
alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
|
||||
dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
|
||||
}else if(isXORComp){
|
||||
xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
|
||||
dstCM, dstRast, _w, _h, xorcolor);
|
||||
}else{
|
||||
Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
|
||||
WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
|
||||
_w, _h, 0, 0, null);
|
||||
cont.compose(sr, dr, dr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DataBufferInt data;
|
||||
Bitmap bmap, bmp;
|
||||
|
||||
void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
|
||||
int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
|
||||
int width, int height, int rule, float alpha, Color bgcolor){
|
||||
|
||||
Object srcPixel = getTransferArray(srcRast, 1);
|
||||
data = (DataBufferInt)srcRast.getDataBuffer();
|
||||
int pix[] = data.getData();
|
||||
bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
|
||||
canvas.drawBitmap(bmap, dstX, dstY, paint);
|
||||
}
|
||||
|
||||
void render(int[] img, int x, int y, int width, int height) {
|
||||
canvas.drawBitmap(Bitmap.createBitmap(img, width, height, Bitmap.Config.ARGB_8888), x, y, paint);
|
||||
}
|
||||
|
||||
void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
|
||||
int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
|
||||
int width, int height, Color xorcolor){
|
||||
|
||||
data = (DataBufferInt)srcRast.getDataBuffer();
|
||||
int pix[] = data.getData();
|
||||
bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
|
||||
canvas.drawBitmap(bmap, dstX, dstY, paint);
|
||||
}
|
||||
|
||||
private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
|
||||
ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
|
||||
int width, int height, AffineTransform at, Composite comp,
|
||||
Color bgcolor, MultiRectArea clip) {
|
||||
|
||||
data = (DataBufferInt)srcR.getDataBuffer();
|
||||
int[] pixels = data.getData();
|
||||
if (!srcCM.hasAlpha()) {
|
||||
// This wouldn't be necessary if Android supported RGB_888.
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
pixels[i] = pixels[i] | 0xff000000;
|
||||
}
|
||||
}
|
||||
bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Matrix tm = new Matrix();
|
||||
tm.setConcat(canvas.getMatrix(), AndroidGraphics2D.createMatrixObj(at));
|
||||
if(at.getType() > 1) {
|
||||
bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, true);
|
||||
} else {
|
||||
bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, false);
|
||||
}
|
||||
canvas.drawBitmap(bmp, dstX + (float)at.getTranslateX(), dstY + (float)at.getTranslateY(), paint);
|
||||
}
|
||||
|
||||
private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
|
||||
int x = r.x;
|
||||
int y = r.y;
|
||||
int width = r.width;
|
||||
int height = r.height;
|
||||
|
||||
float[] corners = {
|
||||
x, y,
|
||||
x + width, y,
|
||||
x + width, y + height,
|
||||
x, y + height
|
||||
};
|
||||
|
||||
at.transform(corners, 0, corners, 0, 4);
|
||||
|
||||
Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
|
||||
bounds.add(corners[2], corners[3]);
|
||||
bounds.add(corners[4], corners[5]);
|
||||
bounds.add(corners[6], corners[7]);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private int compose(int srcRGB, boolean isSrcAlphaPre,
|
||||
int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
|
||||
int rule, int srcConstAlpha){
|
||||
|
||||
int sa, sr, sg, sb, da, dr, dg, db;
|
||||
|
||||
sa = (srcRGB >> 24) & 0xff;
|
||||
sr = (srcRGB >> 16) & 0xff;
|
||||
sg = (srcRGB >> 8) & 0xff;
|
||||
sb = srcRGB & 0xff;
|
||||
|
||||
if(isSrcAlphaPre){
|
||||
sa = mulLUT[srcConstAlpha][sa] & 0xff;
|
||||
sr = mulLUT[srcConstAlpha][sr] & 0xff;
|
||||
sg = mulLUT[srcConstAlpha][sg] & 0xff;
|
||||
sb = mulLUT[srcConstAlpha][sb] & 0xff;
|
||||
}else{
|
||||
sa = mulLUT[srcConstAlpha][sa] & 0xff;
|
||||
sr = mulLUT[sa][sr] & 0xff;
|
||||
sg = mulLUT[sa][sg] & 0xff;
|
||||
sb = mulLUT[sa][sb] & 0xff;
|
||||
}
|
||||
|
||||
da = (dstRGB >> 24) & 0xff;
|
||||
dr = (dstRGB >> 16) & 0xff;
|
||||
dg = (dstRGB >> 8) & 0xff;
|
||||
db = dstRGB & 0xff;
|
||||
|
||||
if(!isDstAlphaPre){
|
||||
dr = mulLUT[da][dr] & 0xff;
|
||||
dg = mulLUT[da][dg] & 0xff;
|
||||
db = mulLUT[da][db] & 0xff;
|
||||
}
|
||||
|
||||
int Fs = 0;
|
||||
int Fd = 0;
|
||||
switch(rule){
|
||||
case AlphaComposite.CLEAR:
|
||||
break;
|
||||
|
||||
case AlphaComposite.DST:
|
||||
Fd = 255;
|
||||
break;
|
||||
|
||||
case AlphaComposite.DST_ATOP:
|
||||
Fs = 255 - da;
|
||||
Fd = sa;
|
||||
break;
|
||||
|
||||
case AlphaComposite.DST_IN:
|
||||
Fd = sa;
|
||||
break;
|
||||
|
||||
case AlphaComposite.DST_OUT:
|
||||
Fd = 255 - sa;
|
||||
break;
|
||||
|
||||
case AlphaComposite.DST_OVER:
|
||||
Fs = 255 - da;
|
||||
Fd = 255;
|
||||
break;
|
||||
|
||||
case AlphaComposite.SRC:
|
||||
Fs = 255;
|
||||
break;
|
||||
|
||||
case AlphaComposite.SRC_ATOP:
|
||||
Fs = da;
|
||||
Fd = 255 - sa;
|
||||
break;
|
||||
|
||||
case AlphaComposite.SRC_IN:
|
||||
Fs = da;
|
||||
break;
|
||||
|
||||
case AlphaComposite.SRC_OUT:
|
||||
Fs = 255 - da;
|
||||
break;
|
||||
|
||||
case AlphaComposite.SRC_OVER:
|
||||
Fs = 255;
|
||||
Fd = 255 - sa;
|
||||
break;
|
||||
|
||||
case AlphaComposite.XOR:
|
||||
Fs = 255 - da;
|
||||
Fd = 255 - sa;
|
||||
break;
|
||||
}
|
||||
dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
|
||||
dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
|
||||
db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
|
||||
|
||||
da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
|
||||
|
||||
if(!isDstAlphaPre){
|
||||
if(da != 255){
|
||||
dr = divLUT[da][dr] & 0xff;
|
||||
dg = divLUT[da][dg] & 0xff;
|
||||
db = divLUT[da][db] & 0xff;
|
||||
}
|
||||
}
|
||||
if(!dstHasAlpha) {
|
||||
da = 0xff;
|
||||
}
|
||||
dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
|
||||
|
||||
return dstRGB;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate an array that can be use to store the result for a
|
||||
* Raster.getDataElements call.
|
||||
* @param raster Raster (type) where the getDataElements call will be made.
|
||||
* @param nbPixels How many pixels to store in the array at most
|
||||
* @return the result array or null
|
||||
*/
|
||||
private Object getTransferArray(Raster raster, int nbPixels) {
|
||||
int transferType = raster.getTransferType();
|
||||
int nbDataElements = raster.getSampleModel().getNumDataElements();
|
||||
int n = nbDataElements * nbPixels;
|
||||
switch (transferType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
return new byte[n];
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
return new short[n];
|
||||
case DataBuffer.TYPE_INT:
|
||||
return new int[n];
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
return new float[n];
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
return new double[n];
|
||||
case DataBuffer.TYPE_UNDEFINED:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a pixel
|
||||
*/
|
||||
private void dot(int x, int y, int clr) {
|
||||
if (colorCache != clr) {
|
||||
paint.setColor(clr);
|
||||
colorCache = clr;
|
||||
}
|
||||
canvas.drawLine(x, y, x + 1, y + 1, paint);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import org.apache.harmony.awt.wtk.NativeEventQueue;
|
||||
|
||||
public class AndroidNativeEventQueue extends NativeEventQueue {
|
||||
|
||||
private Object eventMonitor;
|
||||
|
||||
public AndroidNativeEventQueue() {
|
||||
super();
|
||||
eventMonitor = getEventMonitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void awake() {
|
||||
synchronized (eventMonitor) {
|
||||
eventMonitor.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchEvent() {
|
||||
//???AWT
|
||||
System.out.println(getClass()+": empty method called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getJavaWindow() {
|
||||
//???AWT
|
||||
System.out.println(getClass()+": empty method called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performLater(Task task) {
|
||||
//???AWT
|
||||
System.out.println(getClass()+": empty method called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performTask(Task task) {
|
||||
//???AWT
|
||||
System.out.println(getClass()+": empty method called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean waitEvent() {
|
||||
while (isEmpty() ) {
|
||||
synchronized (eventMonitor) {
|
||||
try {
|
||||
eventMonitor.wait(1000);
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.GraphicsDevice;
|
||||
|
||||
import org.apache.harmony.awt.wtk.CursorFactory;
|
||||
import org.apache.harmony.awt.wtk.GraphicsFactory;
|
||||
import org.apache.harmony.awt.wtk.NativeEventQueue;
|
||||
import org.apache.harmony.awt.wtk.NativeIM;
|
||||
import org.apache.harmony.awt.wtk.NativeMouseInfo;
|
||||
import org.apache.harmony.awt.wtk.NativeRobot;
|
||||
import org.apache.harmony.awt.wtk.SystemProperties;
|
||||
import org.apache.harmony.awt.wtk.WTK;
|
||||
import org.apache.harmony.awt.wtk.WindowFactory;
|
||||
|
||||
public class AndroidWTK extends WTK {
|
||||
|
||||
private AndroidGraphicsFactory mAgf;
|
||||
private AndroidNativeEventQueue mAneq;
|
||||
|
||||
@Override
|
||||
public CursorFactory getCursorFactory() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsFactory getGraphicsFactory() {
|
||||
if(mAgf == null) {
|
||||
mAgf = new AndroidGraphicsFactory();
|
||||
}
|
||||
return mAgf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeEventQueue getNativeEventQueue() {
|
||||
if(mAneq == null) {
|
||||
mAneq = new AndroidNativeEventQueue();
|
||||
}
|
||||
return mAneq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeIM getNativeIM() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeMouseInfo getNativeMouseInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeRobot getNativeRobot(GraphicsDevice screen) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemProperties getSystemProperties() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowFactory getWindowFactory() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import org.apache.harmony.awt.wtk.GraphicsFactory;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
public class AwtFactory {
|
||||
|
||||
private static GraphicsFactory gf;
|
||||
|
||||
/**
|
||||
* Use this method to get acces to AWT drawing primitives and to
|
||||
* render into the surface area of a Android widget. Origin and
|
||||
* clip of the returned graphics object are the same as in the
|
||||
* corresponding Android widget.
|
||||
*
|
||||
* @param c Canvas of the android widget to draw into
|
||||
* @param p The default drawing parameters such as font,
|
||||
* stroke, foreground and background colors, etc.
|
||||
* @return The AWT Graphics object that makes all AWT
|
||||
* drawing primitives available in the androind world.
|
||||
*/
|
||||
public static Graphics2D getAwtGraphics(Canvas c, Paint p) {
|
||||
// AWT?? TODO: test it!
|
||||
if (null == gf) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
gf = tk.getGraphicsFactory();
|
||||
}
|
||||
return gf.getGraphics2D(c, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.awt;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
public class ImageOutputStreamWrapper extends OutputStream {
|
||||
|
||||
protected ImageOutputStream mIos;
|
||||
|
||||
private byte[] mBuff;
|
||||
|
||||
public ImageOutputStreamWrapper(ImageOutputStream ios) {
|
||||
if (null == ios) {
|
||||
throw new IllegalArgumentException("ImageOutputStream must not be null");
|
||||
}
|
||||
this.mIos = ios;
|
||||
this.mBuff = new byte[1];
|
||||
}
|
||||
|
||||
public ImageOutputStream getImageOutputStream() {
|
||||
return mIos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int oneByte) throws IOException {
|
||||
mBuff[0] = (byte)oneByte;
|
||||
mIos.write(mBuff, 0, 1);
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
mIos.write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
mIos.write(b, off, len);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
mIos.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (mIos == null) {
|
||||
throw new IOException("Stream already closed");
|
||||
}
|
||||
mIos = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,456 +0,0 @@
|
|||
package com.android.internal.awt;
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.*;
|
||||
import java.awt.image.renderable.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.image.*;
|
||||
import java.awt.RenderingHints.*;
|
||||
import java.util.*;
|
||||
import java.awt.geom.*;
|
||||
|
||||
public class NullGraphics2D extends Graphics2D
|
||||
{
|
||||
|
||||
@Override
|
||||
public void clearRect(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipRect(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyArea(int sx, int sy, int width, int height, int dx, int dy)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics create()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawArc(int x, int y, int width, int height, int sa, int ea)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOval(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolygon(int[] xpoints, int[] ypoints, int npoints)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolyline(int[] xpoints, int[] ypoints, int npoints)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillArc(int x, int y, int width, int height, int sa, int ea)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillOval(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillPolygon(int[] xpoints, int[] ypoints, int npoints)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getClip()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getClipBounds()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor()
|
||||
{
|
||||
return Color.BLACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getFont()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return Font.decode(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(Font font)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return new FontMetrics(getFont()){};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(Shape clip)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Color c)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(Font font)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaintMode()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXORMode(Color color)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRenderingHints(Map<?, ?> hints)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clip(Shape s)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Shape s)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawGlyphVector(GlyphVector g, float x, float y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderableImage(RenderableImage img, AffineTransform xform)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderedImage(RenderedImage img, AffineTransform xform)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, float x, float y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, int x, int y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String s, float x, float y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, int x, int y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(Shape s)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Composite getComposite()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration getDeviceConfiguration()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderContext getFontRenderContext()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paint getPaint()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRenderingHint(RenderingHints.Key key)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stroke getStroke()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getTransform()
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hit(Rectangle rect, Shape s, boolean onStroke)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta, double x, double y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scale(double sx, double sy)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComposite(Composite comp)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint paint)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHint(RenderingHints.Key key, Object value)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHints(Map<?, ?> hints)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStroke(Stroke s)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(AffineTransform Tx)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shear(double shx, double shy)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(AffineTransform Tx)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(double tx, double ty)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(int x, int y)
|
||||
{
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import static com.pojavdx.dex.EncodedValueReader.ENCODED_ANNOTATION;
|
||||
|
||||
/**
|
||||
* An annotation.
|
||||
*/
|
||||
public final class Annotation implements Comparable<Annotation> {
|
||||
private final Dex dex;
|
||||
private final byte visibility;
|
||||
private final EncodedValue encodedAnnotation;
|
||||
|
||||
public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {
|
||||
this.dex = dex;
|
||||
this.visibility = visibility;
|
||||
this.encodedAnnotation = encodedAnnotation;
|
||||
}
|
||||
|
||||
public byte getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public EncodedValueReader getReader() {
|
||||
return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);
|
||||
}
|
||||
|
||||
public int getTypeIndex() {
|
||||
EncodedValueReader reader = getReader();
|
||||
reader.readAnnotation();
|
||||
return reader.getAnnotationType();
|
||||
}
|
||||
|
||||
public void writeTo(Dex.Section out) {
|
||||
out.writeByte(visibility);
|
||||
encodedAnnotation.writeTo(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Annotation other) {
|
||||
return encodedAnnotation.compareTo(other.encodedAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return dex == null
|
||||
? visibility + " " + getTypeIndex()
|
||||
: visibility + " " + dex.typeNames().get(getTypeIndex());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.Dex.Section;
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
/**
|
||||
* A call_site_id_item: https://source.android.com/devices/tech/dalvik/dex-format#call-site-id-item
|
||||
*/
|
||||
public class CallSiteId implements Comparable<CallSiteId> {
|
||||
|
||||
private final Dex dex;
|
||||
private final int offset;
|
||||
|
||||
public CallSiteId(Dex dex, int offset) {
|
||||
this.dex = dex;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CallSiteId o) {
|
||||
return Unsigned.compare(offset, o.offset);
|
||||
}
|
||||
|
||||
public int getCallSiteOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void writeTo(Section out) {
|
||||
out.writeInt(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (dex == null) {
|
||||
return String.valueOf(offset);
|
||||
}
|
||||
return dex.protoIds().get(offset).toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
public final class ClassData {
|
||||
private final Field[] staticFields;
|
||||
private final Field[] instanceFields;
|
||||
private final Method[] directMethods;
|
||||
private final Method[] virtualMethods;
|
||||
|
||||
public ClassData(Field[] staticFields, Field[] instanceFields,
|
||||
Method[] directMethods, Method[] virtualMethods) {
|
||||
this.staticFields = staticFields;
|
||||
this.instanceFields = instanceFields;
|
||||
this.directMethods = directMethods;
|
||||
this.virtualMethods = virtualMethods;
|
||||
}
|
||||
|
||||
public Field[] getStaticFields() {
|
||||
return staticFields;
|
||||
}
|
||||
|
||||
public Field[] getInstanceFields() {
|
||||
return instanceFields;
|
||||
}
|
||||
|
||||
public Method[] getDirectMethods() {
|
||||
return directMethods;
|
||||
}
|
||||
|
||||
public Method[] getVirtualMethods() {
|
||||
return virtualMethods;
|
||||
}
|
||||
|
||||
public Field[] allFields() {
|
||||
Field[] result = new Field[staticFields.length + instanceFields.length];
|
||||
net.kdt.pojavlaunch.SystemCrackResolver.arraycopy(staticFields, 0, result, 0, staticFields.length);
|
||||
net.kdt.pojavlaunch.SystemCrackResolver.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Method[] allMethods() {
|
||||
Method[] result = new Method[directMethods.length + virtualMethods.length];
|
||||
net.kdt.pojavlaunch.SystemCrackResolver.arraycopy(directMethods, 0, result, 0, directMethods.length);
|
||||
net.kdt.pojavlaunch.SystemCrackResolver.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class Field {
|
||||
private final int fieldIndex;
|
||||
private final int accessFlags;
|
||||
|
||||
public Field(int fieldIndex, int accessFlags) {
|
||||
this.fieldIndex = fieldIndex;
|
||||
this.accessFlags = accessFlags;
|
||||
}
|
||||
|
||||
public int getFieldIndex() {
|
||||
return fieldIndex;
|
||||
}
|
||||
|
||||
public int getAccessFlags() {
|
||||
return accessFlags;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Method {
|
||||
private final int methodIndex;
|
||||
private final int accessFlags;
|
||||
private final int codeOffset;
|
||||
|
||||
public Method(int methodIndex, int accessFlags, int codeOffset) {
|
||||
this.methodIndex = methodIndex;
|
||||
this.accessFlags = accessFlags;
|
||||
this.codeOffset = codeOffset;
|
||||
}
|
||||
|
||||
public int getMethodIndex() {
|
||||
return methodIndex;
|
||||
}
|
||||
|
||||
public int getAccessFlags() {
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public int getCodeOffset() {
|
||||
return codeOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
/**
|
||||
* A type definition.
|
||||
*/
|
||||
public final class ClassDef {
|
||||
public static final int NO_INDEX = -1;
|
||||
private final Dex buffer;
|
||||
private final int offset;
|
||||
private final int typeIndex;
|
||||
private final int accessFlags;
|
||||
private final int supertypeIndex;
|
||||
private final int interfacesOffset;
|
||||
private final int sourceFileIndex;
|
||||
private final int annotationsOffset;
|
||||
private final int classDataOffset;
|
||||
private final int staticValuesOffset;
|
||||
|
||||
public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,
|
||||
int supertypeIndex, int interfacesOffset, int sourceFileIndex,
|
||||
int annotationsOffset, int classDataOffset, int staticValuesOffset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
this.typeIndex = typeIndex;
|
||||
this.accessFlags = accessFlags;
|
||||
this.supertypeIndex = supertypeIndex;
|
||||
this.interfacesOffset = interfacesOffset;
|
||||
this.sourceFileIndex = sourceFileIndex;
|
||||
this.annotationsOffset = annotationsOffset;
|
||||
this.classDataOffset = classDataOffset;
|
||||
this.staticValuesOffset = staticValuesOffset;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public int getTypeIndex() {
|
||||
return typeIndex;
|
||||
}
|
||||
|
||||
public int getSupertypeIndex() {
|
||||
return supertypeIndex;
|
||||
}
|
||||
|
||||
public int getInterfacesOffset() {
|
||||
return interfacesOffset;
|
||||
}
|
||||
|
||||
public short[] getInterfaces() {
|
||||
return buffer.readTypeList(interfacesOffset).getTypes();
|
||||
}
|
||||
|
||||
public int getAccessFlags() {
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public int getSourceFileIndex() {
|
||||
return sourceFileIndex;
|
||||
}
|
||||
|
||||
public int getAnnotationsOffset() {
|
||||
return annotationsOffset;
|
||||
}
|
||||
|
||||
public int getClassDataOffset() {
|
||||
return classDataOffset;
|
||||
}
|
||||
|
||||
public int getStaticValuesOffset() {
|
||||
return staticValuesOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (buffer == null) {
|
||||
return typeIndex + " " + supertypeIndex;
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(buffer.typeNames().get(typeIndex));
|
||||
if (supertypeIndex != NO_INDEX) {
|
||||
result.append(" extends ").append(buffer.typeNames().get(supertypeIndex));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
public final class Code {
|
||||
private final int registersSize;
|
||||
private final int insSize;
|
||||
private final int outsSize;
|
||||
private final int debugInfoOffset;
|
||||
private final short[] instructions;
|
||||
private final Try[] tries;
|
||||
private final CatchHandler[] catchHandlers;
|
||||
|
||||
public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,
|
||||
short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {
|
||||
this.registersSize = registersSize;
|
||||
this.insSize = insSize;
|
||||
this.outsSize = outsSize;
|
||||
this.debugInfoOffset = debugInfoOffset;
|
||||
this.instructions = instructions;
|
||||
this.tries = tries;
|
||||
this.catchHandlers = catchHandlers;
|
||||
}
|
||||
|
||||
public int getRegistersSize() {
|
||||
return registersSize;
|
||||
}
|
||||
|
||||
public int getInsSize() {
|
||||
return insSize;
|
||||
}
|
||||
|
||||
public int getOutsSize() {
|
||||
return outsSize;
|
||||
}
|
||||
|
||||
public int getDebugInfoOffset() {
|
||||
return debugInfoOffset;
|
||||
}
|
||||
|
||||
public short[] getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
|
||||
public Try[] getTries() {
|
||||
return tries;
|
||||
}
|
||||
|
||||
public CatchHandler[] getCatchHandlers() {
|
||||
return catchHandlers;
|
||||
}
|
||||
|
||||
public static class Try {
|
||||
final int startAddress;
|
||||
final int instructionCount;
|
||||
final int catchHandlerIndex;
|
||||
|
||||
Try(int startAddress, int instructionCount, int catchHandlerIndex) {
|
||||
this.startAddress = startAddress;
|
||||
this.instructionCount = instructionCount;
|
||||
this.catchHandlerIndex = catchHandlerIndex;
|
||||
}
|
||||
|
||||
public int getStartAddress() {
|
||||
return startAddress;
|
||||
}
|
||||
|
||||
public int getInstructionCount() {
|
||||
return instructionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this try's catch handler <strong>index</strong>. Note that
|
||||
* this is distinct from the its catch handler <strong>offset</strong>.
|
||||
*/
|
||||
public int getCatchHandlerIndex() {
|
||||
return catchHandlerIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CatchHandler {
|
||||
final int[] typeIndexes;
|
||||
final int[] addresses;
|
||||
final int catchAllAddress;
|
||||
final int offset;
|
||||
|
||||
public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {
|
||||
this.typeIndexes = typeIndexes;
|
||||
this.addresses = addresses;
|
||||
this.catchAllAddress = catchAllAddress;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int[] getTypeIndexes() {
|
||||
return typeIndexes;
|
||||
}
|
||||
|
||||
public int[] getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public int getCatchAllAddress() {
|
||||
return catchAllAddress;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,819 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.Code.CatchHandler;
|
||||
import com.pojavdx.dex.Code.Try;
|
||||
import com.pojavdx.dex.MethodHandle.MethodHandleType;
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
import com.pojavdx.dex.util.ByteOutput;
|
||||
import com.pojavdx.dex.util.FileUtils;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UTFDataFormatException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.RandomAccess;
|
||||
import java.util.zip.Adler32;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* The bytes of a dex file in memory for reading and writing. All int offsets
|
||||
* are unsigned.
|
||||
*/
|
||||
public final class Dex {
|
||||
private static final int CHECKSUM_OFFSET = 8;
|
||||
private static final int CHECKSUM_SIZE = 4;
|
||||
private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;
|
||||
private static final int SIGNATURE_SIZE = 20;
|
||||
// Provided as a convenience to avoid a memory allocation to benefit Dalvik.
|
||||
// Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.
|
||||
static final short[] EMPTY_SHORT_ARRAY = new short[0];
|
||||
|
||||
private ByteBuffer data;
|
||||
private final TableOfContents tableOfContents = new TableOfContents();
|
||||
private int nextSectionStart = 0;
|
||||
private final StringTable strings = new StringTable();
|
||||
private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable();
|
||||
private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable();
|
||||
private final ProtoIdTable protoIds = new ProtoIdTable();
|
||||
private final FieldIdTable fieldIds = new FieldIdTable();
|
||||
private final MethodIdTable methodIds = new MethodIdTable();
|
||||
|
||||
/**
|
||||
* Creates a new dex that reads from {@code data}. It is an error to modify
|
||||
* {@code data} after using it to create a dex buffer.
|
||||
*/
|
||||
public Dex(byte[] data) throws IOException {
|
||||
this(ByteBuffer.wrap(data));
|
||||
}
|
||||
|
||||
private Dex(ByteBuffer data) throws IOException {
|
||||
this.data = data;
|
||||
this.data.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.tableOfContents.readFrom(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty dex of the specified size.
|
||||
*/
|
||||
public Dex(int byteCount) throws IOException {
|
||||
this.data = ByteBuffer.wrap(new byte[byteCount]);
|
||||
this.data.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.
|
||||
*/
|
||||
public Dex(InputStream in) throws IOException {
|
||||
try {
|
||||
loadFrom(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new dex buffer from the dex file {@code file}.
|
||||
*/
|
||||
public Dex(File file) throws IOException {
|
||||
if (FileUtils.hasArchiveSuffix(file.getName())) {
|
||||
ZipFile zipFile = new ZipFile(file);
|
||||
ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
|
||||
if (entry != null) {
|
||||
try (InputStream inputStream = zipFile.getInputStream(entry)) {
|
||||
loadFrom(inputStream);
|
||||
}
|
||||
zipFile.close();
|
||||
} else {
|
||||
throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
|
||||
}
|
||||
} else if (file.getName().endsWith(".dex")) {
|
||||
try (InputStream inputStream = new FileInputStream(file)) {
|
||||
loadFrom(inputStream);
|
||||
}
|
||||
} else {
|
||||
throw new DexException("unknown output extension: " + file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It is the caller's responsibility to close {@code in}.
|
||||
*/
|
||||
private void loadFrom(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
|
||||
int count;
|
||||
while ((count = in.read(buffer)) != -1) {
|
||||
bytesOut.write(buffer, 0, count);
|
||||
}
|
||||
|
||||
this.data = ByteBuffer.wrap(bytesOut.toByteArray());
|
||||
this.data.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.tableOfContents.readFrom(this);
|
||||
}
|
||||
|
||||
private static void checkBounds(int index, int length) {
|
||||
if (index < 0 || index >= length) {
|
||||
throw new IndexOutOfBoundsException("index:" + index + ", length=" + length);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
|
||||
data.clear();
|
||||
while (data.hasRemaining()) {
|
||||
int count = Math.min(buffer.length, data.remaining());
|
||||
data.get(buffer, 0, count);
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(File dexOut) throws IOException {
|
||||
try (OutputStream out = new FileOutputStream(dexOut)) {
|
||||
writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public TableOfContents getTableOfContents() {
|
||||
return tableOfContents;
|
||||
}
|
||||
|
||||
public Section open(int position) {
|
||||
if (position < 0 || position >= data.capacity()) {
|
||||
throw new IllegalArgumentException("position=" + position
|
||||
+ " length=" + data.capacity());
|
||||
}
|
||||
ByteBuffer sectionData = data.duplicate();
|
||||
sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
|
||||
sectionData.position(position);
|
||||
sectionData.limit(data.capacity());
|
||||
return new Section("section", sectionData);
|
||||
}
|
||||
|
||||
public Section appendSection(int maxByteCount, String name) {
|
||||
if ((maxByteCount & 3) != 0) {
|
||||
throw new IllegalStateException("Not four byte aligned!");
|
||||
}
|
||||
int limit = nextSectionStart + maxByteCount;
|
||||
ByteBuffer sectionData = data.duplicate();
|
||||
sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
|
||||
sectionData.position(nextSectionStart);
|
||||
sectionData.limit(limit);
|
||||
Section result = new Section(name, sectionData);
|
||||
nextSectionStart = limit;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return data.capacity();
|
||||
}
|
||||
|
||||
public int getNextSectionStart() {
|
||||
return nextSectionStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the the bytes of this dex.
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
|
||||
byte[] result = new byte[data.capacity()];
|
||||
data.position(0);
|
||||
data.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<String> strings() {
|
||||
return strings;
|
||||
}
|
||||
|
||||
public List<Integer> typeIds() {
|
||||
return typeIds;
|
||||
}
|
||||
|
||||
public List<String> typeNames() {
|
||||
return typeNames;
|
||||
}
|
||||
|
||||
public List<ProtoId> protoIds() {
|
||||
return protoIds;
|
||||
}
|
||||
|
||||
public List<FieldId> fieldIds() {
|
||||
return fieldIds;
|
||||
}
|
||||
|
||||
public List<MethodId> methodIds() {
|
||||
return methodIds;
|
||||
}
|
||||
|
||||
public Iterable<ClassDef> classDefs() {
|
||||
return new ClassDefIterable();
|
||||
}
|
||||
|
||||
public TypeList readTypeList(int offset) {
|
||||
if (offset == 0) {
|
||||
return TypeList.EMPTY;
|
||||
}
|
||||
return open(offset).readTypeList();
|
||||
}
|
||||
|
||||
public ClassData readClassData(ClassDef classDef) {
|
||||
int offset = classDef.getClassDataOffset();
|
||||
if (offset == 0) {
|
||||
throw new IllegalArgumentException("offset == 0");
|
||||
}
|
||||
return open(offset).readClassData();
|
||||
}
|
||||
|
||||
public Code readCode(ClassData.Method method) {
|
||||
int offset = method.getCodeOffset();
|
||||
if (offset == 0) {
|
||||
throw new IllegalArgumentException("offset == 0");
|
||||
}
|
||||
return open(offset).readCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature of all but the first 32 bytes of this dex. The
|
||||
* first 32 bytes of dex files are not specified to be included in the
|
||||
* signature.
|
||||
*/
|
||||
public byte[] computeSignature() throws IOException {
|
||||
MessageDigest digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA-1");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
byte[] buffer = new byte[8192];
|
||||
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
|
||||
data.limit(data.capacity());
|
||||
data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);
|
||||
while (data.hasRemaining()) {
|
||||
int count = Math.min(buffer.length, data.remaining());
|
||||
data.get(buffer, 0, count);
|
||||
digest.update(buffer, 0, count);
|
||||
}
|
||||
return digest.digest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the checksum of all but the first 12 bytes of {@code dex}.
|
||||
*/
|
||||
public int computeChecksum() throws IOException {
|
||||
Adler32 adler32 = new Adler32();
|
||||
byte[] buffer = new byte[8192];
|
||||
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
|
||||
data.limit(data.capacity());
|
||||
data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);
|
||||
while (data.hasRemaining()) {
|
||||
int count = Math.min(buffer.length, data.remaining());
|
||||
data.get(buffer, 0, count);
|
||||
adler32.update(buffer, 0, count);
|
||||
}
|
||||
return (int) adler32.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the signature and checksum of the dex file {@code out} and
|
||||
* writes them to the file.
|
||||
*/
|
||||
public void writeHashes() throws IOException {
|
||||
open(SIGNATURE_OFFSET).write(computeSignature());
|
||||
open(CHECKSUM_OFFSET).writeInt(computeChecksum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a descriptor index from a type index. Cheaper than:
|
||||
* {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}
|
||||
*/
|
||||
public int descriptorIndexFromTypeIndex(int typeIndex) {
|
||||
checkBounds(typeIndex, tableOfContents.typeIds.size);
|
||||
int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);
|
||||
return data.getInt(position);
|
||||
}
|
||||
|
||||
|
||||
public final class Section implements ByteInput, ByteOutput {
|
||||
private final String name;
|
||||
private final ByteBuffer data;
|
||||
private final int initialPosition;
|
||||
|
||||
private Section(String name, ByteBuffer data) {
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.initialPosition = data.position();
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return data.position();
|
||||
}
|
||||
|
||||
public int readInt() {
|
||||
return data.getInt();
|
||||
}
|
||||
|
||||
public short readShort() {
|
||||
return data.getShort();
|
||||
}
|
||||
|
||||
public int readUnsignedShort() {
|
||||
return readShort() & 0xffff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
return data.get();
|
||||
}
|
||||
|
||||
public byte[] readByteArray(int length) {
|
||||
byte[] result = new byte[length];
|
||||
data.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public short[] readShortArray(int length) {
|
||||
if (length == 0) {
|
||||
return EMPTY_SHORT_ARRAY;
|
||||
}
|
||||
short[] result = new short[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
result[i] = readShort();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readUleb128() {
|
||||
return Leb128.readUnsignedLeb128(this);
|
||||
}
|
||||
|
||||
public int readUleb128p1() {
|
||||
return Leb128.readUnsignedLeb128(this) - 1;
|
||||
}
|
||||
|
||||
public int readSleb128() {
|
||||
return Leb128.readSignedLeb128(this);
|
||||
}
|
||||
|
||||
public void writeUleb128p1(int i) {
|
||||
writeUleb128(i + 1);
|
||||
}
|
||||
|
||||
public TypeList readTypeList() {
|
||||
int size = readInt();
|
||||
short[] types = readShortArray(size);
|
||||
alignToFourBytes();
|
||||
return new TypeList(Dex.this, types);
|
||||
}
|
||||
|
||||
public String readString() {
|
||||
int offset = readInt();
|
||||
int savedPosition = data.position();
|
||||
int savedLimit = data.limit();
|
||||
data.position(offset);
|
||||
data.limit(data.capacity());
|
||||
try {
|
||||
int expectedLength = readUleb128();
|
||||
String result = Mutf8.decode(this, new char[expectedLength]);
|
||||
if (result.length() != expectedLength) {
|
||||
throw new DexException("Declared length " + expectedLength
|
||||
+ " doesn't match decoded length of " + result.length());
|
||||
}
|
||||
return result;
|
||||
} catch (UTFDataFormatException e) {
|
||||
throw new DexException(e);
|
||||
} finally {
|
||||
data.position(savedPosition);
|
||||
data.limit(savedLimit);
|
||||
}
|
||||
}
|
||||
|
||||
public FieldId readFieldId() {
|
||||
int declaringClassIndex = readUnsignedShort();
|
||||
int typeIndex = readUnsignedShort();
|
||||
int nameIndex = readInt();
|
||||
return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);
|
||||
}
|
||||
|
||||
public MethodId readMethodId() {
|
||||
int declaringClassIndex = readUnsignedShort();
|
||||
int protoIndex = readUnsignedShort();
|
||||
int nameIndex = readInt();
|
||||
return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);
|
||||
}
|
||||
|
||||
public ProtoId readProtoId() {
|
||||
int shortyIndex = readInt();
|
||||
int returnTypeIndex = readInt();
|
||||
int parametersOffset = readInt();
|
||||
return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);
|
||||
}
|
||||
|
||||
public CallSiteId readCallSiteId() {
|
||||
int offset = readInt();
|
||||
return new CallSiteId(Dex.this, offset);
|
||||
}
|
||||
|
||||
public MethodHandle readMethodHandle() {
|
||||
MethodHandleType methodHandleType = MethodHandleType.fromValue(readUnsignedShort());
|
||||
int unused1 = readUnsignedShort();
|
||||
int fieldOrMethodId = readUnsignedShort();
|
||||
int unused2 = readUnsignedShort();
|
||||
return new MethodHandle(Dex.this, methodHandleType, unused1, fieldOrMethodId, unused2);
|
||||
}
|
||||
|
||||
public ClassDef readClassDef() {
|
||||
int offset = getPosition();
|
||||
int type = readInt();
|
||||
int accessFlags = readInt();
|
||||
int supertype = readInt();
|
||||
int interfacesOffset = readInt();
|
||||
int sourceFileIndex = readInt();
|
||||
int annotationsOffset = readInt();
|
||||
int classDataOffset = readInt();
|
||||
int staticValuesOffset = readInt();
|
||||
return new ClassDef(Dex.this, offset, type, accessFlags, supertype,
|
||||
interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset,
|
||||
staticValuesOffset);
|
||||
}
|
||||
|
||||
private Code readCode() {
|
||||
int registersSize = readUnsignedShort();
|
||||
int insSize = readUnsignedShort();
|
||||
int outsSize = readUnsignedShort();
|
||||
int triesSize = readUnsignedShort();
|
||||
int debugInfoOffset = readInt();
|
||||
int instructionsSize = readInt();
|
||||
short[] instructions = readShortArray(instructionsSize);
|
||||
Try[] tries;
|
||||
CatchHandler[] catchHandlers;
|
||||
if (triesSize > 0) {
|
||||
if (instructions.length % 2 == 1) {
|
||||
readShort(); // padding
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't read the tries until we've read the catch handlers.
|
||||
* Unfortunately they're in the opposite order in the dex file
|
||||
* so we need to read them out-of-order.
|
||||
*/
|
||||
Section triesSection = open(data.position());
|
||||
skip(triesSize * SizeOf.TRY_ITEM);
|
||||
catchHandlers = readCatchHandlers();
|
||||
tries = triesSection.readTries(triesSize, catchHandlers);
|
||||
} else {
|
||||
tries = new Try[0];
|
||||
catchHandlers = new CatchHandler[0];
|
||||
}
|
||||
return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
|
||||
tries, catchHandlers);
|
||||
}
|
||||
|
||||
private CatchHandler[] readCatchHandlers() {
|
||||
int baseOffset = data.position();
|
||||
int catchHandlersSize = readUleb128();
|
||||
CatchHandler[] result = new CatchHandler[catchHandlersSize];
|
||||
for (int i = 0; i < catchHandlersSize; i++) {
|
||||
int offset = data.position() - baseOffset;
|
||||
result[i] = readCatchHandler(offset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
|
||||
Try[] result = new Try[triesSize];
|
||||
for (int i = 0; i < triesSize; i++) {
|
||||
int startAddress = readInt();
|
||||
int instructionCount = readUnsignedShort();
|
||||
int handlerOffset = readUnsignedShort();
|
||||
int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
|
||||
result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
|
||||
for (int i = 0; i < catchHandlers.length; i++) {
|
||||
CatchHandler catchHandler = catchHandlers[i];
|
||||
if (catchHandler.getOffset() == offset) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
private CatchHandler readCatchHandler(int offset) {
|
||||
int size = readSleb128();
|
||||
int handlersCount = Math.abs(size);
|
||||
int[] typeIndexes = new int[handlersCount];
|
||||
int[] addresses = new int[handlersCount];
|
||||
for (int i = 0; i < handlersCount; i++) {
|
||||
typeIndexes[i] = readUleb128();
|
||||
addresses[i] = readUleb128();
|
||||
}
|
||||
int catchAllAddress = size <= 0 ? readUleb128() : -1;
|
||||
return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
|
||||
}
|
||||
|
||||
private ClassData readClassData() {
|
||||
int staticFieldsSize = readUleb128();
|
||||
int instanceFieldsSize = readUleb128();
|
||||
int directMethodsSize = readUleb128();
|
||||
int virtualMethodsSize = readUleb128();
|
||||
ClassData.Field[] staticFields = readFields(staticFieldsSize);
|
||||
ClassData.Field[] instanceFields = readFields(instanceFieldsSize);
|
||||
ClassData.Method[] directMethods = readMethods(directMethodsSize);
|
||||
ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);
|
||||
return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);
|
||||
}
|
||||
|
||||
private ClassData.Field[] readFields(int count) {
|
||||
ClassData.Field[] result = new ClassData.Field[count];
|
||||
int fieldIndex = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
fieldIndex += readUleb128(); // field index diff
|
||||
int accessFlags = readUleb128();
|
||||
result[i] = new ClassData.Field(fieldIndex, accessFlags);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private ClassData.Method[] readMethods(int count) {
|
||||
ClassData.Method[] result = new ClassData.Method[count];
|
||||
int methodIndex = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
methodIndex += readUleb128(); // method index diff
|
||||
int accessFlags = readUleb128();
|
||||
int codeOff = readUleb128();
|
||||
result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a byte array containing the bytes from {@code start} to this
|
||||
* section's current position.
|
||||
*/
|
||||
private byte[] getBytesFrom(int start) {
|
||||
int end = data.position();
|
||||
byte[] result = new byte[end - start];
|
||||
data.position(start);
|
||||
data.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Annotation readAnnotation() {
|
||||
byte visibility = readByte();
|
||||
int start = data.position();
|
||||
new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();
|
||||
return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));
|
||||
}
|
||||
|
||||
public EncodedValue readEncodedArray() {
|
||||
int start = data.position();
|
||||
new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();
|
||||
return new EncodedValue(getBytesFrom(start));
|
||||
}
|
||||
|
||||
public void skip(int count) {
|
||||
if (count < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
data.position(data.position() + count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips bytes until the position is aligned to a multiple of 4.
|
||||
*/
|
||||
public void alignToFourBytes() {
|
||||
data.position((data.position() + 3) & ~3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes 0x00 until the position is aligned to a multiple of 4.
|
||||
*/
|
||||
public void alignToFourBytesWithZeroFill() {
|
||||
while ((data.position() & 3) != 0) {
|
||||
data.put((byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertFourByteAligned() {
|
||||
if ((data.position() & 3) != 0) {
|
||||
throw new IllegalStateException("Not four byte aligned!");
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte[] bytes) {
|
||||
this.data.put(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int b) {
|
||||
data.put((byte) b);
|
||||
}
|
||||
|
||||
public void writeShort(short i) {
|
||||
data.putShort(i);
|
||||
}
|
||||
|
||||
public void writeUnsignedShort(int i) {
|
||||
short s = (short) i;
|
||||
if (i != (s & 0xffff)) {
|
||||
throw new IllegalArgumentException("Expected an unsigned short: " + i);
|
||||
}
|
||||
writeShort(s);
|
||||
}
|
||||
|
||||
public void write(short[] shorts) {
|
||||
for (short s : shorts) {
|
||||
writeShort(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeInt(int i) {
|
||||
data.putInt(i);
|
||||
}
|
||||
|
||||
public void writeUleb128(int i) {
|
||||
try {
|
||||
Leb128.writeUnsignedLeb128(this, i);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeSleb128(int i) {
|
||||
try {
|
||||
Leb128.writeSignedLeb128(this, i);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeStringData(String value) {
|
||||
try {
|
||||
int length = value.length();
|
||||
writeUleb128(length);
|
||||
write(Mutf8.encode(value));
|
||||
writeByte(0);
|
||||
} catch (UTFDataFormatException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTypeList(TypeList typeList) {
|
||||
short[] types = typeList.getTypes();
|
||||
writeInt(types.length);
|
||||
for (short type : types) {
|
||||
writeShort(type);
|
||||
}
|
||||
alignToFourBytesWithZeroFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes used by this section.
|
||||
*/
|
||||
public int used() {
|
||||
return data.position() - initialPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private final class StringTable extends AbstractList<String> implements RandomAccess {
|
||||
@Override
|
||||
public String get(int index) {
|
||||
checkBounds(index, tableOfContents.stringIds.size);
|
||||
return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM))
|
||||
.readString();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.stringIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
|
||||
implements RandomAccess {
|
||||
@Override
|
||||
public Integer get(int index) {
|
||||
return descriptorIndexFromTypeIndex(index);
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.typeIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class TypeIndexToDescriptorTable extends AbstractList<String>
|
||||
implements RandomAccess {
|
||||
@Override
|
||||
public String get(int index) {
|
||||
return strings.get(descriptorIndexFromTypeIndex(index));
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.typeIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
|
||||
@Override
|
||||
public ProtoId get(int index) {
|
||||
checkBounds(index, tableOfContents.protoIds.size);
|
||||
return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))
|
||||
.readProtoId();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.protoIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
|
||||
@Override
|
||||
public FieldId get(int index) {
|
||||
checkBounds(index, tableOfContents.fieldIds.size);
|
||||
return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index))
|
||||
.readFieldId();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.fieldIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
|
||||
@Override
|
||||
public MethodId get(int index) {
|
||||
checkBounds(index, tableOfContents.methodIds.size);
|
||||
return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index))
|
||||
.readMethodId();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return tableOfContents.methodIds.size;
|
||||
}
|
||||
}
|
||||
|
||||
private final class ClassDefIterator implements Iterator<ClassDef> {
|
||||
private final Dex.Section in = open(tableOfContents.classDefs.off);
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return count < tableOfContents.classDefs.size;
|
||||
}
|
||||
@Override
|
||||
public ClassDef next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
count++;
|
||||
return in.readClassDef();
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private final class ClassDefIterable implements Iterable<ClassDef> {
|
||||
@Override
|
||||
public Iterator<ClassDef> iterator() {
|
||||
return !tableOfContents.classDefs.exists()
|
||||
? Collections.<ClassDef>emptySet().iterator()
|
||||
: new ClassDefIterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ExceptionWithContext;
|
||||
|
||||
/**
|
||||
* Thrown when there's a format problem reading, writing, or generally
|
||||
* processing a dex file.
|
||||
*/
|
||||
public class DexException extends ExceptionWithContext {
|
||||
public DexException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DexException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
/**
|
||||
* Constants that show up in and are otherwise related to {@code .dex}
|
||||
* files, and helper methods for same.
|
||||
*/
|
||||
public final class DexFormat {
|
||||
private DexFormat() {}
|
||||
|
||||
/** API level to target in order to allow spaces in SimpleName */
|
||||
public static final int API_SPACES_IN_SIMPLE_NAME = 10000;
|
||||
|
||||
/** API level to target in order to generate const-method-handle and const-method-type */
|
||||
public static final int API_CONST_METHOD_HANDLE = 28;
|
||||
|
||||
/** API level to target in order to generate invoke-polymorphic and invoke-custom */
|
||||
public static final int API_METHOD_HANDLES = 26;
|
||||
|
||||
/** API level to target in order to define default and static interface methods */
|
||||
public static final int API_DEFINE_INTERFACE_METHODS = 24;
|
||||
|
||||
/** API level to target in order to invoke default and static interface methods */
|
||||
public static final int API_INVOKE_INTERFACE_METHODS = 24;
|
||||
|
||||
/** API level at which the invocation of static interface methods is permitted by dx.
|
||||
* This value has been determined experimentally by testing on different VM versions. */
|
||||
public static final int API_INVOKE_STATIC_INTERFACE_METHODS = 21;
|
||||
|
||||
/** API level to target in order to suppress extended opcode usage */
|
||||
public static final int API_NO_EXTENDED_OPCODES = 13;
|
||||
|
||||
/**
|
||||
* API level to target in order to produce the most modern file
|
||||
* format
|
||||
*/
|
||||
public static final int API_CURRENT = API_CONST_METHOD_HANDLE;
|
||||
|
||||
/** dex file version number for API level 10000 and earlier */
|
||||
public static final String VERSION_FOR_API_10000 = "040";
|
||||
|
||||
/** dex file version number for API level 28 and earlier */
|
||||
public static final String VERSION_FOR_API_28 = "039";
|
||||
|
||||
/** dex file version number for API level 26 and earlier */
|
||||
public static final String VERSION_FOR_API_26 = "038";
|
||||
|
||||
/** dex file version number for API level 24 and earlier */
|
||||
public static final String VERSION_FOR_API_24 = "037";
|
||||
|
||||
/** dex file version number for API level 13 and earlier */
|
||||
public static final String VERSION_FOR_API_13 = "035";
|
||||
|
||||
/**
|
||||
* Dex file version number for dalvik.
|
||||
* <p>
|
||||
* Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or
|
||||
* completed and is not considered a valid dex file format.
|
||||
* </p>
|
||||
*/
|
||||
public static final String VERSION_CURRENT = VERSION_FOR_API_28;
|
||||
|
||||
/**
|
||||
* file name of the primary {@code .dex} file inside an
|
||||
* application or library {@code .jar} file
|
||||
*/
|
||||
public static final String DEX_IN_JAR_NAME = "classes.dex";
|
||||
|
||||
/** common prefix for all dex file "magic numbers" */
|
||||
public static final String MAGIC_PREFIX = "dex\n";
|
||||
|
||||
/** common suffix for all dex file "magic numbers" */
|
||||
public static final String MAGIC_SUFFIX = "\0";
|
||||
|
||||
/**
|
||||
* value used to indicate endianness of file contents
|
||||
*/
|
||||
public static final int ENDIAN_TAG = 0x12345678;
|
||||
|
||||
/**
|
||||
* Maximum addressable field or method index.
|
||||
* The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or
|
||||
* meth@CCCC.
|
||||
*/
|
||||
public static /* final */ int MAX_MEMBER_IDX = 0x2222; // 0xFFFF
|
||||
|
||||
/**
|
||||
* Maximum addressable type index.
|
||||
* The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC.
|
||||
*/
|
||||
public static /* final */ int MAX_TYPE_IDX = 0x2222; // 65535
|
||||
|
||||
/**
|
||||
* Returns the API level corresponding to the given magic number,
|
||||
* or {@code -1} if the given array is not a well-formed dex file
|
||||
* magic number.
|
||||
*
|
||||
* @param magic array of bytes containing DEX file magic string
|
||||
* @return API level corresponding to magic string if valid, -1 otherwise.
|
||||
*/
|
||||
public static int magicToApi(byte[] magic) {
|
||||
if (magic.length != 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
|
||||
(magic[7] != '\0')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
|
||||
|
||||
if (version.equals(VERSION_FOR_API_13)) {
|
||||
return API_NO_EXTENDED_OPCODES;
|
||||
} else if (version.equals(VERSION_FOR_API_24)) {
|
||||
return API_DEFINE_INTERFACE_METHODS;
|
||||
} else if (version.equals(VERSION_FOR_API_26)) {
|
||||
return API_METHOD_HANDLES;
|
||||
} else if (version.equals(VERSION_FOR_API_28)) {
|
||||
return API_CONST_METHOD_HANDLE;
|
||||
} else if (version.equals(VERSION_FOR_API_10000)) {
|
||||
return API_SPACES_IN_SIMPLE_NAME;
|
||||
} else if (version.equals(VERSION_CURRENT)) {
|
||||
return API_CURRENT;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the magic number corresponding to the given target API level.
|
||||
*
|
||||
* @param targetApiLevel level of API (minimum supported value 13).
|
||||
* @return Magic string corresponding to API level supplied.
|
||||
*/
|
||||
public static String apiToMagic(int targetApiLevel) {
|
||||
String version;
|
||||
|
||||
if (targetApiLevel >= API_CURRENT) {
|
||||
version = VERSION_CURRENT;
|
||||
} else if (targetApiLevel >= API_SPACES_IN_SIMPLE_NAME) {
|
||||
version = VERSION_FOR_API_10000;
|
||||
} else if (targetApiLevel >= API_CONST_METHOD_HANDLE) {
|
||||
version = VERSION_FOR_API_28;
|
||||
} else if (targetApiLevel >= API_METHOD_HANDLES) {
|
||||
version = VERSION_FOR_API_26;
|
||||
} else if (targetApiLevel >= API_DEFINE_INTERFACE_METHODS) {
|
||||
version = VERSION_FOR_API_24;
|
||||
} else {
|
||||
version = VERSION_FOR_API_13;
|
||||
}
|
||||
|
||||
return MAGIC_PREFIX + version + MAGIC_SUFFIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a DEX file magic string is supported.
|
||||
* @param magic string from DEX file
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSupportedDexMagic(byte[] magic) {
|
||||
int api = magicToApi(magic);
|
||||
return api > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
/**
|
||||
* Thrown when there's an index overflow writing a dex file.
|
||||
*/
|
||||
public final class DexIndexOverflowException extends DexException {
|
||||
public DexIndexOverflowException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DexIndexOverflowException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ByteArrayByteInput;
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
|
||||
/**
|
||||
* An encoded value or array.
|
||||
*/
|
||||
public final class EncodedValue implements Comparable<EncodedValue> {
|
||||
private final byte[] data;
|
||||
|
||||
public EncodedValue(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ByteInput asByteInput() {
|
||||
return new ByteArrayByteInput(data);
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void writeTo(Dex.Section out) {
|
||||
out.write(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(EncodedValue other) {
|
||||
int size = Math.min(data.length, other.data.length);
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (data[i] != other.data[i]) {
|
||||
return (data[i] & 0xff) - (other.data[i] & 0xff);
|
||||
}
|
||||
}
|
||||
return data.length - other.data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toHexString(data[0] & 0xff) + "...(" + data.length + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
import com.pojavdx.dex.util.ByteOutput;
|
||||
|
||||
/**
|
||||
* Read and write {@code encoded_value} primitives.
|
||||
*/
|
||||
public final class EncodedValueCodec {
|
||||
private EncodedValueCodec() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed integral to {@code out}.
|
||||
*/
|
||||
public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {
|
||||
/*
|
||||
* Figure out how many bits are needed to represent the value,
|
||||
* including a sign bit: The bit count is subtracted from 65
|
||||
* and not 64 to account for the sign bit. The xor operation
|
||||
* has the effect of leaving non-negative values alone and
|
||||
* unary complementing negative values (so that a leading zero
|
||||
* count always returns a useful number for our present
|
||||
* purpose).
|
||||
*/
|
||||
int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
int requiredBytes = (requiredBits + 0x07) >> 3;
|
||||
|
||||
/*
|
||||
* Write the header byte, which includes the type and
|
||||
* requiredBytes - 1.
|
||||
*/
|
||||
out.writeByte(type | ((requiredBytes - 1) << 5));
|
||||
|
||||
// Write the value, per se.
|
||||
while (requiredBytes > 0) {
|
||||
out.writeByte((byte) value);
|
||||
value >>= 8;
|
||||
requiredBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an unsigned integral to {@code out}.
|
||||
*/
|
||||
public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {
|
||||
// Figure out how many bits are needed to represent the value.
|
||||
int requiredBits = 64 - Long.numberOfLeadingZeros(value);
|
||||
if (requiredBits == 0) {
|
||||
requiredBits = 1;
|
||||
}
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
int requiredBytes = (requiredBits + 0x07) >> 3;
|
||||
|
||||
/*
|
||||
* Write the header byte, which includes the type and
|
||||
* requiredBytes - 1.
|
||||
*/
|
||||
out.writeByte(type | ((requiredBytes - 1) << 5));
|
||||
|
||||
// Write the value, per se.
|
||||
while (requiredBytes > 0) {
|
||||
out.writeByte((byte) value);
|
||||
value >>= 8;
|
||||
requiredBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a right-zero-extended value to {@code out}.
|
||||
*/
|
||||
public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {
|
||||
// Figure out how many bits are needed to represent the value.
|
||||
int requiredBits = 64 - Long.numberOfTrailingZeros(value);
|
||||
if (requiredBits == 0) {
|
||||
requiredBits = 1;
|
||||
}
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
int requiredBytes = (requiredBits + 0x07) >> 3;
|
||||
|
||||
// Scootch the first bits to be written down to the low-order bits.
|
||||
value >>= 64 - (requiredBytes * 8);
|
||||
|
||||
/*
|
||||
* Write the header byte, which includes the type and
|
||||
* requiredBytes - 1.
|
||||
*/
|
||||
out.writeByte(type | ((requiredBytes - 1) << 5));
|
||||
|
||||
// Write the value, per se.
|
||||
while (requiredBytes > 0) {
|
||||
out.writeByte((byte) value);
|
||||
value >>= 8;
|
||||
requiredBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a signed integer.
|
||||
*
|
||||
* @param zwidth byte count minus one
|
||||
*/
|
||||
public static int readSignedInt(ByteInput in, int zwidth) {
|
||||
int result = 0;
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
|
||||
}
|
||||
result >>= (3 - zwidth) * 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned integer.
|
||||
*
|
||||
* @param zwidth byte count minus one
|
||||
* @param fillOnRight true to zero fill on the right; false on the left
|
||||
*/
|
||||
public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {
|
||||
int result = 0;
|
||||
if (!fillOnRight) {
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
|
||||
}
|
||||
result >>>= (3 - zwidth) * 8;
|
||||
} else {
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a signed long.
|
||||
*
|
||||
* @param zwidth byte count minus one
|
||||
*/
|
||||
public static long readSignedLong(ByteInput in, int zwidth) {
|
||||
long result = 0;
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
|
||||
}
|
||||
result >>= (7 - zwidth) * 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned long.
|
||||
*
|
||||
* @param zwidth byte count minus one
|
||||
* @param fillOnRight true to zero fill on the right; false on the left
|
||||
*/
|
||||
public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {
|
||||
long result = 0;
|
||||
if (!fillOnRight) {
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
|
||||
}
|
||||
result >>>= (7 - zwidth) * 8;
|
||||
} else {
|
||||
for (int i = zwidth; i >= 0; i--) {
|
||||
result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,307 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
|
||||
/**
|
||||
* Pull parser for encoded values.
|
||||
*/
|
||||
public final class EncodedValueReader {
|
||||
public static final int ENCODED_BYTE = 0x00;
|
||||
public static final int ENCODED_SHORT = 0x02;
|
||||
public static final int ENCODED_CHAR = 0x03;
|
||||
public static final int ENCODED_INT = 0x04;
|
||||
public static final int ENCODED_LONG = 0x06;
|
||||
public static final int ENCODED_FLOAT = 0x10;
|
||||
public static final int ENCODED_DOUBLE = 0x11;
|
||||
public static final int ENCODED_METHOD_TYPE = 0x15;
|
||||
public static final int ENCODED_METHOD_HANDLE = 0x16;
|
||||
public static final int ENCODED_STRING = 0x17;
|
||||
public static final int ENCODED_TYPE = 0x18;
|
||||
public static final int ENCODED_FIELD = 0x19;
|
||||
public static final int ENCODED_ENUM = 0x1b;
|
||||
public static final int ENCODED_METHOD = 0x1a;
|
||||
public static final int ENCODED_ARRAY = 0x1c;
|
||||
public static final int ENCODED_ANNOTATION = 0x1d;
|
||||
public static final int ENCODED_NULL = 0x1e;
|
||||
public static final int ENCODED_BOOLEAN = 0x1f;
|
||||
|
||||
/** placeholder type if the type is not yet known */
|
||||
private static final int MUST_READ = -1;
|
||||
|
||||
protected final ByteInput in;
|
||||
private int type = MUST_READ;
|
||||
private int annotationType;
|
||||
private int arg;
|
||||
|
||||
public EncodedValueReader(ByteInput in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public EncodedValueReader(EncodedValue in) {
|
||||
this(in.asByteInput());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new encoded value reader whose only value is the specified
|
||||
* known type. This is useful for encoded values without a type prefix,
|
||||
* such as class_def_item's encoded_array or annotation_item's
|
||||
* encoded_annotation.
|
||||
*/
|
||||
public EncodedValueReader(ByteInput in, int knownType) {
|
||||
this.in = in;
|
||||
this.type = knownType;
|
||||
}
|
||||
|
||||
public EncodedValueReader(EncodedValue in, int knownType) {
|
||||
this(in.asByteInput(), knownType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the next value to read.
|
||||
*/
|
||||
public int peek() {
|
||||
if (type == MUST_READ) {
|
||||
int argAndType = in.readByte() & 0xff;
|
||||
type = argAndType & 0x1f;
|
||||
arg = (argAndType & 0xe0) >> 5;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins reading the elements of an array, returning the array's size. The
|
||||
* caller must follow up by calling a read method for each element in the
|
||||
* array. For example, this reads a byte array: <pre> {@code
|
||||
* int arraySize = readArray();
|
||||
* for (int i = 0, i < arraySize; i++) {
|
||||
* readByte();
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public int readArray() {
|
||||
checkType(ENCODED_ARRAY);
|
||||
type = MUST_READ;
|
||||
return Leb128.readUnsignedLeb128(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins reading the fields of an annotation, returning the number of
|
||||
* fields. The caller must follow up by making alternating calls to {@link
|
||||
* #readAnnotationName()} and another read method. For example, this reads
|
||||
* an annotation whose fields are all bytes: <pre> {@code
|
||||
* int fieldCount = readAnnotation();
|
||||
* int annotationType = getAnnotationType();
|
||||
* for (int i = 0; i < fieldCount; i++) {
|
||||
* readAnnotationName();
|
||||
* readByte();
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public int readAnnotation() {
|
||||
checkType(ENCODED_ANNOTATION);
|
||||
type = MUST_READ;
|
||||
annotationType = Leb128.readUnsignedLeb128(in);
|
||||
return Leb128.readUnsignedLeb128(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the annotation just returned by {@link
|
||||
* #readAnnotation()}. This method's value is undefined unless the most
|
||||
* recent call was to {@link #readAnnotation()}.
|
||||
*/
|
||||
public int getAnnotationType() {
|
||||
return annotationType;
|
||||
}
|
||||
|
||||
public int readAnnotationName() {
|
||||
return Leb128.readUnsignedLeb128(in);
|
||||
}
|
||||
|
||||
public byte readByte() {
|
||||
checkType(ENCODED_BYTE);
|
||||
type = MUST_READ;
|
||||
return (byte) EncodedValueCodec.readSignedInt(in, arg);
|
||||
}
|
||||
|
||||
public short readShort() {
|
||||
checkType(ENCODED_SHORT);
|
||||
type = MUST_READ;
|
||||
return (short) EncodedValueCodec.readSignedInt(in, arg);
|
||||
}
|
||||
|
||||
public char readChar() {
|
||||
checkType(ENCODED_CHAR);
|
||||
type = MUST_READ;
|
||||
return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readInt() {
|
||||
checkType(ENCODED_INT);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readSignedInt(in, arg);
|
||||
}
|
||||
|
||||
public long readLong() {
|
||||
checkType(ENCODED_LONG);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readSignedLong(in, arg);
|
||||
}
|
||||
|
||||
public float readFloat() {
|
||||
checkType(ENCODED_FLOAT);
|
||||
type = MUST_READ;
|
||||
return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));
|
||||
}
|
||||
|
||||
public double readDouble() {
|
||||
checkType(ENCODED_DOUBLE);
|
||||
type = MUST_READ;
|
||||
return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));
|
||||
}
|
||||
|
||||
public int readMethodType() {
|
||||
checkType(ENCODED_METHOD_TYPE);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readMethodHandle() {
|
||||
checkType(ENCODED_METHOD_HANDLE);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readString() {
|
||||
checkType(ENCODED_STRING);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readType() {
|
||||
checkType(ENCODED_TYPE);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readField() {
|
||||
checkType(ENCODED_FIELD);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readEnum() {
|
||||
checkType(ENCODED_ENUM);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public int readMethod() {
|
||||
checkType(ENCODED_METHOD);
|
||||
type = MUST_READ;
|
||||
return EncodedValueCodec.readUnsignedInt(in, arg, false);
|
||||
}
|
||||
|
||||
public void readNull() {
|
||||
checkType(ENCODED_NULL);
|
||||
type = MUST_READ;
|
||||
}
|
||||
|
||||
public boolean readBoolean() {
|
||||
checkType(ENCODED_BOOLEAN);
|
||||
type = MUST_READ;
|
||||
return arg != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips a single value, including its nested values if it is an array or
|
||||
* annotation.
|
||||
*/
|
||||
public void skipValue() {
|
||||
switch (peek()) {
|
||||
case ENCODED_BYTE:
|
||||
readByte();
|
||||
break;
|
||||
case ENCODED_SHORT:
|
||||
readShort();
|
||||
break;
|
||||
case ENCODED_CHAR:
|
||||
readChar();
|
||||
break;
|
||||
case ENCODED_INT:
|
||||
readInt();
|
||||
break;
|
||||
case ENCODED_LONG:
|
||||
readLong();
|
||||
break;
|
||||
case ENCODED_FLOAT:
|
||||
readFloat();
|
||||
break;
|
||||
case ENCODED_DOUBLE:
|
||||
readDouble();
|
||||
break;
|
||||
case ENCODED_METHOD_TYPE:
|
||||
readMethodType();
|
||||
break;
|
||||
case ENCODED_METHOD_HANDLE:
|
||||
readMethodHandle();
|
||||
break;
|
||||
case ENCODED_STRING:
|
||||
readString();
|
||||
break;
|
||||
case ENCODED_TYPE:
|
||||
readType();
|
||||
break;
|
||||
case ENCODED_FIELD:
|
||||
readField();
|
||||
break;
|
||||
case ENCODED_ENUM:
|
||||
readEnum();
|
||||
break;
|
||||
case ENCODED_METHOD:
|
||||
readMethod();
|
||||
break;
|
||||
case ENCODED_ARRAY:
|
||||
for (int i = 0, size = readArray(); i < size; i++) {
|
||||
skipValue();
|
||||
}
|
||||
break;
|
||||
case ENCODED_ANNOTATION:
|
||||
for (int i = 0, size = readAnnotation(); i < size; i++) {
|
||||
readAnnotationName();
|
||||
skipValue();
|
||||
}
|
||||
break;
|
||||
case ENCODED_NULL:
|
||||
readNull();
|
||||
break;
|
||||
case ENCODED_BOOLEAN:
|
||||
readBoolean();
|
||||
break;
|
||||
default:
|
||||
throw new DexException("Unexpected type: " + Integer.toHexString(type));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkType(int expected) {
|
||||
if (peek() != expected) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Expected %x but was %x", expected, peek()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
public final class FieldId implements Comparable<FieldId> {
|
||||
private final Dex dex;
|
||||
private final int declaringClassIndex;
|
||||
private final int typeIndex;
|
||||
private final int nameIndex;
|
||||
|
||||
public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {
|
||||
this.dex = dex;
|
||||
this.declaringClassIndex = declaringClassIndex;
|
||||
this.typeIndex = typeIndex;
|
||||
this.nameIndex = nameIndex;
|
||||
}
|
||||
|
||||
public int getDeclaringClassIndex() {
|
||||
return declaringClassIndex;
|
||||
}
|
||||
|
||||
public int getTypeIndex() {
|
||||
return typeIndex;
|
||||
}
|
||||
|
||||
public int getNameIndex() {
|
||||
return nameIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FieldId other) {
|
||||
if (declaringClassIndex != other.declaringClassIndex) {
|
||||
return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
|
||||
}
|
||||
if (nameIndex != other.nameIndex) {
|
||||
return Unsigned.compare(nameIndex, other.nameIndex);
|
||||
}
|
||||
return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0
|
||||
}
|
||||
|
||||
public void writeTo(Dex.Section out) {
|
||||
out.writeUnsignedShort(declaringClassIndex);
|
||||
out.writeUnsignedShort(typeIndex);
|
||||
out.writeInt(nameIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (dex == null) {
|
||||
return declaringClassIndex + " " + typeIndex + " " + nameIndex;
|
||||
}
|
||||
return dex.typeNames().get(typeIndex) + "." + dex.strings().get(nameIndex);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
import com.pojavdx.dex.util.ByteOutput;
|
||||
|
||||
/**
|
||||
* Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3
|
||||
* section 7.6.
|
||||
*/
|
||||
public final class Leb128 {
|
||||
private Leb128() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of bytes in the unsigned LEB128 encoding of the
|
||||
* given value.
|
||||
*
|
||||
* @param value the value in question
|
||||
* @return its write size, in bytes
|
||||
*/
|
||||
public static int unsignedLeb128Size(int value) {
|
||||
// TODO: This could be much cleverer.
|
||||
|
||||
int remaining = value >> 7;
|
||||
int count = 0;
|
||||
|
||||
while (remaining != 0) {
|
||||
remaining >>= 7;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an signed integer from {@code in}.
|
||||
*/
|
||||
public static int readSignedLeb128(ByteInput in) {
|
||||
int result = 0;
|
||||
int cur;
|
||||
int count = 0;
|
||||
int signBits = -1;
|
||||
|
||||
do {
|
||||
cur = in.readByte() & 0xff;
|
||||
result |= (cur & 0x7f) << (count * 7);
|
||||
signBits <<= 7;
|
||||
count++;
|
||||
} while (((cur & 0x80) == 0x80) && count < 5);
|
||||
|
||||
if ((cur & 0x80) == 0x80) {
|
||||
throw new DexException("invalid LEB128 sequence");
|
||||
}
|
||||
|
||||
// Sign extend if appropriate
|
||||
if (((signBits >> 1) & result) != 0 ) {
|
||||
result |= signBits;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned integer from {@code in}.
|
||||
*/
|
||||
public static int readUnsignedLeb128(ByteInput in) {
|
||||
int result = 0;
|
||||
int cur;
|
||||
int count = 0;
|
||||
|
||||
do {
|
||||
cur = in.readByte() & 0xff;
|
||||
result |= (cur & 0x7f) << (count * 7);
|
||||
count++;
|
||||
} while (((cur & 0x80) == 0x80) && count < 5);
|
||||
|
||||
if ((cur & 0x80) == 0x80) {
|
||||
throw new DexException("invalid LEB128 sequence");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes {@code value} as an unsigned integer to {@code out}, starting at
|
||||
* {@code offset}. Returns the number of bytes written.
|
||||
*/
|
||||
public static void writeUnsignedLeb128(ByteOutput out, int value) {
|
||||
int remaining = value >>> 7;
|
||||
|
||||
while (remaining != 0) {
|
||||
out.writeByte((byte) ((value & 0x7f) | 0x80));
|
||||
value = remaining;
|
||||
remaining >>>= 7;
|
||||
}
|
||||
|
||||
out.writeByte((byte) (value & 0x7f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes {@code value} as a signed integer to {@code out}, starting at
|
||||
* {@code offset}. Returns the number of bytes written.
|
||||
*/
|
||||
public static void writeSignedLeb128(ByteOutput out, int value) {
|
||||
int remaining = value >> 7;
|
||||
boolean hasMore = true;
|
||||
int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
|
||||
|
||||
while (hasMore) {
|
||||
hasMore = (remaining != end)
|
||||
|| ((remaining & 1) != ((value >> 6) & 1));
|
||||
|
||||
out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));
|
||||
value = remaining;
|
||||
remaining >>= 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.Dex.Section;
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
/**
|
||||
* A method_handle_item:
|
||||
* https://source.android.com/devices/tech/dalvik/dex-format#method-handle-item
|
||||
*/
|
||||
public class MethodHandle implements Comparable<MethodHandle> {
|
||||
|
||||
/**
|
||||
* A method handle type code:
|
||||
* https://source.android.com/devices/tech/dalvik/dex-format#method-handle-type-codes
|
||||
*/
|
||||
public enum MethodHandleType {
|
||||
METHOD_HANDLE_TYPE_STATIC_PUT(0x00),
|
||||
METHOD_HANDLE_TYPE_STATIC_GET(0x01),
|
||||
METHOD_HANDLE_TYPE_INSTANCE_PUT(0x02),
|
||||
METHOD_HANDLE_TYPE_INSTANCE_GET(0x03),
|
||||
METHOD_HANDLE_TYPE_INVOKE_STATIC(0x04),
|
||||
METHOD_HANDLE_TYPE_INVOKE_INSTANCE(0x05),
|
||||
METHOD_HANDLE_TYPE_INVOKE_DIRECT(0x06),
|
||||
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR(0x07),
|
||||
METHOD_HANDLE_TYPE_INVOKE_INTERFACE(0x08);
|
||||
|
||||
private final int value;
|
||||
|
||||
MethodHandleType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
static MethodHandleType fromValue(int value) {
|
||||
for (MethodHandleType methodHandleType : values()) {
|
||||
if (methodHandleType.value == value) {
|
||||
return methodHandleType;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(value));
|
||||
}
|
||||
|
||||
public boolean isField() {
|
||||
switch (this) {
|
||||
case METHOD_HANDLE_TYPE_STATIC_PUT:
|
||||
case METHOD_HANDLE_TYPE_STATIC_GET:
|
||||
case METHOD_HANDLE_TYPE_INSTANCE_PUT:
|
||||
case METHOD_HANDLE_TYPE_INSTANCE_GET:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Dex dex;
|
||||
private final MethodHandleType methodHandleType;
|
||||
private final int unused1;
|
||||
private final int fieldOrMethodId;
|
||||
private final int unused2;
|
||||
|
||||
public MethodHandle(
|
||||
Dex dex,
|
||||
MethodHandleType methodHandleType,
|
||||
int unused1,
|
||||
int fieldOrMethodId,
|
||||
int unused2) {
|
||||
this.dex = dex;
|
||||
this.methodHandleType = methodHandleType;
|
||||
this.unused1 = unused1;
|
||||
this.fieldOrMethodId = fieldOrMethodId;
|
||||
this.unused2 = unused2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodHandle o) {
|
||||
if (methodHandleType != o.methodHandleType) {
|
||||
return methodHandleType.compareTo(o.methodHandleType);
|
||||
}
|
||||
return Unsigned.compare(fieldOrMethodId, o.fieldOrMethodId);
|
||||
}
|
||||
|
||||
public MethodHandleType getMethodHandleType() {
|
||||
return methodHandleType;
|
||||
}
|
||||
|
||||
public int getUnused1() {
|
||||
return unused1;
|
||||
}
|
||||
|
||||
public int getFieldOrMethodId() {
|
||||
return fieldOrMethodId;
|
||||
}
|
||||
|
||||
public int getUnused2() {
|
||||
return unused2;
|
||||
}
|
||||
|
||||
public void writeTo(Section out) {
|
||||
out.writeUnsignedShort(methodHandleType.value);
|
||||
out.writeUnsignedShort(unused1);
|
||||
out.writeUnsignedShort(fieldOrMethodId);
|
||||
out.writeUnsignedShort(unused2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (dex == null) {
|
||||
return methodHandleType + " " + fieldOrMethodId;
|
||||
}
|
||||
return methodHandleType
|
||||
+ " "
|
||||
+ (methodHandleType.isField()
|
||||
? dex.fieldIds().get(fieldOrMethodId)
|
||||
: dex.methodIds().get(fieldOrMethodId));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
public final class MethodId implements Comparable<MethodId> {
|
||||
private final Dex dex;
|
||||
private final int declaringClassIndex;
|
||||
private final int protoIndex;
|
||||
private final int nameIndex;
|
||||
|
||||
public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {
|
||||
this.dex = dex;
|
||||
this.declaringClassIndex = declaringClassIndex;
|
||||
this.protoIndex = protoIndex;
|
||||
this.nameIndex = nameIndex;
|
||||
}
|
||||
|
||||
public int getDeclaringClassIndex() {
|
||||
return declaringClassIndex;
|
||||
}
|
||||
|
||||
public int getProtoIndex() {
|
||||
return protoIndex;
|
||||
}
|
||||
|
||||
public int getNameIndex() {
|
||||
return nameIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodId other) {
|
||||
if (declaringClassIndex != other.declaringClassIndex) {
|
||||
return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
|
||||
}
|
||||
if (nameIndex != other.nameIndex) {
|
||||
return Unsigned.compare(nameIndex, other.nameIndex);
|
||||
}
|
||||
return Unsigned.compare(protoIndex, other.protoIndex);
|
||||
}
|
||||
|
||||
public void writeTo(Dex.Section out) {
|
||||
out.writeUnsignedShort(declaringClassIndex);
|
||||
out.writeUnsignedShort(protoIndex);
|
||||
out.writeInt(nameIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (dex == null) {
|
||||
return declaringClassIndex + " " + protoIndex + " " + nameIndex;
|
||||
}
|
||||
return dex.typeNames().get(declaringClassIndex)
|
||||
+ "." + dex.strings().get(nameIndex)
|
||||
+ dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.ByteInput;
|
||||
import java.io.UTFDataFormatException;
|
||||
|
||||
/**
|
||||
* Modified UTF-8 as described in the dex file format spec.
|
||||
*/
|
||||
public final class Mutf8 {
|
||||
private Mutf8() {}
|
||||
|
||||
/**
|
||||
* Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is
|
||||
* encountered. Returns a new string containing the decoded characters.
|
||||
*/
|
||||
public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {
|
||||
int s = 0;
|
||||
while (true) {
|
||||
char a = (char) (in.readByte() & 0xff);
|
||||
if (a == 0) {
|
||||
return new String(out, 0, s);
|
||||
}
|
||||
out[s] = a;
|
||||
if (a < '\u0080') {
|
||||
s++;
|
||||
} else if ((a & 0xe0) == 0xc0) {
|
||||
int b = in.readByte() & 0xff;
|
||||
if ((b & 0xC0) != 0x80) {
|
||||
throw new UTFDataFormatException("bad second byte");
|
||||
}
|
||||
out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
|
||||
} else if ((a & 0xf0) == 0xe0) {
|
||||
int b = in.readByte() & 0xff;
|
||||
int c = in.readByte() & 0xff;
|
||||
if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
|
||||
throw new UTFDataFormatException("bad second or third byte");
|
||||
}
|
||||
out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
|
||||
} else {
|
||||
throw new UTFDataFormatException("bad byte");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes the modified UTF8 representation of 's' would take.
|
||||
*/
|
||||
private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
|
||||
long result = 0;
|
||||
final int length = s.length();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
|
||||
++result;
|
||||
} else if (ch <= 2047) {
|
||||
result += 2;
|
||||
} else {
|
||||
result += 3;
|
||||
}
|
||||
if (shortLength && result > 65535) {
|
||||
throw new UTFDataFormatException("String more than 65535 UTF bytes long");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code
|
||||
* dst}, starting at {@code offset}.
|
||||
*/
|
||||
public static void encode(byte[] dst, int offset, String s) {
|
||||
final int length = s.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
|
||||
dst[offset++] = (byte) ch;
|
||||
} else if (ch <= 2047) {
|
||||
dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
|
||||
dst[offset++] = (byte) (0x80 | (0x3f & ch));
|
||||
} else {
|
||||
dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
|
||||
dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
|
||||
dst[offset++] = (byte) (0x80 | (0x3f & ch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the <i>modified UTF-8</i> form of {@code s}.
|
||||
*/
|
||||
public static byte[] encode(String s) throws UTFDataFormatException {
|
||||
int utfCount = (int) countBytes(s, true);
|
||||
byte[] result = new byte[utfCount];
|
||||
encode(result, 0, s);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
public final class ProtoId implements Comparable<ProtoId> {
|
||||
private final Dex dex;
|
||||
private final int shortyIndex;
|
||||
private final int returnTypeIndex;
|
||||
private final int parametersOffset;
|
||||
|
||||
public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {
|
||||
this.dex = dex;
|
||||
this.shortyIndex = shortyIndex;
|
||||
this.returnTypeIndex = returnTypeIndex;
|
||||
this.parametersOffset = parametersOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ProtoId other) {
|
||||
if (returnTypeIndex != other.returnTypeIndex) {
|
||||
return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);
|
||||
}
|
||||
return Unsigned.compare(parametersOffset, other.parametersOffset);
|
||||
}
|
||||
|
||||
public int getShortyIndex() {
|
||||
return shortyIndex;
|
||||
}
|
||||
|
||||
public int getReturnTypeIndex() {
|
||||
return returnTypeIndex;
|
||||
}
|
||||
|
||||
public int getParametersOffset() {
|
||||
return parametersOffset;
|
||||
}
|
||||
|
||||
public void writeTo(Dex.Section out) {
|
||||
out.writeInt(shortyIndex);
|
||||
out.writeInt(returnTypeIndex);
|
||||
out.writeInt(parametersOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (dex == null) {
|
||||
return shortyIndex + " " + returnTypeIndex + " " + parametersOffset;
|
||||
}
|
||||
|
||||
return dex.strings().get(shortyIndex)
|
||||
+ ": " + dex.typeNames().get(returnTypeIndex)
|
||||
+ " " + dex.readTypeList(parametersOffset);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
public final class SizeOf {
|
||||
private SizeOf() {}
|
||||
|
||||
public static final int UBYTE = 1;
|
||||
public static final int USHORT = 2;
|
||||
public static final int UINT = 4;
|
||||
|
||||
public static final int SIGNATURE = UBYTE * 20;
|
||||
|
||||
/**
|
||||
* magic ubyte[8]
|
||||
* checksum uint
|
||||
* signature ubyte[20]
|
||||
* file_size uint
|
||||
* header_size uint
|
||||
* endian_tag uint
|
||||
* link_size uint
|
||||
* link_off uint
|
||||
* map_off uint
|
||||
* string_ids_size uint
|
||||
* string_ids_off uint
|
||||
* type_ids_size uint
|
||||
* type_ids_off uint
|
||||
* proto_ids_size uint
|
||||
* proto_ids_off uint
|
||||
* field_ids_size uint
|
||||
* field_ids_off uint
|
||||
* method_ids_size uint
|
||||
* method_ids_off uint
|
||||
* class_defs_size uint
|
||||
* class_defs_off uint
|
||||
* data_size uint
|
||||
* data_off uint
|
||||
*/
|
||||
public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70
|
||||
|
||||
/**
|
||||
* string_data_off uint
|
||||
*/
|
||||
public static final int STRING_ID_ITEM = UINT;
|
||||
|
||||
/**
|
||||
* descriptor_idx uint
|
||||
*/
|
||||
public static final int TYPE_ID_ITEM = UINT;
|
||||
|
||||
/**
|
||||
* type_idx ushort
|
||||
*/
|
||||
public static final int TYPE_ITEM = USHORT;
|
||||
|
||||
/**
|
||||
* shorty_idx uint
|
||||
* return_type_idx uint
|
||||
* return_type_idx uint
|
||||
*/
|
||||
public static final int PROTO_ID_ITEM = UINT + UINT + UINT;
|
||||
|
||||
/**
|
||||
* class_idx ushort
|
||||
* type_idx/proto_idx ushort
|
||||
* name_idx uint
|
||||
*/
|
||||
public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;
|
||||
|
||||
/**
|
||||
* class_idx uint
|
||||
* access_flags uint
|
||||
* superclass_idx uint
|
||||
* interfaces_off uint
|
||||
* source_file_idx uint
|
||||
* annotations_off uint
|
||||
* class_data_off uint
|
||||
* static_values_off uint
|
||||
*/
|
||||
public static final int CLASS_DEF_ITEM = 8 * UINT;
|
||||
|
||||
/**
|
||||
* type ushort
|
||||
* unused ushort
|
||||
* size uint
|
||||
* offset uint
|
||||
*/
|
||||
public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;
|
||||
|
||||
/**
|
||||
* start_addr uint
|
||||
* insn_count ushort
|
||||
* handler_off ushort
|
||||
*/
|
||||
public static final int TRY_ITEM = UINT + USHORT + USHORT;
|
||||
|
||||
/**
|
||||
* call_site_off uint
|
||||
*/
|
||||
public static final int CALL_SITE_ID_ITEM = UINT;
|
||||
|
||||
/**
|
||||
* method_handle_type ushort
|
||||
* unused ushort
|
||||
* field_or_method_id ushort
|
||||
* unused ushort
|
||||
*/
|
||||
public static final int METHOD_HANDLE_ITEM = USHORT + USHORT + USHORT + USHORT;
|
||||
}
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The file header and map.
|
||||
*/
|
||||
public final class TableOfContents {
|
||||
|
||||
/*
|
||||
* TODO: factor out ID constants.
|
||||
*/
|
||||
|
||||
public final Section header = new Section(0x0000);
|
||||
public final Section stringIds = new Section(0x0001);
|
||||
public final Section typeIds = new Section(0x0002);
|
||||
public final Section protoIds = new Section(0x0003);
|
||||
public final Section fieldIds = new Section(0x0004);
|
||||
public final Section methodIds = new Section(0x0005);
|
||||
public final Section classDefs = new Section(0x0006);
|
||||
public final Section callSiteIds = new Section(0x0007);
|
||||
public final Section methodHandles = new Section(0x0008);
|
||||
public final Section mapList = new Section(0x1000);
|
||||
public final Section typeLists = new Section(0x1001);
|
||||
public final Section annotationSetRefLists = new Section(0x1002);
|
||||
public final Section annotationSets = new Section(0x1003);
|
||||
public final Section classDatas = new Section(0x2000);
|
||||
public final Section codes = new Section(0x2001);
|
||||
public final Section stringDatas = new Section(0x2002);
|
||||
public final Section debugInfos = new Section(0x2003);
|
||||
public final Section annotations = new Section(0x2004);
|
||||
public final Section encodedArrays = new Section(0x2005);
|
||||
public final Section annotationsDirectories = new Section(0x2006);
|
||||
public final Section[] sections = {
|
||||
header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList, callSiteIds,
|
||||
methodHandles, typeLists, annotationSetRefLists, annotationSets, classDatas, codes,
|
||||
stringDatas, debugInfos, annotations, encodedArrays, annotationsDirectories
|
||||
};
|
||||
|
||||
public int apiLevel;
|
||||
public int checksum;
|
||||
public byte[] signature;
|
||||
public int fileSize;
|
||||
public int linkSize;
|
||||
public int linkOff;
|
||||
public int dataSize;
|
||||
public int dataOff;
|
||||
|
||||
public TableOfContents() {
|
||||
signature = new byte[20];
|
||||
}
|
||||
|
||||
public void readFrom(Dex dex) throws IOException {
|
||||
readHeader(dex.open(0));
|
||||
readMap(dex.open(mapList.off));
|
||||
computeSizesFromOffsets();
|
||||
}
|
||||
|
||||
private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
|
||||
byte[] magic = headerIn.readByteArray(8);
|
||||
|
||||
if (!DexFormat.isSupportedDexMagic(magic)) {
|
||||
String msg =
|
||||
String.format("Unexpected magic: [0x%02x, 0x%02x, 0x%02x, 0x%02x, "
|
||||
+ "0x%02x, 0x%02x, 0x%02x, 0x%02x]",
|
||||
magic[0], magic[1], magic[2], magic[3],
|
||||
magic[4], magic[5], magic[6], magic[7]);
|
||||
throw new DexException(msg);
|
||||
}
|
||||
|
||||
apiLevel = DexFormat.magicToApi(magic);
|
||||
checksum = headerIn.readInt();
|
||||
signature = headerIn.readByteArray(20);
|
||||
fileSize = headerIn.readInt();
|
||||
int headerSize = headerIn.readInt();
|
||||
if (headerSize != SizeOf.HEADER_ITEM) {
|
||||
throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize));
|
||||
}
|
||||
int endianTag = headerIn.readInt();
|
||||
if (endianTag != DexFormat.ENDIAN_TAG) {
|
||||
throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag));
|
||||
}
|
||||
linkSize = headerIn.readInt();
|
||||
linkOff = headerIn.readInt();
|
||||
mapList.off = headerIn.readInt();
|
||||
if (mapList.off == 0) {
|
||||
throw new DexException("Cannot merge dex files that do not contain a map");
|
||||
}
|
||||
stringIds.size = headerIn.readInt();
|
||||
stringIds.off = headerIn.readInt();
|
||||
typeIds.size = headerIn.readInt();
|
||||
typeIds.off = headerIn.readInt();
|
||||
protoIds.size = headerIn.readInt();
|
||||
protoIds.off = headerIn.readInt();
|
||||
fieldIds.size = headerIn.readInt();
|
||||
fieldIds.off = headerIn.readInt();
|
||||
methodIds.size = headerIn.readInt();
|
||||
methodIds.off = headerIn.readInt();
|
||||
classDefs.size = headerIn.readInt();
|
||||
classDefs.off = headerIn.readInt();
|
||||
dataSize = headerIn.readInt();
|
||||
dataOff = headerIn.readInt();
|
||||
}
|
||||
|
||||
private void readMap(Dex.Section in) throws IOException {
|
||||
int mapSize = in.readInt();
|
||||
Section previous = null;
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
short type = in.readShort();
|
||||
in.readShort(); // unused
|
||||
Section section = getSection(type);
|
||||
int size = in.readInt();
|
||||
int offset = in.readInt();
|
||||
|
||||
if ((section.size != 0 && section.size != size)
|
||||
|| (section.off != -1 && section.off != offset)) {
|
||||
throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
|
||||
}
|
||||
|
||||
section.size = size;
|
||||
section.off = offset;
|
||||
|
||||
if (previous != null && previous.off > section.off) {
|
||||
throw new DexException("Map is unsorted at " + previous + ", " + section);
|
||||
}
|
||||
|
||||
previous = section;
|
||||
}
|
||||
Arrays.sort(sections);
|
||||
}
|
||||
|
||||
public void computeSizesFromOffsets() {
|
||||
int end = dataOff + dataSize;
|
||||
for (int i = sections.length - 1; i >= 0; i--) {
|
||||
Section section = sections[i];
|
||||
if (section.off == -1) {
|
||||
continue;
|
||||
}
|
||||
if (section.off > end) {
|
||||
throw new DexException("Map is unsorted at " + section);
|
||||
}
|
||||
section.byteCount = end - section.off;
|
||||
end = section.off;
|
||||
}
|
||||
}
|
||||
|
||||
private Section getSection(short type) {
|
||||
for (Section section : sections) {
|
||||
if (section.type == type) {
|
||||
return section;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No such map item: " + type);
|
||||
}
|
||||
|
||||
public void writeHeader(Dex.Section out, int api) throws IOException {
|
||||
out.write(DexFormat.apiToMagic(api).getBytes("UTF-8"));
|
||||
out.writeInt(checksum);
|
||||
out.write(signature);
|
||||
out.writeInt(fileSize);
|
||||
out.writeInt(SizeOf.HEADER_ITEM);
|
||||
out.writeInt(DexFormat.ENDIAN_TAG);
|
||||
out.writeInt(linkSize);
|
||||
out.writeInt(linkOff);
|
||||
out.writeInt(mapList.off);
|
||||
out.writeInt(stringIds.size);
|
||||
out.writeInt(stringIds.off);
|
||||
out.writeInt(typeIds.size);
|
||||
out.writeInt(typeIds.off);
|
||||
out.writeInt(protoIds.size);
|
||||
out.writeInt(protoIds.off);
|
||||
out.writeInt(fieldIds.size);
|
||||
out.writeInt(fieldIds.off);
|
||||
out.writeInt(methodIds.size);
|
||||
out.writeInt(methodIds.off);
|
||||
out.writeInt(classDefs.size);
|
||||
out.writeInt(classDefs.off);
|
||||
out.writeInt(dataSize);
|
||||
out.writeInt(dataOff);
|
||||
}
|
||||
|
||||
public void writeMap(Dex.Section out) throws IOException {
|
||||
int count = 0;
|
||||
for (Section section : sections) {
|
||||
if (section.exists()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
out.writeInt(count);
|
||||
for (Section section : sections) {
|
||||
if (section.exists()) {
|
||||
out.writeShort(section.type);
|
||||
out.writeShort((short) 0);
|
||||
out.writeInt(section.size);
|
||||
out.writeInt(section.off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Section implements Comparable<Section> {
|
||||
public final short type;
|
||||
public int size = 0;
|
||||
public int off = -1;
|
||||
public int byteCount = 0;
|
||||
|
||||
public Section(int type) {
|
||||
this.type = (short) type;
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return size > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Section section) {
|
||||
if (off != section.off) {
|
||||
return off < section.off ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex;
|
||||
|
||||
import com.pojavdx.dex.util.Unsigned;
|
||||
|
||||
public final class TypeList implements Comparable<TypeList> {
|
||||
|
||||
public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);
|
||||
|
||||
private final Dex dex;
|
||||
private final short[] types;
|
||||
|
||||
public TypeList(Dex dex, short[] types) {
|
||||
this.dex = dex;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public short[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TypeList other) {
|
||||
for (int i = 0; i < types.length && i < other.types.length; i++) {
|
||||
if (types[i] != other.types[i]) {
|
||||
return Unsigned.compare(types[i], other.types[i]);
|
||||
}
|
||||
}
|
||||
return Unsigned.compare(types.length, other.types.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("(");
|
||||
for (int i = 0, typesLength = types.length; i < typesLength; i++) {
|
||||
result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);
|
||||
}
|
||||
result.append(")");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
public final class ByteArrayByteInput implements ByteInput {
|
||||
|
||||
private final byte[] bytes;
|
||||
private int position;
|
||||
|
||||
public ByteArrayByteInput(byte... bytes) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
return bytes[position++];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
/**
|
||||
* A byte source.
|
||||
*/
|
||||
public interface ByteInput {
|
||||
|
||||
/**
|
||||
* Returns a byte.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if all bytes have been read.
|
||||
*/
|
||||
byte readByte();
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
/**
|
||||
* A byte sink.
|
||||
*/
|
||||
public interface ByteOutput {
|
||||
|
||||
/**
|
||||
* Writes a byte.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if all bytes have been written.
|
||||
*/
|
||||
void writeByte(int i);
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Exception which carries around structured context.
|
||||
*/
|
||||
public class ExceptionWithContext extends RuntimeException {
|
||||
/** {@code non-null;} human-oriented context of the exception */
|
||||
private StringBuffer context;
|
||||
|
||||
/**
|
||||
* Augments the given exception with the given context, and return the
|
||||
* result. The result is either the given exception if it was an
|
||||
* {@link ExceptionWithContext}, or a newly-constructed exception if it
|
||||
* was not.
|
||||
*
|
||||
* @param ex {@code non-null;} the exception to augment
|
||||
* @param str {@code non-null;} context to add
|
||||
* @return {@code non-null;} an appropriate instance
|
||||
*/
|
||||
public static ExceptionWithContext withContext(Throwable ex, String str) {
|
||||
ExceptionWithContext ewc;
|
||||
|
||||
if (ex instanceof ExceptionWithContext) {
|
||||
ewc = (ExceptionWithContext) ex;
|
||||
} else {
|
||||
ewc = new ExceptionWithContext(ex);
|
||||
}
|
||||
|
||||
ewc.addContext(str);
|
||||
return ewc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param message human-oriented message
|
||||
*/
|
||||
public ExceptionWithContext(String message) {
|
||||
this(message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param cause {@code null-ok;} exception that caused this one
|
||||
*/
|
||||
public ExceptionWithContext(Throwable cause) {
|
||||
this(null, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param message human-oriented message
|
||||
* @param cause {@code null-ok;} exception that caused this one
|
||||
*/
|
||||
public ExceptionWithContext(String message, Throwable cause) {
|
||||
super((message != null) ? message :
|
||||
(cause != null) ? cause.getMessage() : null,
|
||||
cause);
|
||||
|
||||
if (cause instanceof ExceptionWithContext) {
|
||||
String ctx = ((ExceptionWithContext) cause).context.toString();
|
||||
context = new StringBuffer(ctx.length() + 200);
|
||||
context.append(ctx);
|
||||
} else {
|
||||
context = new StringBuffer(200);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void printStackTrace(PrintStream out) {
|
||||
super.printStackTrace(out);
|
||||
out.println(context);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter out) {
|
||||
super.printStackTrace(out);
|
||||
out.println(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line of context to this instance.
|
||||
*
|
||||
* @param str {@code non-null;} new context
|
||||
*/
|
||||
public void addContext(String str) {
|
||||
if (str == null) {
|
||||
throw new NullPointerException("str == null");
|
||||
}
|
||||
|
||||
context.append(str);
|
||||
if (!str.endsWith("\n")) {
|
||||
context.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context.
|
||||
*
|
||||
* @return {@code non-null;} the context
|
||||
*/
|
||||
public String getContext() {
|
||||
return context.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message and context.
|
||||
*
|
||||
* @param out {@code non-null;} where to print to
|
||||
*/
|
||||
public void printContext(PrintStream out) {
|
||||
out.println(getMessage());
|
||||
out.print(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message and context.
|
||||
*
|
||||
* @param out {@code non-null;} where to print to
|
||||
*/
|
||||
public void printContext(PrintWriter out) {
|
||||
out.println(getMessage());
|
||||
out.print(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* File I/O utilities.
|
||||
*/
|
||||
public final class FileUtils {
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the named file, translating {@link IOException} to a
|
||||
* {@link RuntimeException} of some sort.
|
||||
*
|
||||
* @param fileName {@code non-null;} name of the file to read
|
||||
* @return {@code non-null;} contents of the file
|
||||
*/
|
||||
public static byte[] readFile(String fileName) {
|
||||
File file = new File(fileName);
|
||||
return readFile(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the given file, translating {@link IOException} to a
|
||||
* {@link RuntimeException} of some sort.
|
||||
*
|
||||
* @param file {@code non-null;} the file to read
|
||||
* @return {@code non-null;} contents of the file
|
||||
*/
|
||||
public static byte[] readFile(File file) {
|
||||
if (!file.exists()) {
|
||||
throw new RuntimeException(file + ": file not found");
|
||||
}
|
||||
|
||||
if (!file.isFile()) {
|
||||
throw new RuntimeException(file + ": not a file");
|
||||
}
|
||||
|
||||
if (!file.canRead()) {
|
||||
throw new RuntimeException(file + ": file not readable");
|
||||
}
|
||||
|
||||
long longLength = file.length();
|
||||
int length = (int) longLength;
|
||||
if (length != longLength) {
|
||||
throw new RuntimeException(file + ": file too long");
|
||||
}
|
||||
|
||||
byte[] result = new byte[length];
|
||||
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
int at = 0;
|
||||
while (length > 0) {
|
||||
int amt = in.read(result, at, length);
|
||||
if (amt == -1) {
|
||||
throw new RuntimeException(file + ": unexpected EOF");
|
||||
}
|
||||
at += amt;
|
||||
length -= amt;
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(file + ": trouble reading", ex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if {@code fileName} names a .zip, .jar, or .apk.
|
||||
*/
|
||||
public static boolean hasArchiveSuffix(String fileName) {
|
||||
return fileName.endsWith(".zip")
|
||||
|| fileName.endsWith(".jar")
|
||||
|| fileName.endsWith(".apk");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dex.util;
|
||||
|
||||
/**
|
||||
* Unsigned arithmetic over Java's signed types.
|
||||
*/
|
||||
public final class Unsigned {
|
||||
private Unsigned() {}
|
||||
|
||||
public static int compare(short ushortA, short ushortB) {
|
||||
if (ushortA == ushortB) {
|
||||
return 0;
|
||||
}
|
||||
int a = ushortA & 0xFFFF;
|
||||
int b = ushortB & 0xFFFF;
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
public static int compare(int uintA, int uintB) {
|
||||
if (uintA == uintB) {
|
||||
return 0;
|
||||
}
|
||||
long a = uintA & 0xFFFFFFFFL;
|
||||
long b = uintB & 0xFFFFFFFFL;
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx;
|
||||
|
||||
/**
|
||||
* Version number for dx.
|
||||
*/
|
||||
public class Version {
|
||||
/** {@code non-null;} version string */
|
||||
public static final String VERSION = "1.16";
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.Constant;
|
||||
|
||||
/**
|
||||
* Attribute class for {@code AnnotationDefault} attributes.
|
||||
*/
|
||||
public final class AttAnnotationDefault extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "AnnotationDefault";
|
||||
|
||||
/** {@code non-null;} the annotation default value */
|
||||
private final Constant value;
|
||||
|
||||
/** {@code >= 0;} attribute data length in the original classfile (not
|
||||
* including the attribute header) */
|
||||
private final int byteLength;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param value {@code non-null;} the annotation default value
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public AttAnnotationDefault(Constant value, int byteLength) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value == null");
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
this.byteLength = byteLength;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
// Add six for the standard attribute header.
|
||||
return byteLength + 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotation default value.
|
||||
*
|
||||
* @return {@code non-null;} the value
|
||||
*/
|
||||
public Constant getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.BootstrapMethodsList;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code AttBootstrapMethods} attributes.
|
||||
*/
|
||||
public class AttBootstrapMethods extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "BootstrapMethods";
|
||||
|
||||
private static final int ATTRIBUTE_HEADER_BYTES = 8;
|
||||
private static final int BOOTSTRAP_METHOD_BYTES = 4;
|
||||
private static final int BOOTSTRAP_ARGUMENT_BYTES = 2;
|
||||
|
||||
private final BootstrapMethodsList bootstrapMethods;
|
||||
|
||||
private final int byteLength;
|
||||
|
||||
public AttBootstrapMethods(BootstrapMethodsList bootstrapMethods) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
this.bootstrapMethods = bootstrapMethods;
|
||||
|
||||
int bytes = ATTRIBUTE_HEADER_BYTES + bootstrapMethods.size() * BOOTSTRAP_METHOD_BYTES;
|
||||
for (int i = 0; i < bootstrapMethods.size(); ++i) {
|
||||
int numberOfArguments = bootstrapMethods.get(i).getBootstrapMethodArguments().size();
|
||||
bytes += numberOfArguments * BOOTSTRAP_ARGUMENT_BYTES;
|
||||
}
|
||||
this.byteLength = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return byteLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bootstrap methods present in attribute.
|
||||
* @return bootstrap methods list
|
||||
*/
|
||||
public BootstrapMethodsList getBootstrapMethods() {
|
||||
return bootstrapMethods;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.ByteCatchList;
|
||||
import com.pojavdx.dx.cf.code.BytecodeArray;
|
||||
import com.pojavdx.dx.cf.iface.AttributeList;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code Code} attributes.
|
||||
*/
|
||||
public final class AttCode extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "Code";
|
||||
|
||||
/** {@code >= 0;} the stack size */
|
||||
private final int maxStack;
|
||||
|
||||
/** {@code >= 0;} the number of locals */
|
||||
private final int maxLocals;
|
||||
|
||||
/** {@code non-null;} array containing the bytecode per se */
|
||||
private final BytecodeArray code;
|
||||
|
||||
/** {@code non-null;} the exception table */
|
||||
private final ByteCatchList catches;
|
||||
|
||||
/** {@code non-null;} the associated list of attributes */
|
||||
private final AttributeList attributes;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param maxStack {@code >= 0;} the stack size
|
||||
* @param maxLocals {@code >= 0;} the number of locals
|
||||
* @param code {@code non-null;} array containing the bytecode per se
|
||||
* @param catches {@code non-null;} the exception table
|
||||
* @param attributes {@code non-null;} the associated list of attributes
|
||||
*/
|
||||
public AttCode(int maxStack, int maxLocals, BytecodeArray code,
|
||||
ByteCatchList catches, AttributeList attributes) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (maxStack < 0) {
|
||||
throw new IllegalArgumentException("maxStack < 0");
|
||||
}
|
||||
|
||||
if (maxLocals < 0) {
|
||||
throw new IllegalArgumentException("maxLocals < 0");
|
||||
}
|
||||
|
||||
if (code == null) {
|
||||
throw new NullPointerException("code == null");
|
||||
}
|
||||
|
||||
try {
|
||||
if (catches.isMutable()) {
|
||||
throw new MutabilityException("catches.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("catches == null");
|
||||
}
|
||||
|
||||
try {
|
||||
if (attributes.isMutable()) {
|
||||
throw new MutabilityException("attributes.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("attributes == null");
|
||||
}
|
||||
|
||||
this.maxStack = maxStack;
|
||||
this.maxLocals = maxLocals;
|
||||
this.code = code;
|
||||
this.catches = catches;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 10 + code.byteLength() + catches.byteLength() +
|
||||
attributes.byteLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum stack size.
|
||||
*
|
||||
* @return {@code >= 0;} the maximum stack size
|
||||
*/
|
||||
public int getMaxStack() {
|
||||
return maxStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of locals.
|
||||
*
|
||||
* @return {@code >= 0;} the number of locals
|
||||
*/
|
||||
public int getMaxLocals() {
|
||||
return maxLocals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bytecode array.
|
||||
*
|
||||
* @return {@code non-null;} the bytecode array
|
||||
*/
|
||||
public BytecodeArray getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception table.
|
||||
*
|
||||
* @return {@code non-null;} the exception table
|
||||
*/
|
||||
public ByteCatchList getCatches() {
|
||||
return catches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated attribute list.
|
||||
*
|
||||
* @return {@code non-null;} the attribute list
|
||||
*/
|
||||
public AttributeList getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.CstDouble;
|
||||
import com.pojavdx.dx.rop.cst.CstFloat;
|
||||
import com.pojavdx.dx.rop.cst.CstInteger;
|
||||
import com.pojavdx.dx.rop.cst.CstLong;
|
||||
import com.pojavdx.dx.rop.cst.CstString;
|
||||
import com.pojavdx.dx.rop.cst.TypedConstant;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code ConstantValue} attributes.
|
||||
*/
|
||||
public final class AttConstantValue extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "ConstantValue";
|
||||
|
||||
/** {@code non-null;} the constant value */
|
||||
private final TypedConstant constantValue;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param constantValue {@code non-null;} the constant value, which must
|
||||
* be an instance of one of: {@code CstString},
|
||||
* {@code CstInteger}, {@code CstLong},
|
||||
* {@code CstFloat}, or {@code CstDouble}
|
||||
*/
|
||||
public AttConstantValue(TypedConstant constantValue) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (!((constantValue instanceof CstString) ||
|
||||
(constantValue instanceof CstInteger) ||
|
||||
(constantValue instanceof CstLong) ||
|
||||
(constantValue instanceof CstFloat) ||
|
||||
(constantValue instanceof CstDouble))) {
|
||||
if (constantValue == null) {
|
||||
throw new NullPointerException("constantValue == null");
|
||||
}
|
||||
throw new IllegalArgumentException("bad type for constantValue");
|
||||
}
|
||||
|
||||
this.constantValue = constantValue;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constant value of this instance. The returned value
|
||||
* is an instance of one of: {@code CstString},
|
||||
* {@code CstInteger}, {@code CstLong},
|
||||
* {@code CstFloat}, or {@code CstDouble}.
|
||||
*
|
||||
* @return {@code non-null;} the constant value
|
||||
*/
|
||||
public TypedConstant getConstantValue() {
|
||||
return constantValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code Deprecated} attributes.
|
||||
*/
|
||||
public final class AttDeprecated extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "Deprecated";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*/
|
||||
public AttDeprecated() {
|
||||
super(ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.CstNat;
|
||||
import com.pojavdx.dx.rop.cst.CstType;
|
||||
|
||||
/**
|
||||
* Attribute class for standards-track {@code EnclosingMethod}
|
||||
* attributes.
|
||||
*/
|
||||
public final class AttEnclosingMethod extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "EnclosingMethod";
|
||||
|
||||
/** {@code non-null;} the innermost enclosing class */
|
||||
private final CstType type;
|
||||
|
||||
/** {@code null-ok;} the name-and-type of the innermost enclosing method, if any */
|
||||
private final CstNat method;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param type {@code non-null;} the innermost enclosing class
|
||||
* @param method {@code null-ok;} the name-and-type of the innermost enclosing
|
||||
* method, if any
|
||||
*/
|
||||
public AttEnclosingMethod(CstType type, CstNat method) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (type == null) {
|
||||
throw new NullPointerException("type == null");
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the innermost enclosing class.
|
||||
*
|
||||
* @return {@code non-null;} the innermost enclosing class
|
||||
*/
|
||||
public CstType getEnclosingClass() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name-and-type of the innermost enclosing method, if
|
||||
* any.
|
||||
*
|
||||
* @return {@code null-ok;} the name-and-type of the innermost enclosing
|
||||
* method, if any
|
||||
*/
|
||||
public CstNat getMethod() {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.type.TypeList;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code Exceptions} attributes.
|
||||
*/
|
||||
public final class AttExceptions extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "Exceptions";
|
||||
|
||||
/** {@code non-null;} list of exception classes */
|
||||
private final TypeList exceptions;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param exceptions {@code non-null;} list of classes, presumed but not
|
||||
* verified to be subclasses of {@code Throwable}
|
||||
*/
|
||||
public AttExceptions(TypeList exceptions) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
try {
|
||||
if (exceptions.isMutable()) {
|
||||
throw new MutabilityException("exceptions.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("exceptions == null");
|
||||
}
|
||||
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8 + exceptions.size() * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of classes associated with this instance. In
|
||||
* general, these classes are not pre-verified to be subclasses of
|
||||
* {@code Throwable}.
|
||||
*
|
||||
* @return {@code non-null;} the list of classes
|
||||
*/
|
||||
public TypeList getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code InnerClasses} attributes.
|
||||
*/
|
||||
public final class AttInnerClasses extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "InnerClasses";
|
||||
|
||||
/** {@code non-null;} list of inner class entries */
|
||||
private final InnerClassList innerClasses;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param innerClasses {@code non-null;} list of inner class entries
|
||||
*/
|
||||
public AttInnerClasses(InnerClassList innerClasses) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
try {
|
||||
if (innerClasses.isMutable()) {
|
||||
throw new MutabilityException("innerClasses.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("innerClasses == null");
|
||||
}
|
||||
|
||||
this.innerClasses = innerClasses;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8 + innerClasses.size() * 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "inner class" entries associated with this instance.
|
||||
*
|
||||
* @return {@code non-null;} the list
|
||||
*/
|
||||
public InnerClassList getInnerClasses() {
|
||||
return innerClasses;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.LineNumberList;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code LineNumberTable} attributes.
|
||||
*/
|
||||
public final class AttLineNumberTable extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "LineNumberTable";
|
||||
|
||||
/** {@code non-null;} list of line number entries */
|
||||
private final LineNumberList lineNumbers;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param lineNumbers {@code non-null;} list of line number entries
|
||||
*/
|
||||
public AttLineNumberTable(LineNumberList lineNumbers) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
try {
|
||||
if (lineNumbers.isMutable()) {
|
||||
throw new MutabilityException("lineNumbers.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("lineNumbers == null");
|
||||
}
|
||||
|
||||
this.lineNumbers = lineNumbers;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8 + 4 * lineNumbers.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "line number" entries associated with this instance.
|
||||
*
|
||||
* @return {@code non-null;} the list
|
||||
*/
|
||||
public LineNumberList getLineNumbers() {
|
||||
return lineNumbers;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.LocalVariableList;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code LocalVariableTable} attributes.
|
||||
*/
|
||||
public final class AttLocalVariableTable extends BaseLocalVariables {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "LocalVariableTable";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param localVariables {@code non-null;} list of local variable entries
|
||||
*/
|
||||
public AttLocalVariableTable(LocalVariableList localVariables) {
|
||||
super(ATTRIBUTE_NAME, localVariables);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.LocalVariableList;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code LocalVariableTypeTable} attributes.
|
||||
*/
|
||||
public final class AttLocalVariableTypeTable extends BaseLocalVariables {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "LocalVariableTypeTable";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param localVariables {@code non-null;} list of local variable entries
|
||||
*/
|
||||
public AttLocalVariableTypeTable(LocalVariableList localVariables) {
|
||||
super(ATTRIBUTE_NAME, localVariables);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.Annotations;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code RuntimeInvisibleAnnotations}
|
||||
* attributes.
|
||||
*/
|
||||
public final class AttRuntimeInvisibleAnnotations extends BaseAnnotations {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "RuntimeInvisibleAnnotations";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param annotations {@code non-null;} the list of annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public AttRuntimeInvisibleAnnotations(Annotations annotations,
|
||||
int byteLength) {
|
||||
super(ATTRIBUTE_NAME, annotations, byteLength);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.AnnotationsList;
|
||||
|
||||
/**
|
||||
* Attribute class for standard
|
||||
* {@code RuntimeInvisibleParameterAnnotations} attributes.
|
||||
*/
|
||||
public final class AttRuntimeInvisibleParameterAnnotations
|
||||
extends BaseParameterAnnotations {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME =
|
||||
"RuntimeInvisibleParameterAnnotations";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param parameterAnnotations {@code non-null;} the parameter annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public AttRuntimeInvisibleParameterAnnotations(
|
||||
AnnotationsList parameterAnnotations, int byteLength) {
|
||||
super(ATTRIBUTE_NAME, parameterAnnotations, byteLength);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.Annotations;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code RuntimeVisibleAnnotations}
|
||||
* attributes.
|
||||
*/
|
||||
public final class AttRuntimeVisibleAnnotations extends BaseAnnotations {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "RuntimeVisibleAnnotations";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param annotations {@code non-null;} the list of annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public AttRuntimeVisibleAnnotations(Annotations annotations,
|
||||
int byteLength) {
|
||||
super(ATTRIBUTE_NAME, annotations, byteLength);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.AnnotationsList;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code RuntimeVisibleParameterAnnotations}
|
||||
* attributes.
|
||||
*/
|
||||
public final class AttRuntimeVisibleParameterAnnotations
|
||||
extends BaseParameterAnnotations {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME =
|
||||
"RuntimeVisibleParameterAnnotations";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param annotations {@code non-null;} the parameter annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public AttRuntimeVisibleParameterAnnotations(
|
||||
AnnotationsList annotations, int byteLength) {
|
||||
super(ATTRIBUTE_NAME, annotations, byteLength);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.CstString;
|
||||
|
||||
/**
|
||||
* Attribute class for standards-track {@code Signature} attributes.
|
||||
*/
|
||||
public final class AttSignature extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "Signature";
|
||||
|
||||
/** {@code non-null;} the signature string */
|
||||
private final CstString signature;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param signature {@code non-null;} the signature string
|
||||
*/
|
||||
public AttSignature(CstString signature) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (signature == null) {
|
||||
throw new NullPointerException("signature == null");
|
||||
}
|
||||
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signature string.
|
||||
*
|
||||
* @return {@code non-null;} the signature string
|
||||
*/
|
||||
public CstString getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.CstString;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code SourceDebugExtension} attributes.
|
||||
*/
|
||||
public final class AttSourceDebugExtension extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "SourceDebugExtension";
|
||||
|
||||
/** {@code non-null;} Contents of SMAP */
|
||||
private final CstString smapString;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param smapString {@code non-null;} the SMAP data from the class file.
|
||||
*/
|
||||
public AttSourceDebugExtension(CstString smapString) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (smapString == null) {
|
||||
throw new NullPointerException("smapString == null");
|
||||
}
|
||||
|
||||
this.smapString = smapString;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
// Add 6 for the standard attribute header: the attribute name
|
||||
// index (2 bytes) and the attribute length (4 bytes).
|
||||
return 6 + smapString.getUtf8Size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SMAP data of this instance.
|
||||
*
|
||||
* @return {@code non-null;} the SMAP data.
|
||||
*/
|
||||
public CstString getSmapString() {
|
||||
return smapString;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.cst.CstString;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code SourceFile} attributes.
|
||||
*/
|
||||
public final class AttSourceFile extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "SourceFile";
|
||||
|
||||
/** {@code non-null;} name of the source file */
|
||||
private final CstString sourceFile;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param sourceFile {@code non-null;} the name of the source file
|
||||
*/
|
||||
public AttSourceFile(CstString sourceFile) {
|
||||
super(ATTRIBUTE_NAME);
|
||||
|
||||
if (sourceFile == null) {
|
||||
throw new NullPointerException("sourceFile == null");
|
||||
}
|
||||
|
||||
this.sourceFile = sourceFile;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source file name of this instance.
|
||||
*
|
||||
* @return {@code non-null;} the source file
|
||||
*/
|
||||
public CstString getSourceFile() {
|
||||
return sourceFile;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
/**
|
||||
* Attribute class for standard {@code Synthetic} attributes.
|
||||
*/
|
||||
public final class AttSynthetic extends BaseAttribute {
|
||||
/** {@code non-null;} attribute name for attributes of this type */
|
||||
public static final String ATTRIBUTE_NAME = "Synthetic";
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*/
|
||||
public AttSynthetic() {
|
||||
super(ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int byteLength() {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.Annotations;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Base class for annotations attributes.
|
||||
*/
|
||||
public abstract class BaseAnnotations extends BaseAttribute {
|
||||
/** {@code non-null;} list of annotations */
|
||||
private final Annotations annotations;
|
||||
|
||||
/** {@code >= 0;} attribute data length in the original classfile (not
|
||||
* including the attribute header) */
|
||||
private final int byteLength;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param attributeName {@code non-null;} the name of the attribute
|
||||
* @param annotations {@code non-null;} the list of annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public BaseAnnotations(String attributeName, Annotations annotations,
|
||||
int byteLength) {
|
||||
super(attributeName);
|
||||
|
||||
try {
|
||||
if (annotations.isMutable()) {
|
||||
throw new MutabilityException("annotations.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("annotations == null");
|
||||
}
|
||||
|
||||
this.annotations = annotations;
|
||||
this.byteLength = byteLength;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final int byteLength() {
|
||||
// Add six for the standard attribute header.
|
||||
return byteLength + 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of annotations associated with this instance.
|
||||
*
|
||||
* @return {@code non-null;} the list
|
||||
*/
|
||||
public final Annotations getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.iface.Attribute;
|
||||
|
||||
/**
|
||||
* Base implementation of {@link Attribute}, which directly stores
|
||||
* the attribute name but leaves the rest up to subclasses.
|
||||
*/
|
||||
public abstract class BaseAttribute implements Attribute {
|
||||
/** {@code non-null;} attribute name */
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param name {@code non-null;} attribute name
|
||||
*/
|
||||
public BaseAttribute(String name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("name == null");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.cf.code.LocalVariableList;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Base attribute class for standard {@code LocalVariableTable}
|
||||
* and {@code LocalVariableTypeTable} attributes.
|
||||
*/
|
||||
public abstract class BaseLocalVariables extends BaseAttribute {
|
||||
/** {@code non-null;} list of local variable entries */
|
||||
private final LocalVariableList localVariables;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param name {@code non-null;} attribute name
|
||||
* @param localVariables {@code non-null;} list of local variable entries
|
||||
*/
|
||||
public BaseLocalVariables(String name,
|
||||
LocalVariableList localVariables) {
|
||||
super(name);
|
||||
|
||||
try {
|
||||
if (localVariables.isMutable()) {
|
||||
throw new MutabilityException("localVariables.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("localVariables == null");
|
||||
}
|
||||
|
||||
this.localVariables = localVariables;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final int byteLength() {
|
||||
return 8 + localVariables.size() * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "local variable" entries associated with this instance.
|
||||
*
|
||||
* @return {@code non-null;} the list
|
||||
*/
|
||||
public final LocalVariableList getLocalVariables() {
|
||||
return localVariables;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pojavdx.dx.cf.attrib;
|
||||
|
||||
import com.pojavdx.dx.rop.annotation.AnnotationsList;
|
||||
import com.pojavdx.dx.util.MutabilityException;
|
||||
|
||||
/**
|
||||
* Base class for parameter annotation list attributes.
|
||||
*/
|
||||
public abstract class BaseParameterAnnotations extends BaseAttribute {
|
||||
/** {@code non-null;} list of annotations */
|
||||
private final AnnotationsList parameterAnnotations;
|
||||
|
||||
/** {@code >= 0;} attribute data length in the original classfile (not
|
||||
* including the attribute header) */
|
||||
private final int byteLength;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param attributeName {@code non-null;} the name of the attribute
|
||||
* @param parameterAnnotations {@code non-null;} the annotations
|
||||
* @param byteLength {@code >= 0;} attribute data length in the original
|
||||
* classfile (not including the attribute header)
|
||||
*/
|
||||
public BaseParameterAnnotations(String attributeName,
|
||||
AnnotationsList parameterAnnotations, int byteLength) {
|
||||
super(attributeName);
|
||||
|
||||
try {
|
||||
if (parameterAnnotations.isMutable()) {
|
||||
throw new MutabilityException(
|
||||
"parameterAnnotations.isMutable()");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
// Translate the exception.
|
||||
throw new NullPointerException("parameterAnnotations == null");
|
||||
}
|
||||
|
||||
this.parameterAnnotations = parameterAnnotations;
|
||||
this.byteLength = byteLength;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final int byteLength() {
|
||||
// Add six for the standard attribute header.
|
||||
return byteLength + 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of annotation lists associated with this instance.
|
||||
*
|
||||
* @return {@code non-null;} the list
|
||||
*/
|
||||
public final AnnotationsList getParameterAnnotations() {
|
||||
return parameterAnnotations;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue