Mercurial > lasercutter
diff src/clojure/asm/ByteVector.java @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/asm/ByteVector.java Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,318 @@ 1.4 +/*** 1.5 + * ASM: a very small and fast Java bytecode manipulation framework 1.6 + * Copyright (c) 2000-2005 INRIA, France Telecom 1.7 + * All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions 1.11 + * are met: 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 2. Redistributions in binary form must reproduce the above copyright 1.15 + * notice, this list of conditions and the following disclaimer in the 1.16 + * documentation and/or other materials provided with the distribution. 1.17 + * 3. Neither the name of the copyright holders nor the names of its 1.18 + * contributors may be used to endorse or promote products derived from 1.19 + * this software without specific prior written permission. 1.20 + * 1.21 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.22 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.23 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.24 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.25 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.26 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.27 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.28 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.29 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.30 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.31 + * THE POSSIBILITY OF SUCH DAMAGE. 1.32 + */ 1.33 +package clojure.asm; 1.34 + 1.35 +/** 1.36 + * A dynamically extensible vector of bytes. This class is roughly equivalent to 1.37 + * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. 1.38 + * 1.39 + * @author Eric Bruneton 1.40 + */ 1.41 +public class ByteVector{ 1.42 + 1.43 +/** 1.44 + * The content of this vector. 1.45 + */ 1.46 +byte[] data; 1.47 + 1.48 +/** 1.49 + * Actual number of bytes in this vector. 1.50 + */ 1.51 +int length; 1.52 + 1.53 +/** 1.54 + * Constructs a new {@link ByteVector ByteVector} with a default initial 1.55 + * size. 1.56 + */ 1.57 +public ByteVector(){ 1.58 + data = new byte[64]; 1.59 +} 1.60 + 1.61 +/** 1.62 + * Constructs a new {@link ByteVector ByteVector} with the given initial 1.63 + * size. 1.64 + * 1.65 + * @param initialSize the initial size of the byte vector to be constructed. 1.66 + */ 1.67 +public ByteVector(final int initialSize){ 1.68 + data = new byte[initialSize]; 1.69 +} 1.70 + 1.71 +/** 1.72 + * Puts a byte into this byte vector. The byte vector is automatically 1.73 + * enlarged if necessary. 1.74 + * 1.75 + * @param b a byte. 1.76 + * @return this byte vector. 1.77 + */ 1.78 +public ByteVector putByte(final int b){ 1.79 + int length = this.length; 1.80 + if(length + 1 > data.length) 1.81 + { 1.82 + enlarge(1); 1.83 + } 1.84 + data[length++] = (byte) b; 1.85 + this.length = length; 1.86 + return this; 1.87 +} 1.88 + 1.89 +/** 1.90 + * Puts two bytes into this byte vector. The byte vector is automatically 1.91 + * enlarged if necessary. 1.92 + * 1.93 + * @param b1 a byte. 1.94 + * @param b2 another byte. 1.95 + * @return this byte vector. 1.96 + */ 1.97 +ByteVector put11(final int b1, final int b2){ 1.98 + int length = this.length; 1.99 + if(length + 2 > data.length) 1.100 + { 1.101 + enlarge(2); 1.102 + } 1.103 + byte[] data = this.data; 1.104 + data[length++] = (byte) b1; 1.105 + data[length++] = (byte) b2; 1.106 + this.length = length; 1.107 + return this; 1.108 +} 1.109 + 1.110 +/** 1.111 + * Puts a short into this byte vector. The byte vector is automatically 1.112 + * enlarged if necessary. 1.113 + * 1.114 + * @param s a short. 1.115 + * @return this byte vector. 1.116 + */ 1.117 +public ByteVector putShort(final int s){ 1.118 + int length = this.length; 1.119 + if(length + 2 > data.length) 1.120 + { 1.121 + enlarge(2); 1.122 + } 1.123 + byte[] data = this.data; 1.124 + data[length++] = (byte) (s >>> 8); 1.125 + data[length++] = (byte) s; 1.126 + this.length = length; 1.127 + return this; 1.128 +} 1.129 + 1.130 +/** 1.131 + * Puts a byte and a short into this byte vector. The byte vector is 1.132 + * automatically enlarged if necessary. 1.133 + * 1.134 + * @param b a byte. 1.135 + * @param s a short. 1.136 + * @return this byte vector. 1.137 + */ 1.138 +ByteVector put12(final int b, final int s){ 1.139 + int length = this.length; 1.140 + if(length + 3 > data.length) 1.141 + { 1.142 + enlarge(3); 1.143 + } 1.144 + byte[] data = this.data; 1.145 + data[length++] = (byte) b; 1.146 + data[length++] = (byte) (s >>> 8); 1.147 + data[length++] = (byte) s; 1.148 + this.length = length; 1.149 + return this; 1.150 +} 1.151 + 1.152 +/** 1.153 + * Puts an int into this byte vector. The byte vector is automatically 1.154 + * enlarged if necessary. 1.155 + * 1.156 + * @param i an int. 1.157 + * @return this byte vector. 1.158 + */ 1.159 +public ByteVector putInt(final int i){ 1.160 + int length = this.length; 1.161 + if(length + 4 > data.length) 1.162 + { 1.163 + enlarge(4); 1.164 + } 1.165 + byte[] data = this.data; 1.166 + data[length++] = (byte) (i >>> 24); 1.167 + data[length++] = (byte) (i >>> 16); 1.168 + data[length++] = (byte) (i >>> 8); 1.169 + data[length++] = (byte) i; 1.170 + this.length = length; 1.171 + return this; 1.172 +} 1.173 + 1.174 +/** 1.175 + * Puts a long into this byte vector. The byte vector is automatically 1.176 + * enlarged if necessary. 1.177 + * 1.178 + * @param l a long. 1.179 + * @return this byte vector. 1.180 + */ 1.181 +public ByteVector putLong(final long l){ 1.182 + int length = this.length; 1.183 + if(length + 8 > data.length) 1.184 + { 1.185 + enlarge(8); 1.186 + } 1.187 + byte[] data = this.data; 1.188 + int i = (int) (l >>> 32); 1.189 + data[length++] = (byte) (i >>> 24); 1.190 + data[length++] = (byte) (i >>> 16); 1.191 + data[length++] = (byte) (i >>> 8); 1.192 + data[length++] = (byte) i; 1.193 + i = (int) l; 1.194 + data[length++] = (byte) (i >>> 24); 1.195 + data[length++] = (byte) (i >>> 16); 1.196 + data[length++] = (byte) (i >>> 8); 1.197 + data[length++] = (byte) i; 1.198 + this.length = length; 1.199 + return this; 1.200 +} 1.201 + 1.202 +/** 1.203 + * Puts an UTF8 string into this byte vector. The byte vector is 1.204 + * automatically enlarged if necessary. 1.205 + * 1.206 + * @param s a String. 1.207 + * @return this byte vector. 1.208 + */ 1.209 +public ByteVector putUTF8(final String s){ 1.210 + int charLength = s.length(); 1.211 + if(length + 2 + charLength > data.length) 1.212 + { 1.213 + enlarge(2 + charLength); 1.214 + } 1.215 + int len = length; 1.216 + byte[] data = this.data; 1.217 + // optimistic algorithm: instead of computing the byte length and then 1.218 + // serializing the string (which requires two loops), we assume the byte 1.219 + // length is equal to char length (which is the most frequent case), and 1.220 + // we start serializing the string right away. During the serialization, 1.221 + // if we find that this assumption is wrong, we continue with the 1.222 + // general method. 1.223 + data[len++] = (byte) (charLength >>> 8); 1.224 + data[len++] = (byte) charLength; 1.225 + for(int i = 0; i < charLength; ++i) 1.226 + { 1.227 + char c = s.charAt(i); 1.228 + if(c >= '\001' && c <= '\177') 1.229 + { 1.230 + data[len++] = (byte) c; 1.231 + } 1.232 + else 1.233 + { 1.234 + int byteLength = i; 1.235 + for(int j = i; j < charLength; ++j) 1.236 + { 1.237 + c = s.charAt(j); 1.238 + if(c >= '\001' && c <= '\177') 1.239 + { 1.240 + byteLength++; 1.241 + } 1.242 + else if(c > '\u07FF') 1.243 + { 1.244 + byteLength += 3; 1.245 + } 1.246 + else 1.247 + { 1.248 + byteLength += 2; 1.249 + } 1.250 + } 1.251 + data[length] = (byte) (byteLength >>> 8); 1.252 + data[length + 1] = (byte) byteLength; 1.253 + if(length + 2 + byteLength > data.length) 1.254 + { 1.255 + length = len; 1.256 + enlarge(2 + byteLength); 1.257 + data = this.data; 1.258 + } 1.259 + for(int j = i; j < charLength; ++j) 1.260 + { 1.261 + c = s.charAt(j); 1.262 + if(c >= '\001' && c <= '\177') 1.263 + { 1.264 + data[len++] = (byte) c; 1.265 + } 1.266 + else if(c > '\u07FF') 1.267 + { 1.268 + data[len++] = (byte) (0xE0 | c >> 12 & 0xF); 1.269 + data[len++] = (byte) (0x80 | c >> 6 & 0x3F); 1.270 + data[len++] = (byte) (0x80 | c & 0x3F); 1.271 + } 1.272 + else 1.273 + { 1.274 + data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); 1.275 + data[len++] = (byte) (0x80 | c & 0x3F); 1.276 + } 1.277 + } 1.278 + break; 1.279 + } 1.280 + } 1.281 + length = len; 1.282 + return this; 1.283 +} 1.284 + 1.285 +/** 1.286 + * Puts an array of bytes into this byte vector. The byte vector is 1.287 + * automatically enlarged if necessary. 1.288 + * 1.289 + * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> 1.290 + * null bytes into this byte vector. 1.291 + * @param off index of the fist byte of b that must be copied. 1.292 + * @param len number of bytes of b that must be copied. 1.293 + * @return this byte vector. 1.294 + */ 1.295 +public ByteVector putByteArray(final byte[] b, final int off, final int len){ 1.296 + if(length + len > data.length) 1.297 + { 1.298 + enlarge(len); 1.299 + } 1.300 + if(b != null) 1.301 + { 1.302 + System.arraycopy(b, off, data, length, len); 1.303 + } 1.304 + length += len; 1.305 + return this; 1.306 +} 1.307 + 1.308 +/** 1.309 + * Enlarge this byte vector so that it can receive n more bytes. 1.310 + * 1.311 + * @param size number of additional bytes that this byte vector should be 1.312 + * able to receive. 1.313 + */ 1.314 +private void enlarge(final int size){ 1.315 + int length1 = 2 * data.length; 1.316 + int length2 = length + size; 1.317 + byte[] newData = new byte[length1 > length2 ? length1 : length2]; 1.318 + System.arraycopy(data, 0, newData, 0, length); 1.319 + data = newData; 1.320 +} 1.321 +}