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 }