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 */ 020package org.apache.directory.api.util; 021 022 023import org.apache.directory.api.i18n.I18n; 024 025 026/** 027 * A dynamically growing byte[]. 028 * 029 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 030 */ 031public 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 039 /** the position into the buffer */ 040 private int pos = 0; 041 042 /** the bytes of the buffer */ 043 private byte[] buf; 044 045 /** 046 * Create a default ByteBuffer capable of holding 10 bytes 047 */ 048 public ByteBuffer() 049 { 050 this( DEFAULT_INITIAL_SIZE ); 051 } 052 053 054 /** 055 * Creates a ByteBuffer which has an initialze size 056 * 057 * @param initialSize The initial buffer size 058 */ 059 public ByteBuffer( int initialSize ) 060 { 061 if ( initialSize <= 0 ) 062 { 063 throw new IllegalArgumentException( I18n.err( I18n.ERR_04354 ) ); 064 } 065 066 this.initialSize = initialSize; 067 this.buf = new byte[initialSize]; 068 } 069 070 071 /** 072 * Reset the Buffer position to 0. Every new added byte will be put on position 0. 073 * Note that whatever this buffer contained before a call to the clear() method 074 * will not be removed. 075 */ 076 public final void clear() 077 { 078 pos = 0; 079 } 080 081 082 /** 083 * @return The current position in the buffer 084 */ 085 public final int position() 086 { 087 return pos; 088 } 089 090 091 /** 092 * @return The number of bytes that can be added into this buffer 093 */ 094 public final int capacity() 095 { 096 return buf.length; 097 } 098 099 100 /** 101 * Returns the byte at a given position. Note that no control is done 102 * on the position validity. 103 * 104 * @param i The position 105 * @return The byte at the given position in the buffer 106 */ 107 public final byte get( int i ) 108 { 109 return buf[i]; 110 } 111 112 113 /** 114 * Get's the bytes, the backing store for this buffer. Note 115 * that you need to use the position index to determine where 116 * to stop reading from this buffer. 117 * 118 * @return The interned Byte[] 119 */ 120 public final byte[] buffer() 121 { 122 return buf; 123 } 124 125 126 /** 127 * Get's a copy of the bytes used. 128 * 129 * @return A copy of the interned Byte[] 130 */ 131 public final byte[] copyOfUsedBytes() 132 { 133 byte[] copy = new byte[pos]; 134 System.arraycopy( buf, 0, copy, 0, pos ); 135 return copy; 136 } 137 138 139 /** 140 * Appends the bytes to this buffer. 141 * 142 * @param bytes The byte[] to append to the buffer 143 */ 144 public final void append( byte[] bytes ) 145 { 146 if ( pos + bytes.length > buf.length ) 147 { 148 growBuffer( bytes.length ); 149 } 150 151 System.arraycopy( bytes, 0, buf, pos, bytes.length ); 152 pos += bytes.length; 153 } 154 155 156 /** 157 * Appends a byte to this buffer. 158 * 159 * @param b The byte to append to the buffer 160 */ 161 public final void append( byte b ) 162 { 163 if ( pos >= buf.length ) 164 { 165 growBuffer(); 166 } 167 168 buf[pos] = b; 169 pos++; 170 } 171 172 173 /** 174 * Appends an int to this buffer. WARNING: the int is truncated to 175 * a byte value. 176 * 177 * @param val The integer to append to the buffer 178 */ 179 public final void append( int val ) 180 { 181 if ( pos >= buf.length ) 182 { 183 growBuffer(); 184 } 185 186 buf[pos] = ( byte ) val; 187 pos++; 188 } 189 190 191 private void growBuffer( int size ) 192 { 193 if ( size > initialSize ) 194 { 195 byte[] copy = new byte[buf.length + size]; 196 System.arraycopy( buf, 0, copy, 0, pos ); 197 this.buf = copy; 198 } 199 else 200 { 201 byte[] copy = new byte[buf.length + initialSize]; 202 System.arraycopy( buf, 0, copy, 0, pos ); 203 this.buf = copy; 204 } 205 } 206 207 208 private void growBuffer() 209 { 210 byte[] copy = new byte[buf.length + initialSize]; 211 System.arraycopy( buf, 0, copy, 0, pos ); 212 this.buf = copy; 213 } 214}