View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.util;
21  
22  
23  import org.apache.directory.api.i18n.I18n;
24  
25  
26  /**
27   * A dynamically growing byte[]. 
28   *
29   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
30   */
31  public class ByteBuffer
32  {
33      /** the default initial buffer size */
34      private static final int DEFAULT_INITIAL_SIZE = 10;
35  
36      /** the initial size of the buffer in number of bytes: also increment for allocations */
37      private final int initialSize;
38  
39      /** the position into the buffer */
40      private int pos = 0;
41  
42      /** the bytes of the buffer */
43      private byte[] buf;
44  
45  
46      public ByteBuffer()
47      {
48          this( DEFAULT_INITIAL_SIZE );
49      }
50  
51  
52      public ByteBuffer( int initialSize )
53      {
54          if ( initialSize <= 0 )
55          {
56              throw new IllegalArgumentException( I18n.err( I18n.ERR_04354 ) );
57          }
58  
59          this.initialSize = initialSize;
60          this.buf = new byte[initialSize];
61      }
62  
63  
64      public final void clear()
65      {
66          pos = 0;
67      }
68  
69  
70      public final int position()
71      {
72          return pos;
73      }
74  
75  
76      public final int capacity()
77      {
78          return buf.length;
79      }
80  
81  
82      public final byte get( int i )
83      {
84          return buf[i];
85      }
86  
87  
88      /**
89       * Get's the bytes, the backing store for this buffer.  Note
90       * that you need to use the position index to determine where
91       * to stop reading from this buffer.
92       */
93      public final byte[] buffer()
94      {
95          return buf;
96      }
97  
98  
99      /**
100      * Get's a copy of the bytes used.
101      */
102     public final byte[] copyOfUsedBytes()
103     {
104         byte[] copy = new byte[pos];
105         System.arraycopy( buf, 0, copy, 0, pos );
106         return copy;
107     }
108 
109 
110     /**
111      * Appends the bytes to this buffer.
112      */
113     public final void append( byte[] bytes )
114     {
115         if ( pos + bytes.length > buf.length )
116         {
117             growBuffer( bytes.length );
118         }
119 
120         System.arraycopy( bytes, 0, buf, pos, bytes.length );
121         pos += bytes.length;
122     }
123 
124 
125     /**
126      * Appends a byte to this buffer.
127      */
128     public final void append( byte b )
129     {
130         if ( pos >= buf.length )
131         {
132             growBuffer();
133         }
134 
135         buf[pos] = b;
136         pos++;
137     }
138 
139 
140     /**
141      * Appends an int to this buffer.  WARNING: the int is truncated to 
142      * a byte value.
143      */
144     public final void append( int val )
145     {
146         if ( pos >= buf.length )
147         {
148             growBuffer();
149         }
150 
151         buf[pos] = ( byte ) val;
152         pos++;
153     }
154 
155 
156     private void growBuffer( int size )
157     {
158         if ( size > initialSize )
159         {
160             byte[] copy = new byte[buf.length + size];
161             System.arraycopy( buf, 0, copy, 0, pos );
162             this.buf = copy;
163         }
164         else
165         {
166             byte[] copy = new byte[buf.length + initialSize];
167             System.arraycopy( buf, 0, copy, 0, pos );
168             this.buf = copy;
169         }
170     }
171 
172 
173     private void growBuffer()
174     {
175         byte[] copy = new byte[buf.length + initialSize];
176         System.arraycopy( buf, 0, copy, 0, pos );
177         this.buf = copy;
178     }
179 }