1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm; 60 61 /** 62 * A dynamically extensible vector of bytes. This class is roughly equivalent to 63 * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. 64 * 65 * @author Eric Bruneton 66 */ 67 public class ByteVector { 68 69 /** 70 * The content of this vector. 71 */ 72 byte[] data; 73 74 /** 75 * Actual number of bytes in this vector. 76 */ 77 int length; 78 79 /** 80 * Constructs a new {@link ByteVector ByteVector} with a default initial 81 * size. 82 */ 83 public ByteVector() { 84 data = new byte[64]; 85 } 86 87 /** 88 * Constructs a new {@link ByteVector ByteVector} with the given initial 89 * size. 90 * 91 * @param initialSize the initial size of the byte vector to be constructed. 92 */ 93 public ByteVector(final int initialSize) { 94 data = new byte[initialSize]; 95 } 96 97 /** 98 * Puts a byte into this byte vector. The byte vector is automatically 99 * enlarged if necessary. 100 * 101 * @param b a byte. 102 * @return this byte vector. 103 */ 104 public ByteVector putByte(final int b) { 105 int length = this.length; 106 if (length + 1 > data.length) { 107 enlarge(1); 108 } 109 data[length++] = (byte) b; 110 this.length = length; 111 return this; 112 } 113 114 /** 115 * Puts two bytes into this byte vector. The byte vector is automatically 116 * enlarged if necessary. 117 * 118 * @param b1 a byte. 119 * @param b2 another byte. 120 * @return this byte vector. 121 */ 122 ByteVector put11(final int b1, final int b2) { 123 int length = this.length; 124 if (length + 2 > data.length) { 125 enlarge(2); 126 } 127 byte[] data = this.data; 128 data[length++] = (byte) b1; 129 data[length++] = (byte) b2; 130 this.length = length; 131 return this; 132 } 133 134 /** 135 * Puts a short into this byte vector. The byte vector is automatically 136 * enlarged if necessary. 137 * 138 * @param s a short. 139 * @return this byte vector. 140 */ 141 public ByteVector putShort(final int s) { 142 int length = this.length; 143 if (length + 2 > data.length) { 144 enlarge(2); 145 } 146 byte[] data = this.data; 147 data[length++] = (byte) (s >>> 8); 148 data[length++] = (byte) s; 149 this.length = length; 150 return this; 151 } 152 153 /** 154 * Puts a byte and a short into this byte vector. The byte vector is 155 * automatically enlarged if necessary. 156 * 157 * @param b a byte. 158 * @param s a short. 159 * @return this byte vector. 160 */ 161 ByteVector put12(final int b, final int s) { 162 int length = this.length; 163 if (length + 3 > data.length) { 164 enlarge(3); 165 } 166 byte[] data = this.data; 167 data[length++] = (byte) b; 168 data[length++] = (byte) (s >>> 8); 169 data[length++] = (byte) s; 170 this.length = length; 171 return this; 172 } 173 174 /** 175 * Puts an int into this byte vector. The byte vector is automatically 176 * enlarged if necessary. 177 * 178 * @param i an int. 179 * @return this byte vector. 180 */ 181 public ByteVector putInt(final int i) { 182 int length = this.length; 183 if (length + 4 > data.length) { 184 enlarge(4); 185 } 186 byte[] data = this.data; 187 data[length++] = (byte) (i >>> 24); 188 data[length++] = (byte) (i >>> 16); 189 data[length++] = (byte) (i >>> 8); 190 data[length++] = (byte) i; 191 this.length = length; 192 return this; 193 } 194 195 /** 196 * Puts a long into this byte vector. The byte vector is automatically 197 * enlarged if necessary. 198 * 199 * @param l a long. 200 * @return this byte vector. 201 */ 202 public ByteVector putLong(final long l) { 203 int length = this.length; 204 if (length + 8 > data.length) { 205 enlarge(8); 206 } 207 byte[] data = this.data; 208 int i = (int) (l >>> 32); 209 data[length++] = (byte) (i >>> 24); 210 data[length++] = (byte) (i >>> 16); 211 data[length++] = (byte) (i >>> 8); 212 data[length++] = (byte) i; 213 i = (int) l; 214 data[length++] = (byte) (i >>> 24); 215 data[length++] = (byte) (i >>> 16); 216 data[length++] = (byte) (i >>> 8); 217 data[length++] = (byte) i; 218 this.length = length; 219 return this; 220 } 221 222 /** 223 * Puts an UTF8 string into this byte vector. The byte vector is 224 * automatically enlarged if necessary. 225 * 226 * @param s a String. 227 * @return this byte vector. 228 */ 229 public ByteVector putUTF8(final String s) { 230 int charLength = s.length(); 231 int len = length; 232 if (len + 2 + charLength > data.length) { 233 enlarge(2 + charLength); 234 } 235 byte[] data = this.data; 236 // optimistic algorithm: instead of computing the byte length and then 237 // serializing the string (which requires two loops), we assume the byte 238 // length is equal to char length (which is the most frequent case), and 239 // we start serializing the string right away. During the serialization, 240 // if we find that this assumption is wrong, we continue with the 241 // general method. 242 data[len++] = (byte) (charLength >>> 8); 243 data[len++] = (byte) charLength; 244 for (int i = 0; i < charLength; ++i) { 245 char c = s.charAt(i); 246 if (c >= '\001' && c <= '\177') { 247 data[len++] = (byte) c; 248 } else { 249 int byteLength = i; 250 for (int j = i; j < charLength; ++j) { 251 c = s.charAt(j); 252 if (c >= '\001' && c <= '\177') { 253 byteLength++; 254 } else if (c > '\u07FF') { 255 byteLength += 3; 256 } else { 257 byteLength += 2; 258 } 259 } 260 data[length] = (byte) (byteLength >>> 8); 261 data[length + 1] = (byte) byteLength; 262 if (length + 2 + byteLength > data.length) { 263 length = len; 264 enlarge(2 + byteLength); 265 data = this.data; 266 } 267 for (int j = i; j < charLength; ++j) { 268 c = s.charAt(j); 269 if (c >= '\001' && c <= '\177') { 270 data[len++] = (byte) c; 271 } else if (c > '\u07FF') { 272 data[len++] = (byte) (0xE0 | c >> 12 & 0xF); 273 data[len++] = (byte) (0x80 | c >> 6 & 0x3F); 274 data[len++] = (byte) (0x80 | c & 0x3F); 275 } else { 276 data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); 277 data[len++] = (byte) (0x80 | c & 0x3F); 278 } 279 } 280 break; 281 } 282 } 283 length = len; 284 return this; 285 } 286 287 /** 288 * Puts an array of bytes into this byte vector. The byte vector is 289 * automatically enlarged if necessary. 290 * 291 * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> 292 * null bytes into this byte vector. 293 * @param off index of the fist byte of b that must be copied. 294 * @param len number of bytes of b that must be copied. 295 * @return this byte vector. 296 */ 297 public ByteVector putByteArray(final byte[] b, final int off, final int len) 298 { 299 if (length + len > data.length) { 300 enlarge(len); 301 } 302 if (b != null) { 303 System.arraycopy(b, off, data, length, len); 304 } 305 length += len; 306 return this; 307 } 308 309 /** 310 * Enlarge this byte vector so that it can receive n more bytes. 311 * 312 * @param size number of additional bytes that this byte vector should be 313 * able to receive. 314 */ 315 private void enlarge(final int size) { 316 int length1 = 2 * data.length; 317 int length2 = length + size; 318 byte[] newData = new byte[length1 > length2 ? length1 : length2]; 319 System.arraycopy(data, 0, newData, 0, length); 320 data = newData; 321 } 322 }