1 /*
   2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.util;
  27 
  28 import java.io.*;
  29 
  30 /** A byte buffer is a flexible array which grows when elements are
  31  *  appended. There are also methods to append names to byte buffers
  32  *  and to convert byte buffers to names.
  33  *
  34  *  <p><b>This is NOT part of any supported API.
  35  *  If you write code that depends on this, you do so at your own risk.
  36  *  This code and its internal interfaces are subject to change or
  37  *  deletion without notice.</b>
  38  */
  39 public class ByteBuffer {
  40 
  41     /** An array holding the bytes in this buffer; can be grown.
  42      */
  43     public byte[] elems;
  44 
  45     /** The current number of defined bytes in this buffer.
  46      */
  47     public int length;
  48 
  49     /** Create a new byte buffer.
  50      */
  51     public ByteBuffer() {
  52         this(64);
  53     }
  54 
  55     /** Create a new byte buffer with an initial elements array
  56      *  of given size.
  57      */
  58     public ByteBuffer(int initialSize) {
  59         elems = new byte[initialSize];
  60         length = 0;
  61     }
  62 
  63     /** Append byte to this buffer.
  64      */
  65     public void appendByte(int b) {
  66         elems = ArrayUtils.ensureCapacity(elems, length);
  67         elems[length++] = (byte)b;
  68     }
  69 
  70     /** Append `len' bytes from byte array,
  71      *  starting at given `start' offset.
  72      */
  73     public void appendBytes(byte[] bs, int start, int len) {
  74         elems = ArrayUtils.ensureCapacity(elems, length + len);
  75         System.arraycopy(bs, start, elems, length, len);
  76         length += len;
  77     }
  78 
  79     /** Append all bytes from given byte array.
  80      */
  81     public void appendBytes(byte[] bs) {
  82         appendBytes(bs, 0, bs.length);
  83     }
  84 
  85     /** Append a character as a two byte number.
  86      */
  87     public void appendChar(int x) {
  88         elems = ArrayUtils.ensureCapacity(elems, length + 1);
  89         elems[length  ] = (byte)((x >>  8) & 0xFF);
  90         elems[length+1] = (byte)((x      ) & 0xFF);
  91         length = length + 2;
  92     }
  93 
  94     /** Append an integer as a four byte number.
  95      */
  96     public void appendInt(int x) {
  97         elems = ArrayUtils.ensureCapacity(elems, length + 3);
  98         elems[length  ] = (byte)((x >> 24) & 0xFF);
  99         elems[length+1] = (byte)((x >> 16) & 0xFF);
 100         elems[length+2] = (byte)((x >>  8) & 0xFF);
 101         elems[length+3] = (byte)((x      ) & 0xFF);
 102         length = length + 4;
 103     }
 104 
 105     /** Append a long as an eight byte number.
 106      */
 107     public void appendLong(long x) {
 108         ByteArrayOutputStream buffer = new ByteArrayOutputStream(8);
 109         DataOutputStream bufout = new DataOutputStream(buffer);
 110         try {
 111             bufout.writeLong(x);
 112             appendBytes(buffer.toByteArray(), 0, 8);
 113         } catch (IOException e) {
 114             throw new AssertionError("write");
 115         }
 116     }
 117 
 118     /** Append a float as a four byte number.
 119      */
 120     public void appendFloat(float x) {
 121         ByteArrayOutputStream buffer = new ByteArrayOutputStream(4);
 122         DataOutputStream bufout = new DataOutputStream(buffer);
 123         try {
 124             bufout.writeFloat(x);
 125             appendBytes(buffer.toByteArray(), 0, 4);
 126         } catch (IOException e) {
 127             throw new AssertionError("write");
 128         }
 129     }
 130 
 131     /** Append a double as a eight byte number.
 132      */
 133     public void appendDouble(double x) {
 134         ByteArrayOutputStream buffer = new ByteArrayOutputStream(8);
 135         DataOutputStream bufout = new DataOutputStream(buffer);
 136         try {
 137             bufout.writeDouble(x);
 138             appendBytes(buffer.toByteArray(), 0, 8);
 139         } catch (IOException e) {
 140             throw new AssertionError("write");
 141         }
 142     }
 143 
 144     /** Append a name.
 145      */
 146     public void appendName(Name name) {
 147         appendBytes(name.getByteArray(), name.getByteOffset(), name.getByteLength());
 148     }
 149 
 150     /** Reset to zero length.
 151      */
 152     public void reset() {
 153         length = 0;
 154     }
 155 
 156     /** Convert contents to name.
 157      */
 158     public Name toName(Names names) {
 159         return names.fromUtf(elems, 0, length);
 160     }
 161 }