All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reandroid.arsc.coder.ReferenceString Maven / Gradle / Ivy

There is a newer version: 1.3.5
Show newest version
/*
 *  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.coder;

import com.reandroid.arsc.chunk.PackageBlock;
import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.model.ResourceEntry;
import com.reandroid.arsc.value.ValueType;

import java.io.IOException;

public class ReferenceString {
    public final String prefix;
    public final String packageName;
    public final String type;
    public final String name;

    public ReferenceString(String prefix, String packageName, String type, String name) {
        this.prefix = prefix;
        this.packageName = packageName;
        this.type = type;
        this.name = name;
    }
    public EncodeResult encode(TableBlock tableBlock){
        return encode(tableBlock, null);
    }
    public EncodeResult encode(TableBlock tableBlock, EncodeResult notFound){
        ResourceEntry resourceEntry = tableBlock.getResource(packageName, type, name);
        if(resourceEntry != null){
            return new EncodeResult(getValueType(), resourceEntry.getResourceId());
        }
        return notFound;
    }
    public EncodeResult encode(PackageBlock packageBlock){
        return encode(packageBlock, null);
    }
    public EncodeResult encode(PackageBlock packageBlock, EncodeResult notFound){
        ResourceEntry resourceEntry = packageBlock.getTableBlock()
                .getResource(packageBlock, packageName, type, name);
        if(resourceEntry != null){
            return new EncodeResult(getValueType(), resourceEntry.getResourceId());
        }
        return notFound;
    }
    public ValueType getValueType(){
        if("?".equals(prefix)){
            return ValueType.ATTRIBUTE;
        }
        return ValueType.REFERENCE;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (prefix != null) {
            builder.append(prefix);
        }
        if (packageName != null) {
            builder.append(packageName);
            builder.append(':');
        }
        if (type != null) {
            builder.append(type);
            builder.append('/');
        }
        builder.append(name);
        return builder.toString();
    }

    public static EncodeResult encodeReference(PackageBlock packageBlock, String text) throws IOException {
        return encodeReference(packageBlock, text, null);
    }

    public static EncodeResult encodeReference(PackageBlock packageBlock, String text, EncodeResult errorResult) throws IOException {
        EncodeResult encodeResult = ValueCoder.encodeUnknownResourceId(text);
        if(encodeResult != null){
            return encodeResult;
        }
        ReferenceString referenceString = ReferenceString.parseReference(text);
        if(referenceString == null){
            return null;
        }
        encodeResult = referenceString.encode(packageBlock.getTableBlock());
        if(encodeResult == null){
            if(errorResult != null){
                return errorResult;
            }
            throw new IOException("Unknown reference: " + text);
        }
        return encodeResult;
    }

    public static ReferenceString parseReference(String ref){
        if(ref == null || ref.length() < 2 || ref.indexOf('/') < 0 || ref.indexOf(' ') > 0){
            return null;
        }
        char first = ref.charAt(0);
        if(first != '@' && first != '?'){
            return null;
        }
        String prefix;
        int i = 1;
        if(ref.charAt(1) == '+'){
            i = 2;
        }
        prefix = ref.substring(0, i);
        ref = ref.substring(i);
        String packageName = null;
        i = ref.indexOf(':');
        if(i > 0){
            packageName = ref.substring(0, i);
            i++;
            ref = ref.substring(i);
        }
        i = ref.indexOf('/');
        if(i < 0){
            return null;
        }
        String type = ref.substring(0, i);
        i++;
        String name = ref.substring(i);
        if(!isValidResourceName(name)){
            return null;
        }
        return new ReferenceString(prefix, packageName, type, name);
    }
    private static boolean isValidResourceName(String text){
        char[] chars = text.toCharArray();
        int length = chars.length;
        if(length == 0){
            return false;
        }
        for(int i = 0; i < length; i++){
            if(!isValidResourceName(chars[i])){
                return false;
            }
        }
        return true;
    }
    private static boolean isValidResourceName(char ch){
        switch (ch){
            case ':':
            case '/':
            case '@':
            case '?':
            case '"':
            case '<':
            case '>':
            case '+':
            case '*':
                return false;
            default:
                return true;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy