parse locale script & variant, allow config size 52

This commit is contained in:
REAndroid 2023-03-12 12:06:08 -04:00
parent e873913f68
commit 7fe33a0b8f
2 changed files with 294 additions and 84 deletions

View File

@ -34,6 +34,7 @@ public class ResConfig extends FixedBlockContainer
private final ByteArray mValuesContainer; private final ByteArray mValuesContainer;
private String mQualifiers; private String mQualifiers;
private int mQualifiersStamp;
public ResConfig(){ public ResConfig(){
super(2); super(2);
@ -42,7 +43,7 @@ public class ResConfig extends FixedBlockContainer
addChild(0, configSize); addChild(0, configSize);
addChild(1, mValuesContainer); addChild(1, mValuesContainer);
this.configSize.setBlockLoad(this); this.configSize.setBlockLoad(this);
this.mValuesContainer.setBlockLoad(this); this.mQualifiersStamp = 0;
} }
public void copyFrom(ResConfig resConfig){ public void copyFrom(ResConfig resConfig){
if(resConfig==this||resConfig==null){ if(resConfig==this||resConfig==null){
@ -55,8 +56,6 @@ public class ResConfig extends FixedBlockContainer
public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { public void onBlockLoaded(BlockReader reader, Block sender) throws IOException {
if(sender==configSize){ if(sender==configSize){
setConfigSize(configSize.get()); setConfigSize(configSize.get());
}else if(sender==mValuesContainer){
valuesChanged();
} }
} }
@Override @Override
@ -66,27 +65,17 @@ public class ResConfig extends FixedBlockContainer
} }
@Override @Override
protected void onRefreshed() { protected void onRefreshed() {
valuesChanged();
} }
public void parseQualifiers(String name){ public void parseQualifiers(String name){
ResConfigHelper.parseQualifiers(this, name); ResConfigHelper.parseQualifiers(this, name);
mQualifiers=null;
} }
public void setConfigSize(int size){ public void setConfigSize(int size){
if( size != SIZE_16 if(!isValidSize(size)){
&& size != SIZE_28
&& size != SIZE_32
&& size != SIZE_36
&& size != SIZE_48
&& size != SIZE_56
&& size != SIZE_64
){
throw new IllegalArgumentException("Invalid config size = " + size); throw new IllegalArgumentException("Invalid config size = " + size);
} }
this.configSize.set(size); this.configSize.set(size);
size=size-4; size=size-4;
mValuesContainer.setSize(size); mValuesContainer.setSize(size);
valuesChanged();
} }
public int getConfigSize(){ public int getConfigSize(){
return this.configSize.get(); return this.configSize.get();
@ -96,14 +85,7 @@ public class ResConfig extends FixedBlockContainer
if(current==size){ if(current==size){
return true; return true;
} }
if( size != SIZE_16 if(!isValidSize(size)){
&& size != SIZE_28
&& size != SIZE_32
&& size != SIZE_36
&& size != SIZE_48
&& size != SIZE_56
&& size != SIZE_64
){
return false; return false;
} }
if(current<size){ if(current<size){
@ -129,11 +111,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_mcc, sh); mValuesContainer.putShort(OFFSET_mcc, sh);
} }
public short getMcc(){ public int getMcc(){
if(getConfigSize()<SIZE_16){ if(getConfigSize()<SIZE_16){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_mcc); return mValuesContainer.getShortUnsigned(OFFSET_mcc);
} }
public void setMnc(short sh){ public void setMnc(short sh){
if(getConfigSize()<SIZE_16){ if(getConfigSize()<SIZE_16){
@ -144,11 +126,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_mnc, sh); mValuesContainer.putShort(OFFSET_mnc, sh);
} }
public short getMnc(){ public int getMnc(){
if(getConfigSize()<SIZE_16){ if(getConfigSize()<SIZE_16){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_mnc); return mValuesContainer.getShortUnsigned(OFFSET_mnc);
} }
public void setLanguageIn0(byte b){ public void setLanguageIn0(byte b){
if(getConfigSize()<SIZE_16){ if(getConfigSize()<SIZE_16){
@ -319,20 +301,20 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_density, sh); mValuesContainer.putShort(OFFSET_density, sh);
} }
public short getDensityValue(){ public int getDensityValue(){
if(getConfigSize()<SIZE_16){ if(getConfigSize()<SIZE_16){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_density); return mValuesContainer.getShortUnsigned(OFFSET_density);
} }
public String getDensity(){ public String getDensity(){
return ResConfigHelper.decodeDensity(getDensityValue()); return ResConfigHelper.decodeDensity(getDensityValue());
} }
public void setDensity(String density){ public void setDensity(String density){
setDensity(ResConfigHelper.encodeDensity(density)); setDensity((short) ResConfigHelper.encodeDensity(density));
} }
public void setKeyboard(byte b){ public void setKeyboard(byte b){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_16){
if(b==0){ if(b==0){
return; return;
} }
@ -341,7 +323,7 @@ public class ResConfig extends FixedBlockContainer
mValuesContainer.put(OFFSET_keyboard, b); mValuesContainer.put(OFFSET_keyboard, b);
} }
public byte getKeyboardByte(){ public byte getKeyboardByte(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_16){
return 0; return 0;
} }
return mValuesContainer.get(OFFSET_keyboard); return mValuesContainer.get(OFFSET_keyboard);
@ -357,7 +339,7 @@ public class ResConfig extends FixedBlockContainer
setKeyboard(b); setKeyboard(b);
} }
public void setNavigation(byte b){ public void setNavigation(byte b){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_16){
if(b==0){ if(b==0){
return; return;
} }
@ -366,7 +348,7 @@ public class ResConfig extends FixedBlockContainer
mValuesContainer.put(OFFSET_navigation, b); mValuesContainer.put(OFFSET_navigation, b);
} }
public byte getNavigationByte(){ public byte getNavigationByte(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_16){
return 0; return 0;
} }
return mValuesContainer.get(OFFSET_navigation); return mValuesContainer.get(OFFSET_navigation);
@ -426,11 +408,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_screenWidth, sh); mValuesContainer.putShort(OFFSET_screenWidth, sh);
} }
public short getScreenWidth(){ public int getScreenWidth(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_screenWidth); return mValuesContainer.getShortUnsigned(OFFSET_screenWidth);
} }
public void setScreenHeight(short sh){ public void setScreenHeight(short sh){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
@ -441,11 +423,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_screenHeight, sh); mValuesContainer.putShort(OFFSET_screenHeight, sh);
} }
public short getScreenHeight(){ public int getScreenHeight(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_screenHeight); return mValuesContainer.getShortUnsigned(OFFSET_screenHeight);
} }
public void setScreenSize(short w, short h){ public void setScreenSize(short w, short h){
this.setScreenWidth(w); this.setScreenWidth(w);
@ -460,11 +442,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_sdkVersion, sh); mValuesContainer.putShort(OFFSET_sdkVersion, sh);
} }
public short getSdkVersion(){ public int getSdkVersion(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_sdkVersion); return mValuesContainer.getShortUnsigned(OFFSET_sdkVersion);
} }
public void setMinorVersion(short sh){ public void setMinorVersion(short sh){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
@ -475,11 +457,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_minorVersion, sh); mValuesContainer.putShort(OFFSET_minorVersion, sh);
} }
public short getMinorVersion(){ public int getMinorVersion(){
if(getConfigSize()<SIZE_28){ if(getConfigSize()<SIZE_28){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_minorVersion); return mValuesContainer.getShortUnsigned(OFFSET_minorVersion);
} }
public void setScreenLayout(byte b){ public void setScreenLayout(byte b){
if(getConfigSize()<SIZE_32){ if(getConfigSize()<SIZE_32){
@ -532,11 +514,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_smallestScreenWidthDp, sh); mValuesContainer.putShort(OFFSET_smallestScreenWidthDp, sh);
} }
public short getSmallestScreenWidthDp(){ public int getSmallestScreenWidthDp(){
if(getConfigSize()<SIZE_32){ if(getConfigSize()<SIZE_32){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_smallestScreenWidthDp); return mValuesContainer.getShortUnsigned(OFFSET_smallestScreenWidthDp);
} }
public void setScreenWidthDp(short sh){ public void setScreenWidthDp(short sh){
if(getConfigSize()<SIZE_36){ if(getConfigSize()<SIZE_36){
@ -547,11 +529,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_screenWidthDp, sh); mValuesContainer.putShort(OFFSET_screenWidthDp, sh);
} }
public short getScreenWidthDp(){ public int getScreenWidthDp(){
if(getConfigSize()<SIZE_36){ if(getConfigSize()<SIZE_36){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_screenWidthDp); return mValuesContainer.getShortUnsigned(OFFSET_screenWidthDp);
} }
public void setScreenHeightDp(short sh){ public void setScreenHeightDp(short sh){
if(getConfigSize()<SIZE_36){ if(getConfigSize()<SIZE_36){
@ -562,11 +544,11 @@ public class ResConfig extends FixedBlockContainer
} }
mValuesContainer.putShort(OFFSET_screenHeightDp, sh); mValuesContainer.putShort(OFFSET_screenHeightDp, sh);
} }
public short getScreenHeightDp(){ public int getScreenHeightDp(){
if(getConfigSize()<SIZE_36){ if(getConfigSize()<SIZE_36){
return 0; return 0;
} }
return mValuesContainer.getShort(OFFSET_screenHeightDp); return mValuesContainer.getShortUnsigned(OFFSET_screenHeightDp);
} }
public void setLocaleScript(byte[] bts){ public void setLocaleScript(byte[] bts){
if(getConfigSize()<SIZE_48){ if(getConfigSize()<SIZE_48){
@ -582,12 +564,35 @@ public class ResConfig extends FixedBlockContainer
byte[] bts=toByteArray(chs, LEN_localeScript); byte[] bts=toByteArray(chs, LEN_localeScript);
setLocaleScript(bts); setLocaleScript(bts);
} }
public char[] getLocaleScript(){ public void setLocaleScript(String script){
char[] chs = null;
script = trimPostfix(script, POSTFIX_locale);
if(script!=null){
chs = script.toCharArray();
}
setLocaleScript(chs);
}
public char[] getLocaleScriptChars(){
if(getConfigSize()<SIZE_48){ if(getConfigSize()<SIZE_48){
return null; return null;
} }
byte[] bts = mValuesContainer.getByteArray(OFFSET_localeScript, LEN_localeScript); byte[] bts = mValuesContainer.getByteArray(OFFSET_localeScript, LEN_localeScript);
return toCharArray(bts); return trimEndingZero(toCharArray(bts));
}
private String getLocaleScriptInternal(){
char[] chs = getLocaleScriptChars();
if(chs==null){
return null;
}
return new String(chs);
}
public String getLocaleScript(){
String script = getLocaleScriptInternal();
if(script==null){
return null;
}
script = ensureLength(script, 3, POSTFIX_locale);
return script;
} }
public void setLocaleVariant(byte[] bts){ public void setLocaleVariant(byte[] bts){
if(getConfigSize()<SIZE_48){ if(getConfigSize()<SIZE_48){
@ -603,15 +608,44 @@ public class ResConfig extends FixedBlockContainer
byte[] bts=toByteArray(chs, LEN_localeVariant); byte[] bts=toByteArray(chs, LEN_localeVariant);
setLocaleVariant(bts); setLocaleVariant(bts);
} }
public char[] getLocaleVariant(){ public void setLocaleVariant(String variant){
if(variant!=null){
variant = variant.toLowerCase();
}
setLocaleVariantInternal(variant);
}
private void setLocaleVariantInternal(String variant){
char[] chs = null;
variant = trimPostfix(variant, POSTFIX_locale);
if(variant!=null){
chs = variant.toCharArray();
}
setLocaleVariant(chs);
}
public char[] getLocaleVariantChars(){
if(getConfigSize()<SIZE_48){ if(getConfigSize()<SIZE_48){
return null; return null;
} }
byte[] bts = mValuesContainer.getByteArray(OFFSET_localeVariant, LEN_localeVariant); byte[] bts = mValuesContainer.getByteArray(OFFSET_localeVariant, LEN_localeVariant);
return toCharArray(bts); return trimEndingZero(toCharArray(bts));
}
private String getLocaleVariantInternal(){
char[] chs = getLocaleVariantChars();
if(chs==null){
return null;
}
return new String(chs);
}
public String getLocaleVariant(){
String variant = getLocaleVariantInternal();
if(variant==null){
return null;
}
variant = ensureLength(variant, 5, POSTFIX_locale);
return variant.toUpperCase();
} }
public void setScreenLayout2(byte b){ public void setScreenLayout2(byte b){
if(getConfigSize()<SIZE_56){ if(getConfigSize()<SIZE_52){
if(b==0){ if(b==0){
return; return;
} }
@ -620,7 +654,7 @@ public class ResConfig extends FixedBlockContainer
mValuesContainer.put(OFFSET_screenLayout2, b); mValuesContainer.put(OFFSET_screenLayout2, b);
} }
public byte getScreenLayout2(){ public byte getScreenLayout2(){
if(getConfigSize()<SIZE_56){ if(getConfigSize()<SIZE_52){
return 0; return 0;
} }
return mValuesContainer.get(OFFSET_screenLayout2); return mValuesContainer.get(OFFSET_screenLayout2);
@ -641,14 +675,12 @@ public class ResConfig extends FixedBlockContainer
return mValuesContainer.get(OFFSET_colorMode); return mValuesContainer.get(OFFSET_colorMode);
} }
private void valuesChanged(){
mQualifiers=null;
}
public String getQualifiers(){ public String getQualifiers(){
if(mQualifiers==null){ int hash = this.hashCode();
if(mQualifiers==null || mQualifiersStamp!=hash){
try{ try{
mQualifiers = ResConfigHelper.toQualifier(this).trim(); mQualifiers = ResConfigHelper.toQualifier(this).trim();
mQualifiersStamp = hash;
}catch (Exception ex){ }catch (Exception ex){
mQualifiers = ""; mQualifiers = "";
} }
@ -751,6 +783,14 @@ public class ResConfig extends FixedBlockContainer
if(val!=0){ if(val!=0){
jsonObject.put(NAME_screenHeightDp, val); jsonObject.put(NAME_screenHeightDp, val);
} }
str = getLocaleScriptInternal();
if(str!=null){
jsonObject.put(NAME_localeScript, str);
}
str = getLocaleVariantInternal();
if(str!=null){
jsonObject.put(NAME_localeVariant, str);
}
return jsonObject; return jsonObject;
} }
@Override @Override
@ -780,9 +820,10 @@ public class ResConfig extends FixedBlockContainer
setSmallestScreenWidthDp((short) json.optInt(NAME_smallestScreenWidthDp)); setSmallestScreenWidthDp((short) json.optInt(NAME_smallestScreenWidthDp));
setScreenWidthDp((short) json.optInt(NAME_screenWidthDp)); setScreenWidthDp((short) json.optInt(NAME_screenWidthDp));
setScreenHeightDp((short) json.optInt(NAME_screenHeightDp)); setScreenHeightDp((short) json.optInt(NAME_screenHeightDp));
setLocaleScript(json.optString(NAME_localeScript));
setLocaleVariantInternal(json.optString(NAME_localeVariant));
trimToSize(SIZE_48); trimToSize(SIZE_48);
valuesChanged();
} }
@Override @Override
public int hashCode(){ public int hashCode(){
@ -892,10 +933,32 @@ public class ResConfig extends FixedBlockContainer
int sz=bts.length; int sz=bts.length;
char[] chs=new char[sz]; char[] chs=new char[sz];
for(int i=0; i<sz;i++){ for(int i=0; i<sz;i++){
chs[i]= (char) bts[i]; int val = 0xff & bts[i];
chs[i]= (char) val;
} }
return chs; return chs;
} }
private static char[] trimEndingZero(char[] chars){
if(chars==null){
return null;
}
int lastNonZero = -1;
for(int i=0;i<chars.length;i++){
if(chars[i]!=0){
lastNonZero = i;
}
}
if(lastNonZero==-1){
return null;
}
lastNonZero = lastNonZero+1;
if(lastNonZero==chars.length){
return chars;
}
char[] result = new char[lastNonZero];
System.arraycopy(chars, 0, result, 0, lastNonZero);
return result;
}
private static boolean isNull(char[] chs){ private static boolean isNull(char[] chs){
if(chs==null){ if(chs==null){
return true; return true;
@ -933,6 +996,48 @@ public class ResConfig extends FixedBlockContainer
System.arraycopy(bts, 0, result, 0, max); System.arraycopy(bts, 0, result, 0, max);
return result; return result;
} }
private static String ensureLength(String str, int min, char postfix){
int length = str.length();
if(length >= min){
return str;
}
StringBuilder builder = new StringBuilder();
builder.append(str);
int remain = min - length;
for(int i=0; i<remain; i++){
builder.append(postfix);
}
return builder.toString();
}
private static String trimPostfix(String str, char postfix){
if(str==null){
return null;
}
int length = str.length();
int index = length-1;
while (length>0 && str.charAt(index) == postfix){
str = str.substring(0, index);
length = str.length();
index = length - 1;
}
return str;
}
public static boolean isValidSize(int size){
switch (size){
case SIZE_16:
case SIZE_28:
case SIZE_32:
case SIZE_36:
case SIZE_48:
case SIZE_52:
case SIZE_56:
case SIZE_64:
return true;
default:
return size > SIZE_64;
}
}
public enum Orientation{ public enum Orientation{
PORT((byte) 0x1), PORT((byte) 0x1),
LAND((byte) 0x2), LAND((byte) 0x2),
@ -1090,6 +1195,7 @@ public class ResConfig extends FixedBlockContainer
public static final int SIZE_32 = 32; public static final int SIZE_32 = 32;
public static final int SIZE_36 = 36; public static final int SIZE_36 = 36;
public static final int SIZE_48 = 48; public static final int SIZE_48 = 48;
public static final int SIZE_52 = 52;
public static final int SIZE_56 = 56; public static final int SIZE_56 = 56;
public static final int SIZE_64 = 64; public static final int SIZE_64 = 64;
@ -1160,5 +1266,6 @@ public class ResConfig extends FixedBlockContainer
private static final String NAME_screenLayout2 = "screenLayout2"; private static final String NAME_screenLayout2 = "screenLayout2";
private static final String NAME_colorMode = "colorMode"; private static final String NAME_colorMode = "colorMode";
private static final char POSTFIX_locale = '#';
} }

View File

@ -27,7 +27,7 @@ public class ResConfigHelper {
result.refresh(); result.refresh();
return result; return result;
} }
static String toQualifier(ResConfig resConfig){ public static String toQualifier(ResConfig resConfig){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();
builder.append(decodeLanguageAndCountry(resConfig)); builder.append(decodeLanguageAndCountry(resConfig));
builder.append(decodeOrientation(resConfig)); builder.append(decodeOrientation(resConfig));
@ -105,6 +105,7 @@ public class ResConfigHelper {
encodeMnc(resConfig, split); encodeMnc(resConfig, split);
encodeScreenSize(resConfig, split); encodeScreenSize(resConfig, split);
encodeLanguageAndCountry(resConfig, split); encodeLanguageAndCountry(resConfig, split);
encodeScriptAndVariant(resConfig, split);
} }
private static void encodeLanguageAndCountry(ResConfig resConfig, String[] split){ private static void encodeLanguageAndCountry(ResConfig resConfig, String[] split){
@ -151,6 +152,93 @@ public class ResConfigHelper {
char[] chs=country.toCharArray(); char[] chs=country.toCharArray();
resConfig.setRegion(chs); resConfig.setRegion(chs);
} }
private static void encodeScriptAndVariant(ResConfig resConfig, String[] split){
if(split==null){
return;
}
for(int i=0;i<split.length;i++){
String s=split[i];
if(encodeScriptAndVariant(resConfig, s)){
split[i] = null;
break;
}
}
}
private static boolean encodeScriptAndVariant(ResConfig resConfig, String str){
if(str==null){
return false;
}
if(!str.startsWith("b+")){
return false;
}
str = str.substring(2);
String[] splits = str.split("\\+");
String lang = null;
String region = null;
String script = null;
String variant = null;
for(int i=0; i<splits.length; i++){
String s = splits[i];
int len = s.length();
if(len==0){
continue;
}
if(isLocaleVariant(s)){
if(variant!=null){
return false;
}
variant = s;
continue;
}
if(isLanguageName(s)){
if(lang!=null){
return false;
}
lang = s;
continue;
}
boolean is_region = (region==null && isCountryName(s));
boolean is_script = (script==null && isLocaleScript(s));
if(is_region && is_script){
if(s.charAt(len-1)=='#'){
script = s;
continue;
}
if(len==3 && s.charAt(0)=='r'){
region = s;
continue;
}
// TODO: should throw error or false ?
return false;
}
if(is_region){
region = s;
continue;
}
if(is_script){
script = s;
continue;
}
// TODO: should throw error or false ?
return false;
}
if(lang!=null){
resConfig.setLanguage(lang);
}
if(region!=null){
if(region.charAt(0)=='r'){
region = region.substring(1);
}
resConfig.setRegion(region);
}
if(script!=null){
resConfig.setLocaleScript(script);
}
if(variant!=null){
resConfig.setLocaleVariant(variant);
}
return true;
}
public static String decodeLanguage(char[] language){ public static String decodeLanguage(char[] language){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();
if(language[0]!=0){ if(language[0]!=0){
@ -191,8 +279,8 @@ public class ResConfigHelper {
} }
private static String decodeLanguageAndCountry(ResConfig resConfig) { private static String decodeLanguageAndCountry(ResConfig resConfig) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
char[] localeVariant=resConfig.getLocaleVariant(); String localeVariant = resConfig.getLocaleVariant();
char[] localeScript=resConfig.getLocaleScript(); String localeScript = resConfig.getLocaleScript();
char[] region=resConfig.getRegionChars(); char[] region=resConfig.getRegionChars();
char[] language=resConfig.getLanguageChars(); char[] language=resConfig.getLanguageChars();
if (localeVariant == null && localeScript == null && (region[0] != '\00' || language[0] != '\00') && if (localeVariant == null && localeScript == null && (region[0] != '\00' || language[0] != '\00') &&
@ -201,22 +289,19 @@ public class ResConfigHelper {
if (region[0] != '\00') { if (region[0] != '\00') {
builder.append("-r").append(region); builder.append("-r").append(region);
} }
} else { } else if(language[0] != 0 || region[0] != 0 || localeScript!=null || localeVariant!=null){
if (language[0] == '\00' && region[0] == '\00') { builder.append("-b");
return builder.toString();
}
builder.append("-b+");
if (language[0] != '\00') { if (language[0] != '\00') {
builder.append(language); builder.append('+').append(language);
} }
if (localeScript != null && localeScript.length == 4) { if (localeScript != null) {
builder.append("+").append(localeScript); builder.append('+').append(localeScript);
} }
if ((region.length == 2 || region.length == 3) && region[0] != '\00') { if ((region.length == 2 || region.length == 3) && region[0] != '\00') {
builder.append("+").append(region); builder.append('+').append(region);
} }
if (localeVariant != null && localeVariant.length >= 5) { if (localeVariant != null) {
builder.append("+").append(toUpper(localeVariant)); builder.append('+').append(localeVariant);
} }
} }
return builder.toString(); return builder.toString();
@ -408,7 +493,7 @@ public class ResConfigHelper {
/* /*
* Encodes density to value * Encodes density to value
* densityName is full name like: mdpi, xxxdpi, 580dpi ... */ * densityName is full name like: mdpi, xxxdpi, 580dpi ... */
public static short encodeDensity(String densityName){ public static int encodeDensity(String densityName){
short density=0; short density=0;
if(densityName==null){ if(densityName==null){
return density; return density;
@ -419,7 +504,7 @@ public class ResConfigHelper {
} }
return encodeDensityName(matcher.group(1)); return encodeDensityName(matcher.group(1));
} }
private static short encodeDensityName(String name){ private static int encodeDensityName(String name){
if("l".equals(name)){ if("l".equals(name)){
return DENSITY_LOW; return DENSITY_LOW;
}else if("m".equals(name)){ }else if("m".equals(name)){
@ -501,7 +586,7 @@ public class ResConfigHelper {
} }
return ret.toString(); return ret.toString();
} }
public static String decodeDensity(short density){ public static String decodeDensity(int density){
switch (density) { switch (density) {
case DENSITY_DEFAULT: case DENSITY_DEFAULT:
return null; return null;
@ -1046,8 +1131,8 @@ public class ResConfigHelper {
resConfig.setMnc(sh); resConfig.setMnc(sh);
} }
private static String decodeMccMnc(ResConfig resConfig){ private static String decodeMccMnc(ResConfig resConfig){
short mcc=resConfig.getMcc(); int mcc=resConfig.getMcc();
short mnc=resConfig.getMnc(); int mnc=resConfig.getMnc();
int size=resConfig.getConfigSize(); int size=resConfig.getConfigSize();
StringBuilder ret = new StringBuilder(); StringBuilder ret = new StringBuilder();
if (mcc != 0) { if (mcc != 0) {
@ -1191,8 +1276,8 @@ public class ResConfigHelper {
return builder.toString(); return builder.toString();
} }
private static String decodeScreenSize(ResConfig resConfig){ private static String decodeScreenSize(ResConfig resConfig){
short width=resConfig.getScreenWidth(); int width=resConfig.getScreenWidth();
short height=resConfig.getScreenHeight(); int height=resConfig.getScreenHeight();
if(width==0||height==0){ if(width==0||height==0){
return ""; return "";
} }
@ -1236,6 +1321,20 @@ public class ResConfigHelper {
Matcher matcher=PATTERN_LANG_NAME.matcher(str); Matcher matcher=PATTERN_LANG_NAME.matcher(str);
return matcher.find(); return matcher.find();
} }
private static boolean isLocaleScript(String str){
if(str==null){
return false;
}
Matcher matcher=PATTERN_LOCALE_SCRIPT.matcher(str);
return matcher.find();
}
private static boolean isLocaleVariant(String str){
if(str==null){
return false;
}
Matcher matcher=PATTERN_LOCALE_VARIANT.matcher(str);
return matcher.find();
}
private static boolean isCountryName(String str){ private static boolean isCountryName(String str){
if(str==null){ if(str==null){
return false; return false;
@ -1289,6 +1388,10 @@ public class ResConfigHelper {
private static final Pattern PATTERN_COUNTRY_NAME=Pattern.compile("^[a-zA-Z]{2,3}$"); private static final Pattern PATTERN_COUNTRY_NAME=Pattern.compile("^[a-zA-Z]{2,3}$");
private static final Pattern PATTERN_LOCALE_SCRIPT=Pattern.compile("^[a-zA-Z0-9]{3,4}$");
private static final Pattern PATTERN_LOCALE_VARIANT=Pattern.compile("^[a-zA-Z0-9#]{5,8}$");
private static final Pattern PATTERN_MCC_MNC=Pattern.compile("^(m[cn]c)([0-9]{2,3})$"); private static final Pattern PATTERN_MCC_MNC=Pattern.compile("^(m[cn]c)([0-9]{2,3})$");
private static final Pattern PATTERN_DENSITY=Pattern.compile("^([^\\s]+)dpi$"); private static final Pattern PATTERN_DENSITY=Pattern.compile("^([^\\s]+)dpi$");
@ -1374,8 +1477,8 @@ public class ResConfigHelper {
private final static int DENSITY_XHIGH = 320; private final static int DENSITY_XHIGH = 320;
private final static int DENSITY_XXHIGH = 480; private final static int DENSITY_XXHIGH = 480;
private final static int DENSITY_XXXHIGH = 640; private final static int DENSITY_XXXHIGH = 640;
private final static int DENSITY_ANY = -2; private final static int DENSITY_ANY = 0xfffe;
private final static int DENSITY_NONE = -1; private final static int DENSITY_NONE = 0xffff;
} }