Skip to content

Commit

Permalink
Fix issue #8 and update to modern build/dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
strazzere committed Aug 2, 2024
1 parent 2a831c2 commit 63ed4de
Show file tree
Hide file tree
Showing 16 changed files with 243 additions and 214 deletions.
52 changes: 29 additions & 23 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'com.github.kt3k.coveralls'
plugins {
id 'java'
id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.8.4'
}

version = '0.1.7'

repositories {
mavenCentral()
jcenter()
// You can include other repositories if needed
}

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.4.0'
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
testImplementation 'org.mockito:mockito-core:5.9.0'
// testImplementation 'org.mockito:mockito-inline:5.2.0'
}

allprojects {
Expand All @@ -26,22 +26,28 @@ allprojects {

jacocoTestReport {
reports {
html.enabled = true
xml.enabled = true
csv.enabled = false
html.required.set(true)
xml.required.set(true)
csv.required.set(false)
}
}

dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
}

jar {
tasks.jar {
manifest {
attributes 'Main-Class': 'diff.rednaga.AXMLPrinter'
}

processResources.inputs.property('version', version)
processResources.expand('version': version)
}
processResources {
inputs.property('version', version)
expand('version': version)
}
}

test {
useJUnitPlatform()
jvmArgs(
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
'--add-opens', 'java.base/java.io=ALL-UNNAMED',
'--add-opens', 'java.base/java.util=ALL-UNNAMED'
)
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
24 changes: 16 additions & 8 deletions src/main/java/android/content/res/IntReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Simple helper class that allows reading of integers.
Expand All @@ -27,10 +29,16 @@
*/
public class IntReader {

private static final int BYTE_LENGTH = 1;
private static final int SHORT_LENGTH = 2;
private static final int INT_LENGTH = 4;

private InputStream stream;
private boolean bigEndian;
private int bytesRead;

private static final Logger LOGGER = Logger.getLogger(IntReader.class.getName());

public IntReader(InputStream stream, boolean bigEndian) {
reset(stream, bigEndian);
}
Expand All @@ -55,22 +63,22 @@ public void close() {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
LOGGER.log(Level.SEVERE, "Error closing stream", e);
}
reset(null, false);
}
}

public int readByte() throws IOException {
return readInt(1);
return readInt(BYTE_LENGTH);
}

public int readShort() throws IOException {
return readInt(2);
return readInt(SHORT_LENGTH);
}

public int readInt() throws IOException {
return readInt(4);
return readInt(INT_LENGTH);
}

/**
Expand All @@ -81,7 +89,7 @@ public int readInt() throws IOException {
* @throws IOException
*/
public int readInt(int length) throws IOException {
if ((length < 0) || (length > 4)) {
if ((length < 0) || (length > INT_LENGTH)) {
throw new IllegalArgumentException();
}
int result = 0;
Expand Down Expand Up @@ -126,7 +134,7 @@ public void skip(int bytes) throws IOException {
}

public void skipInt() throws IOException {
skip(4);
skip(INT_LENGTH);
}

public int getBytesRead() {
Expand Down
73 changes: 49 additions & 24 deletions src/main/java/android/content/res/chunk/sections/StringSection.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class StringSection extends GenericChunkSection implements Chunk, ChunkSection {

Expand Down Expand Up @@ -82,37 +83,61 @@ public void readSection(IntReader inputReader) throws IOException {
}
}

// TODO : Ensure we goto the proper offset in the case it isn't in proper order
private void readPool(ArrayList<PoolItem> pool, int flags, IntReader inputReader) throws IOException {
int offset = 0;
for (PoolItem item : pool) {
// TODO: This assumes that the pool is ordered...
inputReader.skip(item.getOffset() - offset);
offset = item.getOffset();
private void readPool(ArrayList<PoolItem> pool, int flags, IntReader inputReader) throws IOException {
// Create a list of indices to maintain the original order
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < pool.size(); i++) {
indices.add(i);
}

// Sort indices based on the offsets of the pool items
indices.sort((i1, i2) -> Integer.compare(pool.get(i1).getOffset(), pool.get(i2).getOffset()));

int currentStreamPosition = 0;

// Temporary storage for strings
String[] results = new String[pool.size()];

int length = 0;
// Read data in the order determined by sorted indices
for (int index : indices) {
PoolItem item = pool.get(index);
int targetOffset = item.getOffset();

// Move to the target offset, skip forward if needed
if (targetOffset > currentStreamPosition) {
inputReader.skip(targetOffset - currentStreamPosition);
currentStreamPosition = targetOffset;
}

int length = 0;
if ((flags & UTF8_FLAG) != 0) {
length = inputReader.readByte();
currentStreamPosition += 1;
} else {
length = inputReader.readShort();
currentStreamPosition += 2;
}

StringBuilder result = new StringBuilder(length);
for (; length != 0; length -= 1) {
if ((flags & UTF8_FLAG) != 0) {
length = inputReader.readByte();
offset += 1;
result.append((char) inputReader.readByte());
currentStreamPosition += 1;
} else {
length = inputReader.readShort();
offset += 2;
result.append((char) inputReader.readShort());
currentStreamPosition += 2;
}
}

StringBuilder result = new StringBuilder(length);
for (; length != 0; length -= 1) {
if ((flags & UTF8_FLAG) != 0) {
result.append((char) inputReader.readByte());
offset += 1;
} else {
result.append((char) inputReader.readShort());
offset += 2;
}
}
// Store the result temporarily
results[index] = result.toString();
}

item.setString(result.toString());
}
// Assign results back to the pool items in the original order
for (int i = 0; i < pool.size(); i++) {
pool.get(i).setString(results[i]);
}
}

public int getStringIndex(String string) {
if (string != null) {
Expand Down
20 changes: 10 additions & 10 deletions src/test/java/android/content/res/TestAXMLResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import android.content.res.chunk.AttributeType;
import android.content.res.chunk.types.Attribute;
import android.content.res.chunk.types.StartTag;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
Expand All @@ -16,15 +15,16 @@
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* @author tstrazzere
*/
@RunWith(Enclosed.class)
public class TestAXMLResource {
public static class FunctionalTest {

@Nested
class FunctionalTest {

// Legacy files from original repo
String[] oldTestFiles = {"test.xml", "test1.xml", "test2.xml", "test3.xml"};
Expand All @@ -34,7 +34,7 @@ public static class FunctionalTest {

AXMLResource underTest;

@Before
@BeforeEach
public void setUp() {
underTest = new AXMLResource();
}
Expand Down Expand Up @@ -128,4 +128,4 @@ public void testWriteInsertedApplicationAttribute() throws IOException {
"test");
}
}
}
}
21 changes: 10 additions & 11 deletions src/test/java/android/content/res/TestChunkUtil.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package android.content.res;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.IOException;

import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import android.content.res.chunk.ChunkType;
import android.content.res.chunk.ChunkUtil;
Expand All @@ -25,9 +24,10 @@
/**
* @author tstrazzere
*/
@RunWith(Enclosed.class)
public class TestChunkUtil {
public static class UnitTest {

@Nested
class UnitTest {

@Test
public void testReadChunkType() throws IOException {
Expand Down Expand Up @@ -66,7 +66,7 @@ public void testCreateResourceSection() throws IOException {
when(mockReader.readInt()).thenReturn(ChunkType.RESOURCE_SECTION.getIntType(), 8, 0);

if (!(ChunkUtil.createChunk(mockReader) instanceof ResourceSection)) {
throw new AssertionError("Expected AXMLHeader chunk!");
throw new AssertionError("Expected ResourceSection chunk!");
}
}

Expand All @@ -76,7 +76,7 @@ public void testCreateStringSection() throws IOException {
when(mockReader.readInt()).thenReturn(ChunkType.STRING_SECTION.getIntType(), 0);

if (!(ChunkUtil.createChunk(mockReader) instanceof StringSection)) {
throw new AssertionError("Expected AXMLHeader chunk!");
throw new AssertionError("Expected StringSection chunk!");
}
}

Expand All @@ -86,7 +86,7 @@ public void testCreateBuffer() throws IOException {
when(mockReader.readInt()).thenReturn(ChunkType.BUFFER.getIntType(), 0);

if (!(ChunkUtil.createChunk(mockReader) instanceof Buffer)) {
throw new AssertionError("Expected AXMLHeader chunk!");
throw new AssertionError("Expected Buffer chunk!");
}
}

Expand All @@ -109,7 +109,6 @@ public void testCreateNameSpace() throws IOException {
}

assertEquals(false, ((NameSpace) chunk).isStart());

}

@Test
Expand Down Expand Up @@ -145,4 +144,4 @@ public void testCreateTextTag() throws IOException {
}
}
}
}
}
Loading

0 comments on commit 63ed4de

Please sign in to comment.