/ app / src / main / java / com / reandroid / arsc / item / FixedLengthString.java
FixedLengthString.java
  1  /*
  2   *  Copyright (C) 2022 github.com/REAndroid
  3   *
  4   *  Licensed under the Apache License, Version 2.0 (the "License");
  5   *  you may not use this file except in compliance with the License.
  6   *  You may obtain a copy of the License at
  7   *
  8   *      http://www.apache.org/licenses/LICENSE-2.0
  9   *
 10   * Unless required by applicable law or agreed to in writing, software
 11   * distributed under the License is distributed on an "AS IS" BASIS,
 12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13   * See the License for the specific language governing permissions and
 14   * limitations under the License.
 15   */
 16  package com.reandroid.arsc.item;
 17  
 18  import com.reandroid.arsc.io.BlockReader;
 19  import com.reandroid.utils.StringsUtil;
 20  
 21  import java.nio.charset.StandardCharsets;
 22  
 23  public class FixedLengthString  extends StringItem {
 24      private final int bytesLength;
 25      public FixedLengthString(int bytesLength){
 26          super(true);
 27          this.bytesLength = bytesLength;
 28          setBytesLength(bytesLength);
 29      }
 30      @Override
 31      protected byte[] encodeString(String text){
 32          if(text == null){
 33              return new byte[bytesLength];
 34          }
 35          byte[] bytes = getUtf16Bytes(text);
 36          byte[] results = new byte[this.bytesLength];
 37          int length = bytes.length;
 38          if(length > this.bytesLength){
 39              length = this.bytesLength;
 40          }
 41          System.arraycopy(bytes, 0, results, 0, length);
 42          return results;
 43      }
 44      @Override
 45      protected String decodeString(byte[] bytes){
 46          return decodeUtf16Bytes(bytes);
 47      }
 48      @Override
 49      public StyleItem getOrCreateStyle(){
 50          return null;
 51      }
 52      @Override
 53      int calculateReadLength(BlockReader reader){
 54          return bytesLength;
 55      }
 56  
 57      @Override
 58      protected void onStringChanged(String old, String text) {
 59      }
 60  
 61      @Override
 62      public int compareTo(StringItem stringItem){
 63          if(stringItem == null){
 64              return -1;
 65          }
 66          return StringsUtil.compareStrings(get(), stringItem.get());
 67      }
 68      @Override
 69      public String toString(){
 70          return "FIXED-" + bytesLength + " {" + get() + "}";
 71      }
 72      private static String decodeUtf16Bytes(byte[] bytes){
 73          if(isNullBytes(bytes)){
 74              return null;
 75          }
 76          int length = getEndNullPosition(bytes);
 77          return new String(bytes,0, length, StandardCharsets.UTF_16LE);
 78      }
 79      private static int getEndNullPosition(byte[] bytes){
 80          int length = bytes.length;
 81          int result = 0;
 82          boolean found = false;
 83          for(int i = 1; i < length; i++){
 84              byte b0 = bytes[i - 1];
 85              byte b1 = bytes[i];
 86              if(b0 == 0 && b1 == 0){
 87                  if(!found){
 88                      result = i;
 89                      found = true;
 90                  }else if(result<i-1){
 91                      return result;
 92                  }
 93              }else {
 94                  found = false;
 95              }
 96          }
 97          if(!found){
 98              return length;
 99          }
100          return result;
101      }
102  }