/ app / src / main / java / com / reandroid / arsc / item / ByteArray.java
ByteArray.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 java.util.AbstractList;
 19  import java.util.List;
 20  
 21  public class ByteArray extends BlockItem {
 22      public ByteArray(int bytesLength) {
 23          super(bytesLength);
 24      }
 25      public ByteArray() {
 26          this(0);
 27      }
 28      public final void clear(){
 29          setSize(0);
 30      }
 31      public final void add(byte[] values){
 32          if(values==null || values.length==0){
 33              return;
 34          }
 35          int old=size();
 36          int len=values.length;
 37          setBytesLength(old+len, false);
 38          byte[] bts = getBytesInternal();
 39          System.arraycopy(values, 0, bts, old, len);
 40      }
 41      public final void set(byte[] values){
 42          super.setBytesInternal(values);
 43      }
 44      public final byte[] toArray(){
 45          return getBytes();
 46      }
 47      public final void fill(byte value){
 48          byte[] bts=getBytesInternal();
 49          int max=bts.length;
 50          for(int i=0;i<max;i++){
 51              bts[i]=value;
 52          }
 53      }
 54      public final void ensureArraySize(int s){
 55          int sz=size();
 56          if(sz>=s){
 57              return;
 58          }
 59          setSize(s);
 60      }
 61      public final void setSize(int s){
 62          if(s<0){
 63              s=0;
 64          }
 65          setBytesLength(s);
 66      }
 67      public final int size(){
 68          return getBytesLength();
 69      }
 70      public byte get(int index){
 71          return getBytesInternal()[index];
 72      }
 73      public int getByteUnsigned(int index){
 74          return 0xff & get(index);
 75      }
 76      public final void putByte(int index, int byteValue){
 77          put(index, (byte) byteValue);
 78      }
 79      public final void put(int index, byte value){
 80          byte[] bts = getBytesInternal();
 81          bts[index]=value;
 82      }
 83      public boolean getBit(int byteOffset, int bitIndex){
 84          return getBit(getBytesInternal(), byteOffset, bitIndex);
 85      }
 86      public void putBit(int byteOffset, int bitIndex, boolean bit){
 87          putBit(getBytesInternal(), byteOffset, bitIndex, bit);
 88      }
 89      public final void putShort(int offset, int value){
 90          putShort(offset, (short) value);
 91      }
 92      public final void putShort(int offset, short val){
 93          byte[] bts = getBytesInternal();
 94          bts[offset+1]= (byte) (val >>> 8 & 0xff);
 95          bts[offset]= (byte) (val & 0xff);
 96      }
 97      public final int getShortUnsigned(int offset){
 98          return 0xffff & getShort(offset);
 99      }
100      public final short getShort(int offset){
101          byte[] bts = getBytesInternal();
102          return (short) (bts[offset] & 0xff | (bts[offset+1] & 0xff) << 8);
103      }
104      public final void putInteger(int offset, int val){
105          byte[] bts = getBytesInternal();
106          if((offset+4)>bts.length){
107              return;
108          }
109          bts[offset+3]= (byte) (val >>> 24 & 0xff);
110          bts[offset+2]= (byte) (val >>> 16 & 0xff);
111          bts[offset+1]= (byte) (val >>> 8 & 0xff);
112          bts[offset]= (byte) (val & 0xff);
113      }
114      public final int getInteger(int offset){
115          byte[] bts = getBytesInternal();
116          if((offset+4)>bts.length){
117              return 0;
118          }
119          return bts[offset] & 0xff |
120                  (bts[offset+1] & 0xff) << 8 |
121                  (bts[offset+2] & 0xff) << 16 |
122                  (bts[offset+3] & 0xff) << 24;
123      }
124      public final void putByteArray(int offset, byte[] val){
125          byte[] bts = getBytesInternal();
126          int avail = bts.length-offset;
127          if(avail<=0){
128              return;
129          }
130          int len = val.length;
131          if(len>avail){
132              len=avail;
133          }
134          System.arraycopy(val, 0, bts, offset, len);
135      }
136      public final byte[] getByteArray(int offset, int length){
137          byte[] bts = getBytesInternal();
138          byte[] result = new byte[length];
139          if (result.length >= 0) {
140              System.arraycopy(bts, offset, result, 0, result.length);
141          }
142          return result;
143      }
144  
145      public final List<Byte> toByteList(){
146          return new AbstractList<Byte>() {
147              @Override
148              public Byte get(int i) {
149                  return ByteArray.this.get(i);
150              }
151              @Override
152              public int size() {
153                  return ByteArray.this.size();
154              }
155          };
156      }
157      public final List<Short> toShortList(){
158          return new AbstractList<Short>() {
159              @Override
160              public Short get(int i) {
161                  return ByteArray.this.getShort(i);
162              }
163              @Override
164              public int size() {
165                  return ByteArray.this.size()/2;
166              }
167          };
168      }
169      public final List<Integer> toIntegerList(){
170          return new AbstractList<Integer>() {
171              @Override
172              public Integer get(int i) {
173                  return ByteArray.this.getInteger(i);
174              }
175              @Override
176              public int size() {
177                  return ByteArray.this.size()/4;
178              }
179          };
180      }
181      @Override
182      public String toString(){
183          return "size="+size();
184      }
185  
186      public static byte[] trimTrailZeros(byte[] bts){
187          if(bts==null){
188              return new byte[0];
189          }
190          int len=0;
191          for(int i=0;i<bts.length;i++){
192              if(bts[i]!=0){
193                  len=i+1;
194              }
195          }
196          byte[] result=new byte[len];
197          if(result.length>0){
198              System.arraycopy(bts, 0, result, 0, result.length);
199          }
200          return result;
201      }
202      public static boolean equals(byte[] bts1, byte[] bts2){
203          if(bts1==bts2){
204              return true;
205          }
206          if(bts1==null || bts1.length==0){
207              return bts2==null || bts2.length==0;
208          }
209          if(bts2==null || bts2.length==0){
210              return false;
211          }
212          if(bts1.length!=bts2.length){
213              return false;
214          }
215          for(int i=0;i<bts1.length;i++){
216              if(bts1[i]!=bts2[i]){
217                  return false;
218              }
219          }
220          return true;
221      }
222      public static boolean equalsIgnoreTrailZero(byte[] bts1, byte[] bts2){
223          if(bts1==bts2){
224              return true;
225          }
226          return equals(trimTrailZeros(bts1), trimTrailZeros(bts2));
227      }
228  }