java2.util2.zip2.ZipOutputStream: 90.84%

Overview

Search Parameters

EvoSuite Parameters

Old Parameters

Statistics

Test suite

Test case 1

  1: String var0 = "q5\u0016\u001F&\u001E";
  2: ByteArrayOutputStream var1 = new java.io.ByteArrayOutputStream();
  3: ZipOutputStream var2 = new java2.util2.zip2.ZipOutputStream(var1);
  4: int var3 = -1054;
  5: var2.setComment(var0);
  6: byte[] var5 = var1.toByteArray();
  7: byte var6 = -32;
  8: try {
  9:   var2.write(var5, var6, var3);
 10: } catch(IndexOutOfBoundsException e) {}
 11: ZipEntry var8 = new java2.util2.zip2.ZipEntry(var0);
 12: var2.putNextEntry(var8);
 13: try {
 14:   var2.putNextEntry(var8);
 15: } catch(ZipException e) {}
 16: var8.setComment(var0);
 17: var2.close();

Test case 2

  1: int var0 = 32;
  2: ByteArrayOutputStream var1 = new java.io.ByteArrayOutputStream(var0);
  3: ZipOutputStream var2 = new java2.util2.zip2.ZipOutputStream(var1);
  4: byte[] var3 = new byte[1];
  5: try {
  6:   var2.write(var3, var3[0], var0);
  7: } catch(IndexOutOfBoundsException e) {}
  8: try {
  9:   var2.finish();
 10: } catch(ZipException e) {}

Test case 3

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: byte[] var1 = var0.toByteArray();
  3: ZipOutputStream var2 = new java2.util2.zip2.ZipOutputStream(var0);
  4: String var3 = var0.toString();
  5: ZipEntry var4 = new java2.util2.zip2.ZipEntry(var3);
  6: var4.setExtra(var1);
  7: var2.putNextEntry(var4);
  8: var2.close();
  9: try {
 10:   var2.putNextEntry(var4);
 11: } catch(IOException e) {}
 12: var2.close();

Test case 4

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: ZipOutputStream var1 = new java2.util2.zip2.ZipOutputStream(var0);
  3: byte[] var2 = new byte[12];
  4: int var3 = -560;
  5: try {
  6:   var1.write(var2, var2[10], var3);
  7: } catch(IndexOutOfBoundsException e) {}

Test case 5

  1: String var0 = "STORED entry missing size, compressed size, or crc-32";
  2: int var1 = java2.util2.zip2.ZipOutputStream.getUTF8Length(var0);

Test case 6

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: int var1 = 3;
  3: var0.write(var1);
  4: String var3 = var0.toString(var1);
  5: int var4 = java2.util2.zip2.ZipOutputStream.getUTF8Length(var3);
  6: ZipOutputStream var5 = new java2.util2.zip2.ZipOutputStream(var0);
  7: ZipEntry var6 = new java2.util2.zip2.ZipEntry(var3);
  8: var5.putNextEntry(var6);

Test case 7

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: int var1 = -2;
  3: var0.write(var1);
  4: String var3 = var0.toString(var1);
  5: int var4 = java2.util2.zip2.ZipOutputStream.getUTF8Length(var3);

Test case 8

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: ZipOutputStream var1 = new java2.util2.zip2.ZipOutputStream(var0);
  3: String var2 = "[\u0004#";
  4: int var3 = 0;
  5: var1.setMethod(var3);
  6: ZipEntry var5 = new java2.util2.zip2.ZipEntry(var2);
  7: try {
  8:   var1.putNextEntry(var5);
  9: } catch(ZipException e) {}

Test case 9

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: ZipOutputStream var1 = new java2.util2.zip2.ZipOutputStream(var0);
  3: String var2 = "\u0004#";
  4: int var3 = 0;
  5: var1.setMethod(var3);
  6: ZipEntry var5 = new java2.util2.zip2.ZipEntry(var2);
  7: var5.setCompressedSize(var3);
  8: try {
  9:   var1.putNextEntry(var5);
 10: } catch(ZipException e) {}
 11: byte[] var8 = new byte[1];
 12: var1.closeEntry();
 13: try {
 14:   var1.write(var8);
 15: } catch(ZipException e) {}
 16: var1.setLevel(var3);
 17: var1.write(var8, var8[0], var8[0]);
 18: try {
 19:   var1.putNextEntry(var5);
 20: } catch(ZipException e) {}

Test case 10

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: int var1 = 43;
  3: var0.write(var1);
  4: String var3 = var0.toString(var1);
  5: byte[] var4 = new byte[14];
  6: ZipOutputStream var5 = new java2.util2.zip2.ZipOutputStream(var0);
  7: ZipEntry var6 = new java2.util2.zip2.ZipEntry(var3);
  8: var5.putNextEntry(var6);
  9: var6.setSize(var4[4]);
 10: var6.setMethod(var4[5]);
 11: try {
 12:   var5.close();
 13: } catch(ZipException e) {}

Test case 11

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: int var1 = -7;
  3: String var2 = var0.toString(var1);
  4: byte[] var3 = new byte[14];
  5: ZipOutputStream var4 = new java2.util2.zip2.ZipOutputStream(var0);
  6: ZipEntry var5 = new java2.util2.zip2.ZipEntry(var2);
  7: var4.putNextEntry(var5);
  8: var5.setMethod(var3[5]);
  9: try {
 10:   var4.write(var3[6]);
 11: } catch(ZipException e) {}

Test case 12

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: int var1 = 16;
  3: String var2 = var0.toString(var1);
  4: byte[] var3 = new byte[14];
  5: ZipOutputStream var4 = new java2.util2.zip2.ZipOutputStream(var0);
  6: ZipEntry var5 = new java2.util2.zip2.ZipEntry(var2);
  7: var4.putNextEntry(var5);
  8: var5.setMethod(var3[5]);
  9: try {
 10:   var4.close();
 11: } catch(ZipException e) {}
 12: String var9 = null;
 13: try {
 14:   var9 = var0.toString(var2);
 15: } catch(UnsupportedEncodingException e) {}
 16: var4.setComment(var9);

Test case 13

  1: int var0 = 8;
  2: ByteArrayOutputStream var1 = new java.io.ByteArrayOutputStream(var0);
  3: DeflaterOutputStream var2 = new java2.util2.zip2.DeflaterOutputStream(var1);
  4: ZipOutputStream var3 = new java2.util2.zip2.ZipOutputStream(var2);
  5: int var4 = 40;
  6: try {
  7:   var3.setMethod(var4);
  8: } catch(IllegalArgumentException e) {}
  9: var3.setMethod(var0);

Test case 14

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: ZipOutputStream var1 = new java2.util2.zip2.ZipOutputStream(var0);
  3: String var2 = "A\u001B_\u0001\u0001_\u0014TE\u0012\u000F72";
  4: ZipEntry var3 = new java2.util2.zip2.ZipEntry(var2);
  5: long var4 = 1L;
  6: var3.setSize(var4);
  7: var1.putNextEntry(var3);
  8: var1.finish();
  9: ZipOutputStream var8 = new java2.util2.zip2.ZipOutputStream(var0);
 10: var8.putNextEntry(var3);
 11: var8.closeEntry();

Test case 15

  1: ByteArrayOutputStream var0 = new java.io.ByteArrayOutputStream();
  2: ZipOutputStream var1 = new java2.util2.zip2.ZipOutputStream(var0);
  3: String var2 = "A\u001B_\u0001\u0001_\u0014TE\u0012<72";
  4: ZipEntry var3 = new java2.util2.zip2.ZipEntry(var2);
  5: var1.putNextEntry(var3);
  6: var1.finish();
  7: long var6 = 1368L;
  8: var3.setCrc(var6);
  9: var1.finish();
 10: ZipOutputStream var9 = new java2.util2.zip2.ZipOutputStream(var0);
 11: var9.putNextEntry(var3);
 12: try {
 13:   var9.closeEntry();
 14: } catch(ZipException e) {}

Source Code

  1: /*
  2:  * @(#)ZipOutputStream.java	1.36 10/03/23
  3:  *
  4:  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
  5:  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6:  */
  7: 
  8: package java2.util2.zip2;
  9: 
 10: import java.io.OutputStream;
 11: import java.io.IOException;
 12: import java.util.Vector;
 13: import java.util.HashSet;
 14: 
 15: import java.util.zip.ZipException;
 16: import java.util.zip.Deflater;
 17: import java.util.zip.CRC32;
 18: 
 19: /**
 20:  * This class implements an output stream filter for writing files in the
 21:  * ZIP file format. Includes support for both compressed and uncompressed
 22:  * entries.
 23:  *
 24:  * @author	David Connelly
 25:  * @version	1.36, 03/23/10
 26:  */
 27: public
 28: class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
 29: 
 30:     private static class XEntry {
 31: 	public final ZipEntry entry;
 32: 	public final long offset;
 33: 	public final int flag;
 34: 	public XEntry(ZipEntry entry, long offset) {
 35: 	    this.entry = entry;
 36: 	    this.offset = offset;
 37: 	    this.flag = (entry.method == DEFLATED &&
 38: 			 (entry.size  == -1 ||
 39: 			  entry.csize == -1 ||
 40: 			  entry.crc   == -1))
 41: 		// store size, compressed size, and crc-32 in data descriptor
 42: 		// immediately following the compressed entry data
 43: 		? 8
 44: 		// store size, compressed size, and crc-32 in LOC header
 45: 		: 0;
 46: 	}
 47:     }
 48: 
 49:     private XEntry current;
 50:     private Vector<XEntry> xentries = new Vector<XEntry>();
 51:     private HashSet<String> names = new HashSet<String>();
 52:     private CRC32 crc = new CRC32();
 53:     private long written = 0;
 54:     private long locoff = 0;
 55:     private String comment;
 56:     private int method = DEFLATED;
 57:     private boolean finished;
 58: 
 59:     private boolean closed = false;
 60: 
 61:     private static int version(ZipEntry e) throws ZipException {
 62: 	switch (e.method) {
 63: 	case DEFLATED: return 20;
 64: 	case STORED:   return 10;
 65: 	default: throw new ZipException("unsupported compression method");
 66: 	}
 67:     }
 68: 
 69:     /**
 70:      * Checks to make sure that this stream has not been closed.
 71:      */
 72:     private void ensureOpen() throws IOException {
 73: 	if (closed) {
 74: 	    throw new IOException("Stream closed");
 75:         }
 76:     }
 77:     /**
 78:      * Compression method for uncompressed (STORED) entries.
 79:      */
 80:     public static final int STORED = ZipEntry.STORED;
 81: 
 82:     /**
 83:      * Compression method for compressed (DEFLATED) entries.
 84:      */
 85:     public static final int DEFLATED = ZipEntry.DEFLATED;
 86: 
 87:     /**
 88:      * Creates a new ZIP output stream.
 89:      * @param out the actual output stream
 90:      */
 91:     public ZipOutputStream(OutputStream out) {
 92: 	super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
 93:         usesDefaultDeflater = true;
 94:     }
 95: 
 96:     /**
 97:      * Sets the ZIP file comment.
 98:      * @param comment the comment string
 99:      * @exception IllegalArgumentException if the length of the specified
100:      *		  ZIP file comment is greater than 0xFFFF bytes
101:      */
102:     public void setComment(String comment) {
103:         if (comment != null && comment.length() > 0xffff/3
104:                                            && getUTF8Length(comment) > 0xffff) {
105: 	    throw new IllegalArgumentException("ZIP file comment too long.");
106: 	}
107: 	this.comment = comment;
108:     }
109: 
110:     /**
111:      * Sets the default compression method for subsequent entries. This
112:      * default will be used whenever the compression method is not specified
113:      * for an individual ZIP file entry, and is initially set to DEFLATED.
114:      * @param method the default compression method
115:      * @exception IllegalArgumentException if the specified compression method
116:      *		  is invalid
117:      */
118:     public void setMethod(int method) {
119: 	if (method != DEFLATED && method != STORED) {
120: 	    throw new IllegalArgumentException("invalid compression method");
121: 	}
122: 	this.method = method;
123:     }
124: 
125:     /**
126:      * Sets the compression level for subsequent entries which are DEFLATED.
127:      * The default setting is DEFAULT_COMPRESSION.
128:      * @param level the compression level (0-9)
129:      * @exception IllegalArgumentException if the compression level is invalid
130:      */
131:     public void setLevel(int level) {
132: 	def.setLevel(level);
133:     }
134: 
135:     /**
136:      * Begins writing a new ZIP file entry and positions the stream to the
137:      * start of the entry data. Closes the current entry if still active.
138:      * The default compression method will be used if no compression method
139:      * was specified for the entry, and the current time will be used if
140:      * the entry has no set modification time.
141:      * @param e the ZIP entry to be written
142:      * @exception ZipException if a ZIP format error has occurred
143:      * @exception IOException if an I/O error has occurred
144:      */
145:     public void putNextEntry(ZipEntry e) throws IOException {
146: 	ensureOpen();
147: 	if (current != null) {
148: 	    closeEntry();	// close previous entry
149: 	}
150: 	if (e.time == -1) {
151: 	    e.setTime(System.currentTimeMillis());
152: 	}
153: 	if (e.method == -1) {
154: 	    e.method = method;	// use default method
155: 	}
156: 	switch (e.method) {
157: 	case DEFLATED:
158: 	    break;
159: 	case STORED:
160: 	    // compressed size, uncompressed size, and crc-32 must all be
161: 	    // set for entries using STORED compression method
162: 	    if (e.size == -1) {
163: 		e.size = e.csize;
164: 	    } else if (e.csize == -1) {
165: 		e.csize = e.size;
166: 	    } else if (e.size != e.csize) {
167: 		throw new ZipException(
168: 		    "STORED entry where compressed != uncompressed size");
169: 	    }
170: 	    if (e.size == -1 || e.crc == -1) {
171: 		throw new ZipException(
172: 		    "STORED entry missing size, compressed size, or crc-32");
173: 	    }
174: 	    break;
175: 	default:
176: 	    throw new ZipException("unsupported compression method");
177: 	}
178: 	if (! names.add(e.name)) {
179: 	    throw new ZipException("duplicate entry: " + e.name);
180: 	}
181: 	current = new XEntry(e, written);
182: 	xentries.add(current);
183:         writeLOC(current);
184:     }
185: 
186:     /**
187:      * Closes the current ZIP entry and positions the stream for writing
188:      * the next entry.
189:      * @exception ZipException if a ZIP format error has occurred
190:      * @exception IOException if an I/O error has occurred
191:      */
192:     public void closeEntry() throws IOException {
193: 	ensureOpen();
194: 	if (current != null) {
195: 	    ZipEntry e = current.entry;
196: 	    switch (e.method) {
197: 	    case DEFLATED:
198: 		def.finish();
199: 		while (!def.finished()) {
200: 		    deflate();
201: 		}
202: 		if ((current.flag & 8) == 0) {
203: 		    // verify size, compressed size, and crc-32 settings
204: 		    if (e.size != def.getBytesRead()) {
205: 			throw new ZipException(
206: 			    "invalid entry size (expected " + e.size +
207: 			    " but got " + def.getBytesRead() + " bytes)");
208: 		    }
209: 		    if (e.csize != def.getBytesWritten()) {
210: 			throw new ZipException(
211: 			    "invalid entry compressed size (expected " +
212: 			    e.csize + " but got " + def.getBytesWritten() + " bytes)");
213: 		    }
214: 		    if (e.crc != crc.getValue()) {
215: 			throw new ZipException(
216: 			    "invalid entry CRC-32 (expected 0x" +
217: 			    Long.toHexString(e.crc) + " but got 0x" +
218: 			    Long.toHexString(crc.getValue()) + ")");
219: 		    }
220: 		} else {
221: 		    e.size  = def.getBytesRead();
222: 		    e.csize = def.getBytesWritten();
223: 		    e.crc = crc.getValue();
224: 		    writeEXT(e);
225: 		}
226: 		def.reset();
227: 		written += e.csize;
228: 		break;
229: 	    case STORED:
230: 		// we already know that both e.size and e.csize are the same
231: 		if (e.size != written - locoff) {
232: 		    throw new ZipException(
233: 			"invalid entry size (expected " + e.size +
234: 			" but got " + (written - locoff) + " bytes)");
235: 		}
236: 		if (e.crc != crc.getValue()) {
237: 		    throw new ZipException(
238: 			 "invalid entry crc-32 (expected 0x" +
239: 			 Long.toHexString(e.crc) + " but got 0x" +
240: 			 Long.toHexString(crc.getValue()) + ")");
241: 		}
242: 		break;
243: 	    default:
244: 		throw new ZipException("invalid compression method");
245: 	    }
246: 	    crc.reset();
247: 	    current = null;
248: 	}
249:     }
250: 
251:     /**
252:      * Writes an array of bytes to the current ZIP entry data. This method
253:      * will block until all the bytes are written.
254:      * @param b the data to be written
255:      * @param off the start offset in the data
256:      * @param len the number of bytes that are written
257:      * @exception ZipException if a ZIP file error has occurred
258:      * @exception IOException if an I/O error has occurred
259:      */
260:     public synchronized void write(byte[] b, int off, int len)
261: 	throws IOException
262:     {
263: 	ensureOpen();
264:         if (off < 0 || len < 0 || off > b.length - len) {
265: 	    throw new IndexOutOfBoundsException();
266: 	} else if (len == 0) {
267: 	    return;
268: 	}
269: 
270: 	if (current == null) {
271: 	    throw new ZipException("no current ZIP entry");
272: 	}
273: 	ZipEntry entry = current.entry;
274: 	switch (entry.method) {
275: 	case DEFLATED:
276: 	    super.write(b, off, len);
277: 	    break;
278: 	case STORED:
279: 	    written += len;
280: 	    if (written - locoff > entry.size) {
281: 		throw new ZipException(
282: 		    "attempt to write past end of STORED entry");
283: 	    }
284: 	    out.write(b, off, len);
285: 	    break;
286: 	default:
287: 	    throw new ZipException("invalid compression method");
288: 	}
289: 	crc.update(b, off, len);
290:     }
291: 
292:     /**
293:      * Finishes writing the contents of the ZIP output stream without closing
294:      * the underlying stream. Use this method when applying multiple filters
295:      * in succession to the same output stream.
296:      * @exception ZipException if a ZIP file error has occurred
297:      * @exception IOException if an I/O exception has occurred
298:      */
299:     public void finish() throws IOException {
300: 	ensureOpen();
301: 	if (finished) {
302: 	    return;
303: 	}
304: 	if (current != null) {
305: 	    closeEntry();
306: 	}
307: 	if (xentries.size() < 1) {
308: 	    throw new ZipException("ZIP file must have at least one entry");
309: 	}
310: 	// write central directory
311: 	long off = written;
312: 	for (XEntry xentry : xentries)
313: 	    writeCEN(xentry);
314: 	writeEND(off, written - off);
315: 	finished = true;
316:     }
317: 
318:     /**
319:      * Closes the ZIP output stream as well as the stream being filtered.
320:      * @exception ZipException if a ZIP file error has occurred
321:      * @exception IOException if an I/O error has occurred
322:      */
323:     public void close() throws IOException {
324:         if (!closed) {
325:             super.close();
326:             closed = true;
327:         }
328:     }
329: 
330:     /*
331:      * Writes local file (LOC) header for specified entry.
332:      */
333:     private void writeLOC(XEntry xentry) throws IOException {
334: 	ZipEntry e = xentry.entry;
335: 	int flag = xentry.flag;
336: 	writeInt(LOCSIG);	    // LOC header signature
337: 	writeShort(version(e));     // version needed to extract
338: 	writeShort(flag);           // general purpose bit flag
339: 	writeShort(e.method);       // compression method
340: 	writeInt(e.time);           // last modification time
341: 	if ((flag & 8) == 8) {
342: 	    // store size, uncompressed size, and crc-32 in data descriptor
343: 	    // immediately following compressed entry data
344: 	    writeInt(0);
345: 	    writeInt(0);
346: 	    writeInt(0);
347: 	} else {
348: 	    writeInt(e.crc);        // crc-32
349: 	    writeInt(e.csize);      // compressed size
350: 	    writeInt(e.size);       // uncompressed size
351: 	}
352: 	byte[] nameBytes = getUTF8Bytes(e.name);
353: 	writeShort(nameBytes.length);
354: 	writeShort(e.extra != null ? e.extra.length : 0);
355: 	writeBytes(nameBytes, 0, nameBytes.length);
356: 	if (e.extra != null) {
357: 	    writeBytes(e.extra, 0, e.extra.length);
358: 	}
359: 	locoff = written;
360:     }
361: 
362:     /*
363:      * Writes extra data descriptor (EXT) for specified entry.
364:      */
365:     private void writeEXT(ZipEntry e) throws IOException {
366: 	writeInt(EXTSIG);	    // EXT header signature
367: 	writeInt(e.crc);	    // crc-32
368: 	writeInt(e.csize);	    // compressed size
369: 	writeInt(e.size);	    // uncompressed size
370:     }
371: 
372:     /*
373:      * Write central directory (CEN) header for specified entry.
374:      * REMIND: add support for file attributes
375:      */
376:     private void writeCEN(XEntry xentry) throws IOException {
377: 	ZipEntry e  = xentry.entry;
378: 	int flag = xentry.flag;
379: 	int version = version(e);
380: 	writeInt(CENSIG);	    // CEN header signature
381: 	writeShort(version);	    // version made by
382: 	writeShort(version);	    // version needed to extract
383: 	writeShort(flag);	    // general purpose bit flag
384: 	writeShort(e.method);	    // compression method
385: 	writeInt(e.time);	    // last modification time
386: 	writeInt(e.crc);	    // crc-32
387: 	writeInt(e.csize);	    // compressed size
388: 	writeInt(e.size);	    // uncompressed size
389: 	byte[] nameBytes = getUTF8Bytes(e.name);
390: 	writeShort(nameBytes.length);
391: 	writeShort(e.extra != null ? e.extra.length : 0);
392: 	byte[] commentBytes;
393: 	if (e.comment != null) {
394: 	    commentBytes = getUTF8Bytes(e.comment);
395: 	    writeShort(commentBytes.length);
396: 	} else {
397: 	    commentBytes = null;
398: 	    writeShort(0);
399: 	}
400: 	writeShort(0);		    // starting disk number
401: 	writeShort(0);		    // internal file attributes (unused)
402: 	writeInt(0);		    // external file attributes (unused)
403: 	writeInt(xentry.offset);    // relative offset of local header
404: 	writeBytes(nameBytes, 0, nameBytes.length);
405: 	if (e.extra != null) {
406: 	    writeBytes(e.extra, 0, e.extra.length);
407: 	}
408: 	if (commentBytes != null) {
409: 	    writeBytes(commentBytes, 0, commentBytes.length);
410: 	}
411:     }
412: 
413:     /*
414:      * Writes end of central directory (END) header.
415:      */
416:     private void writeEND(long off, long len) throws IOException {
417: 	int count = xentries.size();
418: 	writeInt(ENDSIG);	    // END record signature
419: 	writeShort(0);		    // number of this disk
420: 	writeShort(0);		    // central directory start disk
421: 	writeShort(count);	    // number of directory entries on disk
422: 	writeShort(count);	    // total number of directory entries
423: 	writeInt(len);		    // length of central directory
424: 	writeInt(off);		    // offset of central directory
425: 	if (comment != null) {	    // zip file comment
426: 	    byte[] b = getUTF8Bytes(comment);
427: 	    writeShort(b.length);
428: 	    writeBytes(b, 0, b.length);
429: 	} else {
430: 	    writeShort(0);
431: 	}
432:     }
433: 
434:     /*
435:      * Writes a 16-bit short to the output stream in little-endian byte order.
436:      */
437:     private void writeShort(int v) throws IOException {
438: 	OutputStream out = this.out;
439: 	out.write((v >>> 0) & 0xff);
440: 	out.write((v >>> 8) & 0xff);
441: 	written += 2;
442:     }
443: 
444:     /*
445:      * Writes a 32-bit int to the output stream in little-endian byte order.
446:      */
447:     private void writeInt(long v) throws IOException {
448: 	OutputStream out = this.out;
449: 	out.write((int)((v >>>  0) & 0xff));
450: 	out.write((int)((v >>>  8) & 0xff));
451: 	out.write((int)((v >>> 16) & 0xff));
452: 	out.write((int)((v >>> 24) & 0xff));
453: 	written += 4;
454:     }
455: 
456:     /*
457:      * Writes an array of bytes to the output stream.
458:      */
459:     private void writeBytes(byte[] b, int off, int len) throws IOException {
460: 	super.out.write(b, off, len);
461: 	written += len;
462:     }
463: 
464:     /*
465:      * Returns the length of String's UTF8 encoding.
466:      */
467:     static int getUTF8Length(String s) {
468:         int count = 0;
469:         for (int i = 0; i < s.length(); i++) {
470:             char ch = s.charAt(i);
471:             if (ch <= 0x7f) {
472:                 count++;
473:             } else if (ch <= 0x7ff) {
474:                 count += 2;
475:             } else {
476:                 count += 3;
477:             }
478:         }
479:         return count;
480:     }
481: 
482:     /*
483:      * Returns an array of bytes representing the UTF8 encoding
484:      * of the specified String.
485:      */
486:     private static byte[] getUTF8Bytes(String s) {
487: 	char[] c = s.toCharArray();
488: 	int len = c.length;
489: 	// Count the number of encoded bytes...
490: 	int count = 0;
491: 	for (int i = 0; i < len; i++) {
492: 	    int ch = c[i];
493: 	    if (ch <= 0x7f) {
494: 		count++;
495: 	    } else if (ch <= 0x7ff) {
496: 		count += 2;
497: 	    } else {
498: 		count += 3;
499: 	    }
500: 	}
501: 	// Now return the encoded bytes...
502: 	byte[] b = new byte[count];
503: 	int off = 0;
504: 	for (int i = 0; i < len; i++) {
505: 	    int ch = c[i];
506: 	    if (ch <= 0x7f) {
507: 		b[off++] = (byte)ch;
508: 	    } else if (ch <= 0x7ff) {
509: 		b[off++] = (byte)((ch >> 6) | 0xc0);
510: 		b[off++] = (byte)((ch & 0x3f) | 0x80);
511: 	    } else {
512: 		b[off++] = (byte)((ch >> 12) | 0xe0);
513: 		b[off++] = (byte)(((ch >> 6) & 0x3f) | 0x80);
514: 		b[off++] = (byte)((ch & 0x3f) | 0x80);
515: 	    }
516: 	}
517: 	return b;
518:     }
519: }