Mercurial > lasercutter
view 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 source
1 /***2 * ASM: a very small and fast Java bytecode manipulation framework3 * Copyright (c) 2000-2005 INRIA, France Telecom4 * All rights reserved.5 *6 * Redistribution and use in source and binary forms, with or without7 * modification, are permitted provided that the following conditions8 * are met:9 * 1. Redistributions of source code must retain the above copyright10 * notice, this list of conditions and the following disclaimer.11 * 2. Redistributions in binary form must reproduce the above copyright12 * notice, this list of conditions and the following disclaimer in the13 * documentation and/or other materials provided with the distribution.14 * 3. Neither the name of the copyright holders nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF28 * THE POSSIBILITY OF SUCH DAMAGE.29 */30 package clojure.asm;32 /**33 * A dynamically extensible vector of bytes. This class is roughly equivalent to34 * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.35 *36 * @author Eric Bruneton37 */38 public class ByteVector{40 /**41 * The content of this vector.42 */43 byte[] data;45 /**46 * Actual number of bytes in this vector.47 */48 int length;50 /**51 * Constructs a new {@link ByteVector ByteVector} with a default initial52 * size.53 */54 public ByteVector(){55 data = new byte[64];56 }58 /**59 * Constructs a new {@link ByteVector ByteVector} with the given initial60 * size.61 *62 * @param initialSize the initial size of the byte vector to be constructed.63 */64 public ByteVector(final int initialSize){65 data = new byte[initialSize];66 }68 /**69 * Puts a byte into this byte vector. The byte vector is automatically70 * enlarged if necessary.71 *72 * @param b a byte.73 * @return this byte vector.74 */75 public ByteVector putByte(final int b){76 int length = this.length;77 if(length + 1 > data.length)78 {79 enlarge(1);80 }81 data[length++] = (byte) b;82 this.length = length;83 return this;84 }86 /**87 * Puts two bytes into this byte vector. The byte vector is automatically88 * enlarged if necessary.89 *90 * @param b1 a byte.91 * @param b2 another byte.92 * @return this byte vector.93 */94 ByteVector put11(final int b1, final int b2){95 int length = this.length;96 if(length + 2 > data.length)97 {98 enlarge(2);99 }100 byte[] data = this.data;101 data[length++] = (byte) b1;102 data[length++] = (byte) b2;103 this.length = length;104 return this;105 }107 /**108 * Puts a short into this byte vector. The byte vector is automatically109 * enlarged if necessary.110 *111 * @param s a short.112 * @return this byte vector.113 */114 public ByteVector putShort(final int s){115 int length = this.length;116 if(length + 2 > data.length)117 {118 enlarge(2);119 }120 byte[] data = this.data;121 data[length++] = (byte) (s >>> 8);122 data[length++] = (byte) s;123 this.length = length;124 return this;125 }127 /**128 * Puts a byte and a short into this byte vector. The byte vector is129 * automatically enlarged if necessary.130 *131 * @param b a byte.132 * @param s a short.133 * @return this byte vector.134 */135 ByteVector put12(final int b, final int s){136 int length = this.length;137 if(length + 3 > data.length)138 {139 enlarge(3);140 }141 byte[] data = this.data;142 data[length++] = (byte) b;143 data[length++] = (byte) (s >>> 8);144 data[length++] = (byte) s;145 this.length = length;146 return this;147 }149 /**150 * Puts an int into this byte vector. The byte vector is automatically151 * enlarged if necessary.152 *153 * @param i an int.154 * @return this byte vector.155 */156 public ByteVector putInt(final int i){157 int length = this.length;158 if(length + 4 > data.length)159 {160 enlarge(4);161 }162 byte[] data = this.data;163 data[length++] = (byte) (i >>> 24);164 data[length++] = (byte) (i >>> 16);165 data[length++] = (byte) (i >>> 8);166 data[length++] = (byte) i;167 this.length = length;168 return this;169 }171 /**172 * Puts a long into this byte vector. The byte vector is automatically173 * enlarged if necessary.174 *175 * @param l a long.176 * @return this byte vector.177 */178 public ByteVector putLong(final long l){179 int length = this.length;180 if(length + 8 > data.length)181 {182 enlarge(8);183 }184 byte[] data = this.data;185 int i = (int) (l >>> 32);186 data[length++] = (byte) (i >>> 24);187 data[length++] = (byte) (i >>> 16);188 data[length++] = (byte) (i >>> 8);189 data[length++] = (byte) i;190 i = (int) l;191 data[length++] = (byte) (i >>> 24);192 data[length++] = (byte) (i >>> 16);193 data[length++] = (byte) (i >>> 8);194 data[length++] = (byte) i;195 this.length = length;196 return this;197 }199 /**200 * Puts an UTF8 string into this byte vector. The byte vector is201 * automatically enlarged if necessary.202 *203 * @param s a String.204 * @return this byte vector.205 */206 public ByteVector putUTF8(final String s){207 int charLength = s.length();208 if(length + 2 + charLength > data.length)209 {210 enlarge(2 + charLength);211 }212 int len = length;213 byte[] data = this.data;214 // optimistic algorithm: instead of computing the byte length and then215 // serializing the string (which requires two loops), we assume the byte216 // length is equal to char length (which is the most frequent case), and217 // we start serializing the string right away. During the serialization,218 // if we find that this assumption is wrong, we continue with the219 // general method.220 data[len++] = (byte) (charLength >>> 8);221 data[len++] = (byte) charLength;222 for(int i = 0; i < charLength; ++i)223 {224 char c = s.charAt(i);225 if(c >= '\001' && c <= '\177')226 {227 data[len++] = (byte) c;228 }229 else230 {231 int byteLength = i;232 for(int j = i; j < charLength; ++j)233 {234 c = s.charAt(j);235 if(c >= '\001' && c <= '\177')236 {237 byteLength++;238 }239 else if(c > '\u07FF')240 {241 byteLength += 3;242 }243 else244 {245 byteLength += 2;246 }247 }248 data[length] = (byte) (byteLength >>> 8);249 data[length + 1] = (byte) byteLength;250 if(length + 2 + byteLength > data.length)251 {252 length = len;253 enlarge(2 + byteLength);254 data = this.data;255 }256 for(int j = i; j < charLength; ++j)257 {258 c = s.charAt(j);259 if(c >= '\001' && c <= '\177')260 {261 data[len++] = (byte) c;262 }263 else if(c > '\u07FF')264 {265 data[len++] = (byte) (0xE0 | c >> 12 & 0xF);266 data[len++] = (byte) (0x80 | c >> 6 & 0x3F);267 data[len++] = (byte) (0x80 | c & 0x3F);268 }269 else270 {271 data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);272 data[len++] = (byte) (0x80 | c & 0x3F);273 }274 }275 break;276 }277 }278 length = len;279 return this;280 }282 /**283 * Puts an array of bytes into this byte vector. The byte vector is284 * automatically enlarged if necessary.285 *286 * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>287 * null bytes into this byte vector.288 * @param off index of the fist byte of b that must be copied.289 * @param len number of bytes of b that must be copied.290 * @return this byte vector.291 */292 public ByteVector putByteArray(final byte[] b, final int off, final int len){293 if(length + len > data.length)294 {295 enlarge(len);296 }297 if(b != null)298 {299 System.arraycopy(b, off, data, length, len);300 }301 length += len;302 return this;303 }305 /**306 * Enlarge this byte vector so that it can receive n more bytes.307 *308 * @param size number of additional bytes that this byte vector should be309 * able to receive.310 */311 private void enlarge(final int size){312 int length1 = 2 * data.length;313 int length2 = length + size;314 byte[] newData = new byte[length1 > length2 ? length1 : length2];315 System.arraycopy(data, 0, newData, 0, length);316 data = newData;317 }318 }