Skip to content

Commit 970d509

Browse files
authored
Merge branch 'REAndroid:main' into refactor/low-level-operatoins
2 parents dcd4273 + 317c714 commit 970d509

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2681
-1737
lines changed

src/main/java/com/reandroid/arsc/coder/xml/XmlCoder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ public void encodeBag(XMLElement element, Entry entry) throws IOException{
311311
while (childes.hasNext()){
312312
BAG_CHILD.encode(childes.next(), entry);
313313
}
314+
ResTableMapEntry resTableMapEntry = entry.getResTableMapEntry();
315+
if (resTableMapEntry != null) {
316+
resTableMapEntry.sortIfStyle();
317+
}
314318
checkVisibility(entry);
315319
}
316320
private boolean isBag(XMLElement element){

src/main/java/com/reandroid/arsc/value/AttributeDataFormat.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,25 @@ public static int sum(AttributeDataFormat[] typeValues){
158158
return result;
159159
}
160160

161-
public static AttributeDataFormat[] decodeValueTypes(int data){
162-
AttributeDataFormat[] tmp = new AttributeDataFormat[VALUE_TYPES.length];
163-
int length = 0;
164-
for(AttributeDataFormat typeValue : VALUE_TYPES){
165-
int mask = typeValue.getMask();
166-
if(mask == data){
167-
return new AttributeDataFormat[]{typeValue};
168-
}
169-
if(typeValue == ANY){
170-
continue;
171-
}
172-
if((data & mask) == mask){
173-
tmp[length] = typeValue;
174-
length++;
175-
}
161+
public static AttributeDataFormat[] decodeValueTypes(int data) {
162+
if ((data & 0xffff) == 0xffff) {
163+
return new AttributeDataFormat[]{ANY};
176164
}
177-
if(length == 0){
165+
data &= 0xff;
166+
if (data == 0) {
178167
return null;
179168
}
180-
AttributeDataFormat[] results = new AttributeDataFormat[length];
181-
System.arraycopy(tmp, 0, results, 0, length);
169+
AttributeDataFormat[] results = new AttributeDataFormat[Integer.bitCount(data)];
170+
AttributeDataFormat[] valueTypes = VALUE_TYPES;
171+
int length = valueTypes.length - 1;
172+
int j = 0;
173+
for (int i = 0; i < length; i++) {
174+
if ((data & 1) != 0) {
175+
results[j] = valueTypes[i];
176+
j ++;
177+
}
178+
data = data >> 1;
179+
}
182180
return results;
183181
}
184182
public static AttributeDataFormat[] parseValueTypes(String valuesTypes){

src/main/java/com/reandroid/arsc/value/ResTableMapEntry.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public boolean isStyle(){
9292
}
9393
return false;
9494
}
95+
public void sortIfStyle() {
96+
if (isStyle()) {
97+
getValue().sort();
98+
}
99+
}
95100
public ValueType isAllSameValueType(){
96101
ValueType allValueType = null;
97102
Iterator<ResValueMap> iterator = getValue().iterator();

src/main/java/com/reandroid/dex/base/BlockListArray.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
public class BlockListArray<T extends Block> extends BlockArray<T>
2929
implements OffsetSupplier, DexArraySupplier<T>, Creator<T> {
3030

31-
private final IntegerPair countAndOffset;
31+
private IntegerPair countAndOffset;
3232

3333
public BlockListArray(IntegerPair countAndOffset,
3434
Creator<T> creator) {
@@ -50,6 +50,9 @@ public IntegerReference getOffsetReference(){
5050
public IntegerPair getCountAndOffset() {
5151
return countAndOffset;
5252
}
53+
public void addCountAndOffset(IntegerPair countAndOffset) {
54+
this.countAndOffset = ParallelIntegerPair.combine(this.countAndOffset, countAndOffset);
55+
}
5356
@Override
5457
public void onReadBytes(BlockReader reader) throws IOException {
5558
IntegerPair countAndOffset = getCountAndOffset();

src/main/java/com/reandroid/dex/base/ParallelIntegerPair.java

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,30 @@
1616
package com.reandroid.dex.base;
1717

1818
import com.reandroid.arsc.base.BlockRefresh;
19-
import com.reandroid.arsc.item.IntegerReference;
19+
import com.reandroid.utils.ObjectsUtil;
20+
2021

2122
public class ParallelIntegerPair implements IntegerPair, BlockRefresh {
2223

2324
private final ParallelReference first;
2425
private final ParallelReference second;
2526

26-
public ParallelIntegerPair(IntegerPair integerPair){
27-
this.first = new ParallelReference(integerPair.getFirst(), null);
28-
this.second = new ParallelReference(integerPair.getSecond(), null);
27+
public ParallelIntegerPair(IntegerPair integerPair) {
28+
this.first = new ParallelReference(integerPair.getFirst());
29+
this.second = new ParallelReference(integerPair.getSecond());
2930
}
3031

31-
public void setReference2(IntegerPair integerPair){
32-
IntegerReference first;
33-
IntegerReference second;
34-
if(integerPair == null){
35-
first = null;
36-
second = null;
37-
}else {
38-
first = integerPair.getFirst();
39-
second = integerPair.getSecond();
40-
}
41-
getFirst().setReference2(first);
42-
getSecond().setReference2(second);
32+
public void add(IntegerPair pair) {
33+
getFirst().add(pair.getFirst());
34+
getSecond().add(pair.getSecond());
35+
}
36+
public void remove(IntegerPair pair) {
37+
getFirst().remove(pair.getFirst());
38+
getSecond().remove(pair.getSecond());
39+
}
40+
public boolean contains(IntegerPair pair) {
41+
return getFirst().contains(pair.getFirst()) &&
42+
getSecond().contains(pair.getSecond());
4343
}
4444
@Override
4545
public ParallelReference getFirst() {
@@ -50,8 +50,48 @@ public ParallelReference getSecond() {
5050
return second;
5151
}
5252
@Override
53-
public void refresh(){
53+
public void refresh() {
5454
getFirst().refresh();
5555
getSecond().refresh();
5656
}
57+
58+
@Override
59+
public boolean equals(Object obj) {
60+
if (this == obj) {
61+
return true;
62+
}
63+
if (obj == null || getClass() != obj.getClass()) {
64+
return false;
65+
}
66+
ParallelIntegerPair pair = (ParallelIntegerPair) obj;
67+
return ObjectsUtil.equals(first, pair.first) &&
68+
ObjectsUtil.equals(second, pair.second);
69+
}
70+
71+
@Override
72+
public int hashCode() {
73+
return ObjectsUtil.hash(first, second);
74+
}
75+
76+
@Override
77+
public String toString() {
78+
return "(" + first + ", " + second + ")";
79+
}
80+
81+
public static IntegerPair combine(IntegerPair pair1, IntegerPair pair2) {
82+
if (pair1 == null) {
83+
return pair2;
84+
}
85+
if (pair2 == null) {
86+
return pair1;
87+
}
88+
if (pair1 instanceof ParallelIntegerPair) {
89+
ParallelIntegerPair p = (ParallelIntegerPair) pair1;
90+
p.add(pair2);
91+
return p;
92+
}
93+
ParallelIntegerPair p = new ParallelIntegerPair(pair1);
94+
p.add(pair2);
95+
return p;
96+
}
5797
}

src/main/java/com/reandroid/dex/base/ParallelReference.java

Lines changed: 154 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,125 @@
1717

1818
import com.reandroid.arsc.base.BlockRefresh;
1919
import com.reandroid.arsc.item.IntegerReference;
20+
import com.reandroid.utils.ObjectsUtil;
21+
import com.reandroid.utils.collection.CollectionUtil;
22+
import com.reandroid.utils.collection.CombiningIterator;
23+
import com.reandroid.utils.collection.EmptyIterator;
24+
import com.reandroid.utils.collection.SingleIterator;
25+
26+
import java.util.Iterator;
2027

2128
public class ParallelReference implements IntegerReference, BlockRefresh {
2229

2330
private final IntegerReference reference1;
2431
private IntegerReference reference2;
2532

26-
public ParallelReference(IntegerReference reference1, IntegerReference reference2){
33+
public ParallelReference(IntegerReference reference1, IntegerReference reference2) {
2734
this.reference1 = reference1;
2835
this.reference2 = reference2;
2936
}
30-
public ParallelReference(IntegerReference reference1){
37+
public ParallelReference(IntegerReference reference1) {
3138
this(reference1, null);
3239
}
3340

3441
public IntegerReference getReference2() {
3542
return reference2;
3643
}
44+
45+
public boolean contains(IntegerReference reference) {
46+
if (reference == this) {
47+
return true;
48+
}
49+
if (!(reference instanceof ParallelReference)) {
50+
return CollectionUtil.contains(getRootReferences(), reference);
51+
}
52+
Iterator<IntegerReference> iterator = ((ParallelReference) reference).getRootReferences();
53+
while (iterator.hasNext()) {
54+
if (!contains(iterator.next())) {
55+
return false;
56+
}
57+
}
58+
return true;
59+
}
60+
public Iterator<IntegerReference> getRootReferences() {
61+
return CombiningIterator.two(
62+
getRootReferences(reference1),
63+
getRootReferences(reference2));
64+
}
65+
public void remove(IntegerReference ref) {
66+
Iterator<IntegerReference> iterator = getRootReferences(ref);
67+
while (iterator.hasNext()) {
68+
removeRoot(iterator.next());
69+
}
70+
}
71+
private void removeRoot(IntegerReference ref) {
72+
if (ref == reference2) {
73+
this.reference2 = null;
74+
} else if (reference2 instanceof ParallelReference) {
75+
ParallelReference p = (ParallelReference) reference2;
76+
if (p.reference1 == ref) {
77+
if (p.reference2 == null) {
78+
this.reference2 = null;
79+
} else {
80+
p = new ParallelReference(p.reference2);
81+
this.reference2 = p;
82+
}
83+
}
84+
p.removeRoot(ref);
85+
}
86+
}
87+
public void add(IntegerReference ref) {
88+
Iterator<IntegerReference> iterator = getRootReferences(ref);
89+
while (iterator.hasNext()) {
90+
addRoot(iterator.next());
91+
}
92+
}
93+
private void addRoot(IntegerReference ref) {
94+
if (ref == null || contains(ref)) {
95+
return;
96+
}
97+
if (putOnNull(ref)) {
98+
return;
99+
}
100+
this.reference2 = new ParallelReference(this.reference2, ref);
101+
}
102+
private boolean putOnNull(IntegerReference ref) {
103+
IntegerReference current = this.reference1;
104+
if (current instanceof ParallelReference) {
105+
ParallelReference p = (ParallelReference) current;
106+
if (p.putOnNull(ref)) {
107+
return true;
108+
}
109+
}
110+
current = this.reference2;
111+
if (current == null) {
112+
this.reference2 = ref;
113+
return true;
114+
}
115+
if (current instanceof ParallelReference) {
116+
return ((ParallelReference) current).putOnNull(ref);
117+
}
118+
return false;
119+
}
37120
public void setReference2(IntegerReference reference2) {
38-
if(reference2 != this){
121+
if (reference2 == null) {
122+
return;
123+
}
124+
if (contains(reference2)) {
125+
return;
126+
}
127+
IntegerReference current = this.reference2;
128+
if (current instanceof ParallelReference) {
129+
((ParallelReference) current).setReference2(reference2);
130+
} else if (reference2 != this) {
39131
this.reference2 = reference2;
40132
}
41133
}
42134

43135
@Override
44136
public void set(int value) {
45137
this.reference1.set(value);
46-
if(reference2 != null){
138+
if (reference2 != null) {
47139
reference2.set(value);
48140
}
49141
}
@@ -57,22 +149,76 @@ public void refresh() {
57149
}
58150
public int get2() {
59151
IntegerReference ref2 = this.reference2;
60-
if(ref2 != null){
152+
if (ref2 != null) {
61153
return ref2.get();
62154
}
63155
return reference1.get();
64156
}
65157

158+
@Override
159+
public boolean equals(Object obj) {
160+
if (this == obj) {
161+
return true;
162+
}
163+
if (obj == null || getClass() != obj.getClass()) {
164+
return false;
165+
}
166+
ParallelReference ref = (ParallelReference) obj;
167+
return this.contains(ref) && ref.contains(this);
168+
}
169+
170+
@Override
171+
public int hashCode() {
172+
return ObjectsUtil.hash(reference1);
173+
}
174+
66175
@Override
67176
public String toString() {
68177
int i1 = reference1.get();
69-
if(reference2 == null){
178+
if (reference2 == null) {
70179
return Integer.toString(i1);
71180
}
72181
int i2 = reference2.get();
73-
if(i1 == i2){
182+
if (i1 == i2) {
74183
return Integer.toString(i1);
75184
}
76-
return "reference1=" + reference1 + ", reference2=" + reference2;
185+
return "r1=" + reference1 + ", r2=" + reference2;
186+
}
187+
188+
public static IntegerReference combine(IntegerReference reference1, IntegerReference reference2) {
189+
if (reference1 == null) {
190+
return reference2;
191+
}
192+
if (reference2 == null) {
193+
return reference1;
194+
}
195+
if (reference1 instanceof ParallelReference) {
196+
ParallelReference ref = (ParallelReference) reference1;
197+
if (ref.getReference2() == null) {
198+
ref.setReference2(reference2);
199+
return ref;
200+
}
201+
}
202+
if (reference2 instanceof ParallelReference) {
203+
ParallelReference ref = (ParallelReference) reference2;
204+
if (ref.getReference2() == null) {
205+
ref.setReference2(reference1);
206+
return ref;
207+
}
208+
}
209+
if (reference1.equals(reference2)) {
210+
return reference1;
211+
}
212+
return new ParallelReference(reference1, reference2);
213+
}
214+
215+
private static Iterator<IntegerReference> getRootReferences(IntegerReference ref) {
216+
if (ref == null) {
217+
return EmptyIterator.of();
218+
}
219+
if (ref instanceof ParallelReference) {
220+
return ((ParallelReference) ref).getRootReferences();
221+
}
222+
return SingleIterator.of(ref);
77223
}
78224
}

0 commit comments

Comments
 (0)