001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.util;
021
022 import org.apache.directory.shared.i18n.I18n;
023
024
025 /**
026 * A dynamically growing byte[].
027 *
028 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
029 * @version $Rev$
030 */
031 public class ByteBuffer
032 {
033 /** the default initial buffer size */
034 private static final int DEFAULT_INITIAL_SIZE = 10;
035
036 /** the initial size of the buffer in number of bytes: also increment for allocations */
037 private final int initialSize;
038 /** the position into the buffer */
039 private int pos = 0;
040 /** the bytes of the buffer */
041 private byte[] buf;
042
043
044 public ByteBuffer()
045 {
046 this ( DEFAULT_INITIAL_SIZE );
047 }
048
049
050 public ByteBuffer( int initialSize )
051 {
052 if ( initialSize <= 0 )
053 {
054 throw new IllegalArgumentException( I18n.err( I18n.ERR_04354 ) );
055 }
056 this.initialSize = initialSize;
057 this.buf = new byte[initialSize];
058 }
059
060
061 public final void clear()
062 {
063 pos = 0;
064 }
065
066
067 public final int position()
068 {
069 return pos;
070 }
071
072
073 public final int capacity()
074 {
075 return buf.length;
076 }
077
078
079 public final byte get( int ii )
080 {
081 return buf[ii];
082 }
083
084
085 /**
086 * Get's the bytes, the backing store for this buffer. Note
087 * that you need to use the position index to determine where
088 * to stop reading from this buffer.
089 */
090 public final byte[] buffer()
091 {
092 return buf;
093 }
094
095
096 /**
097 * Get's a copy of the bytes used.
098 */
099 public final byte[] copyOfUsedBytes()
100 {
101 byte[] copy = new byte[pos];
102 System.arraycopy( buf, 0, copy, 0, pos );
103 return copy;
104 }
105
106
107 /**
108 * Appends the bytes to this buffer.
109 */
110 public final void append( byte[] bytes )
111 {
112 for ( byte b : bytes )
113 {
114 append( b );
115 }
116 }
117
118
119 /**
120 * Appends a byte to this buffer.
121 */
122 public final void append( byte bite )
123 {
124 if ( pos >= buf.length )
125 {
126 growBuffer();
127 }
128
129 buf[pos] = bite;
130 pos++;
131 }
132
133
134 /**
135 * Appends an int to this buffer. WARNING: the int is truncated to
136 * a byte value.
137 */
138 public final void append( int val )
139 {
140 if ( pos >= buf.length )
141 {
142 growBuffer();
143 }
144
145 buf[pos] = ( byte ) val;
146 pos++;
147 }
148
149
150 private final void growBuffer()
151 {
152 byte[] copy = new byte[buf.length+initialSize];
153 System.arraycopy( buf, 0, copy, 0, pos );
154 this.buf = copy;
155 }
156 }