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 public ByteBuffer() 047 { 048 this( DEFAULT_INITIAL_SIZE ); 049 } 050 051 052 public ByteBuffer( int initialSize ) 053 { 054 if ( initialSize <= 0 ) 055 { 056 throw new IllegalArgumentException( I18n.err( I18n.ERR_04354 ) ); 057 } 058 059 this.initialSize = initialSize; 060 this.buf = new byte[initialSize]; 061 } 062 063 064 public final void clear() 065 { 066 pos = 0; 067 } 068 069 070 public final int position() 071 { 072 return pos; 073 } 074 075 076 public final int capacity() 077 { 078 return buf.length; 079 } 080 081 082 public final byte get( int i ) 083 { 084 return buf[i]; 085 } 086 087 088 /** 089 * Get's the bytes, the backing store for this buffer. Note 090 * that you need to use the position index to determine where 091 * to stop reading from this buffer. 092 */ 093 public final byte[] buffer() 094 { 095 return buf; 096 } 097 098 099 /** 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}