
com.reandroid.arsc.pool.StringPool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ARSCLib Show documentation
Show all versions of ARSCLib Show documentation
Android binary resources read/write library
/*
* Copyright (C) 2022 github.com/REAndroid
*
* 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.reandroid.arsc.pool;
import com.reandroid.arsc.array.OffsetArray;
import com.reandroid.arsc.array.StringArray;
import com.reandroid.arsc.array.StyleArray;
import com.reandroid.arsc.base.Block;
import com.reandroid.arsc.chunk.Chunk;
import com.reandroid.arsc.group.StringGroup;
import com.reandroid.arsc.header.StringPoolHeader;
import com.reandroid.arsc.io.BlockLoad;
import com.reandroid.arsc.io.BlockReader;
import com.reandroid.arsc.item.*;
import com.reandroid.json.JSONArray;
import com.reandroid.json.JSONConvert;
import com.reandroid.utils.CompareUtil;
import com.reandroid.utils.collection.EmptyIterator;
import com.reandroid.utils.collection.FilterIterator;
import java.io.IOException;
import java.util.*;
public abstract class StringPool extends Chunk implements BlockLoad, JSONConvert {
private final Object mLock = new Object();
private final StringArray mArrayStrings;
private final StyleArray mArrayStyles;
private final Map> mUniqueMap;
private boolean stringLinkLocked;
StringPool(boolean is_utf8, boolean stringLinkLocked){
super(new StringPoolHeader(), 4);
OffsetArray offsetStrings = new OffsetArray();
OffsetArray offsetStyles = new OffsetArray();
StringPoolHeader header = getHeaderBlock();
this.mArrayStrings = newInstance(
offsetStrings,
header.getCountStrings(),
header.getStartStrings(),
is_utf8);
this.mArrayStyles = new StyleArray(
offsetStyles,
header.getCountStyles(),
header.getStartStyles());
addChild(offsetStrings);
addChild(offsetStyles);
addChild(mArrayStrings);
addChild(mArrayStyles);
setUtf8(is_utf8, false);
header.getFlagUtf8().setBlockLoad(this);
mUniqueMap = new HashMap<>();
this.stringLinkLocked = stringLinkLocked;
}
StringPool(boolean is_utf8){
this(is_utf8, true);
}
void sort(Comparator comparator){
ensureStringLinkUnlockedInternal();
getStringsArray().sort(comparator);
}
public boolean isStringLinkLocked(){
return stringLinkLocked;
}
public void ensureStringLinkUnlockedInternal(){
if(!stringLinkLocked){
return;
}
synchronized (mLock){
if(!stringLinkLocked){
return;
}
stringLinkLocked = false;
linkStrings();
}
}
void linkStrings(){
linkStyles();
}
private void linkStyles(){
StyleArray styleArray = getStyleArray();
if(styleArray == null){
return;
}
StyleItem[] styles = styleArray.getChildes();
for(StyleItem styleItem : styles){
styleItem.linkIfRequiredInternal();
}
}
public void removeString(T item){
getStringsArray().remove(item);
}
public void destroy(){
getStyleArray().clearChildes();
getStringsArray().clearChildes();
}
public List toStringList(){
return getStringsArray().toStringList();
}
public void addStrings(Collection stringList){
if(stringList==null || stringList.size()==0){
return;
}
Set uniqueSet;
if(stringList instanceof HashSet){
uniqueSet=(HashSet)stringList;
}else {
uniqueSet=new HashSet<>(stringList);
}
refreshUniqueIdMap();
Set keySet=mUniqueMap.keySet();
for(String key:keySet){
uniqueSet.remove(key);
}
List sortedList=new ArrayList<>(uniqueSet);
sortedList.sort(CompareUtil.STRING_COMPARATOR);
insertStringList(sortedList);
}
private void insertStringList(List stringList){
StringArray stringsArray = getStringsArray();
int initialSize=stringsArray.childesCount();
stringsArray.ensureSize(initialSize + stringList.size());
int size=stringsArray.childesCount();
int j=0;
for (int i=initialSize;i insertStrings(List stringList){
Map results=new HashMap<>();
StringArray stringsArray = getStringsArray();
int initialSize=stringsArray.childesCount();
stringsArray.ensureSize(initialSize + stringList.size());
int size=stringsArray.childesCount();
int j=0;
for (int i=initialSize;i> map = mUniqueMap;
map.clear();
StringArray stringArray = this.mArrayStrings;
T[] stringItems = stringArray.getChildes();
int length = stringItems.length;
if(length == 0){
return;
}
for(int i = 0; i < length; i++){
T item = stringItems[i];
if(item == null){
continue;
}
String str = item.getXml();
if(str == null){
continue;
}
StringGroup group = map.get(str);
if(group == null){
group = new StringGroup<>(stringArray, str, item);
map.put(str, group);
}else {
group.add(item);
}
}
}
void updateUniqueIdMap(T item){
if(item == null){
return;
}
String str = item.getXml();
if(str == null){
str = "";
}
StringGroup group = mUniqueMap.get(str);
if(group == null){
group = new StringGroup<>(mArrayStrings, str, item);
mUniqueMap.put(str, group);
}else {
group.add(item);
}
}
public int clearDuplicates(){
int results = 0;
Iterator> iterator = mUniqueMap.values().iterator();
while (iterator.hasNext()){
results += iterator.next().clearDuplicates();
}
return results;
}
public Iterator> listDuplicates(){
if(mUniqueMap.size() == countStrings() || countStrings() == 0){
return EmptyIterator.of();
}
return new FilterIterator<>(mUniqueMap.values().iterator(), StringGroup::isDuplicate);
}
public List removeUnusedStrings(){
return getStringsArray().removeUnusedStrings();
}
public List listUnusedStrings(){
return getStringsArray().listUnusedStrings();
}
public Collection listStrings(){
return getStringsArray().listItems();
}
public StyleArray getStyleArray(){
return mArrayStyles;
}
public StringArray getStringsArray(){
return mArrayStrings;
}
public T removeReference(ReferenceItem ref){
if(ref==null){
return null;
}
T item=get(ref.get());
if(item!=null){
item.removeReference(ref);
return item;
}
return null;
}
public boolean contains(String str){
return mUniqueMap.containsKey(str);
}
public final T get(int index){
return mArrayStrings.get(index);
}
public final T getLast(){
return mArrayStrings.getLast();
}
public final StringGroup get(String str){
return mUniqueMap.get(str);
}
public T getOrCreate(String str){
if(str == null){
str = "";
}
StringGroup group = mUniqueMap.get(str);
T item;
if(group == null){
item = createNewString(str);
group = new StringGroup<>(mArrayStrings, str, item);
mUniqueMap.put(str, group);
}else if(group.size() == 0){
item = createNewString(str);
group.add(item);
}else {
item = group.get(0);
}
return item;
}
private T createNewString(String str){
T item = mArrayStrings.createNext();
item.set(str);
//getHeaderBlock().getCountStrings().set(mArrayStrings.childesCount());
return item;
}
public final StyleItem getStyle(int index){
return mArrayStyles.get(index);
}
public final int countStrings(){
return mArrayStrings.childesCount();
}
public final int countStyles(){
return mArrayStyles.childesCount();
}
public final T[] getStrings(){
return mArrayStrings.getChildes();
}
public final StyleItem[] getStyles(){
return mArrayStyles.getChildes();
}
public boolean isUtf8(){
return getHeaderBlock().isUtf8();
}
public void setUtf8(boolean is_utf8){
setUtf8(is_utf8, true);
}
private void setUtf8(boolean is_utf8, boolean updateAll){
StringPoolHeader header = getHeaderBlock();
if(is_utf8 == header.isUtf8()){
return;
}
ByteItem flagUtf8 = header.getFlagUtf8();
if(is_utf8){
flagUtf8.set((byte) 0x01);
}else {
flagUtf8.set((byte) 0x00);
}
if(!updateAll){
return;
}
mArrayStrings.setUtf8(is_utf8);
}
public void setFlagSorted(boolean sorted){
getHeaderBlock().setSorted(sorted);
}
abstract StringArray newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8);
@Override
protected void onChunkRefreshed() {
mArrayStrings.refreshCountAndStart();
mArrayStyles.refreshCountAndStart();
}
@Override
public void onChunkLoaded() {
refreshUniqueIdMap();
StyleItem[] styles = getStyles();
if(styles!=null){
for(StyleItem styleItem:styles){
styleItem.onDataLoaded();
}
}
}
@Override
public void onBlockLoaded(BlockReader reader, Block sender) throws IOException {
StringPoolHeader header = getHeaderBlock();
if(sender == header.getFlagUtf8()){
mArrayStrings.setUtf8(header.isUtf8());
}
}
@Override
public JSONArray toJson() {
return getStringsArray().toJson();
}
//Only for styled strings
@Override
public void fromJson(JSONArray json) {
if(json==null){
return;
}
JsonStringPoolHelper helper=new JsonStringPoolHelper<>(this);
helper.loadStyledStrings(json);
refresh();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy