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.james.mime4j.util; 021 022 023 /** 024 * A resizable byte array. 025 */ 026 public final class ByteArrayBuffer implements ByteSequence { 027 028 private byte[] buffer; 029 private int len; 030 031 public ByteArrayBuffer(int capacity) { 032 super(); 033 if (capacity < 0) { 034 throw new IllegalArgumentException("Buffer capacity may not be negative"); 035 } 036 this.buffer = new byte[capacity]; 037 } 038 039 public ByteArrayBuffer(byte[] bytes, boolean dontCopy) { 040 this(bytes, bytes.length, dontCopy); 041 } 042 043 public ByteArrayBuffer(byte[] bytes, int len, boolean dontCopy) { 044 if (bytes == null) 045 throw new IllegalArgumentException(); 046 if (len < 0 || len > bytes.length) 047 throw new IllegalArgumentException(); 048 049 if (dontCopy) { 050 this.buffer = bytes; 051 } else { 052 this.buffer = new byte[len]; 053 System.arraycopy(bytes, 0, this.buffer, 0, len); 054 } 055 056 this.len = len; 057 } 058 059 private void expand(int newlen) { 060 byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)]; 061 System.arraycopy(this.buffer, 0, newbuffer, 0, this.len); 062 this.buffer = newbuffer; 063 } 064 065 public void append(final byte[] b, int off, int len) { 066 if (b == null) { 067 return; 068 } 069 if ((off < 0) || (off > b.length) || (len < 0) || 070 ((off + len) < 0) || ((off + len) > b.length)) { 071 throw new IndexOutOfBoundsException(); 072 } 073 if (len == 0) { 074 return; 075 } 076 int newlen = this.len + len; 077 if (newlen > this.buffer.length) { 078 expand(newlen); 079 } 080 System.arraycopy(b, off, this.buffer, this.len, len); 081 this.len = newlen; 082 } 083 084 public void append(int b) { 085 int newlen = this.len + 1; 086 if (newlen > this.buffer.length) { 087 expand(newlen); 088 } 089 this.buffer[this.len] = (byte)b; 090 this.len = newlen; 091 } 092 093 public void clear() { 094 this.len = 0; 095 } 096 097 public byte[] toByteArray() { 098 byte[] b = new byte[this.len]; 099 if (this.len > 0) { 100 System.arraycopy(this.buffer, 0, b, 0, this.len); 101 } 102 return b; 103 } 104 105 public byte byteAt(int i) { 106 if (i < 0 || i >= this.len) 107 throw new IndexOutOfBoundsException(); 108 109 return this.buffer[i]; 110 } 111 112 public int capacity() { 113 return this.buffer.length; 114 } 115 116 public int length() { 117 return this.len; 118 } 119 120 public byte[] buffer() { 121 return this.buffer; 122 } 123 124 public int indexOf(byte b) { 125 return indexOf(b, 0, this.len); 126 } 127 128 public int indexOf(byte b, int beginIndex, int endIndex) { 129 if (beginIndex < 0) { 130 beginIndex = 0; 131 } 132 if (endIndex > this.len) { 133 endIndex = this.len; 134 } 135 if (beginIndex > endIndex) { 136 return -1; 137 } 138 for (int i = beginIndex; i < endIndex; i++) { 139 if (this.buffer[i] == b) { 140 return i; 141 } 142 } 143 return -1; 144 } 145 146 public void setLength(int len) { 147 if (len < 0 || len > this.buffer.length) { 148 throw new IndexOutOfBoundsException(); 149 } 150 this.len = len; 151 } 152 153 public boolean isEmpty() { 154 return this.len == 0; 155 } 156 157 public boolean isFull() { 158 return this.len == this.buffer.length; 159 } 160 161 @Override 162 public String toString() { 163 return new String(toByteArray()); 164 } 165 166 }