/* * Copyright 2014 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.apiman.gateway.engine.io; import io.apiman.gateway.engine.components.IBufferFactoryComponent; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Arrays; /** * A simple {@link IApimanBuffer} from a byte array. Don't use this class * directly - create and manage buffers by using the {@link IBufferFactoryComponent} * instead! The factory will give you a platform-specific buffer implementation. * * @author eric.wittmann@redhat.com */ @SuppressWarnings("nls") // TODO finish the implementation of this class! public class ByteBuffer implements IApimanBuffer { private byte [] buffer; private int bytesInBuffer = 0; /** * Constructor. * @param buffer * @param size */ public ByteBuffer(byte [] buffer, int size) { this.buffer = buffer; this.bytesInBuffer = size; } /** * Constructor. * * @param size initial size */ public ByteBuffer(int size) { buffer = new byte[size]; } /** * Constructor. * * @param stringData String data */ public ByteBuffer(String stringData) { buffer = stringData.getBytes(); bytesInBuffer = buffer.length; } /** * Constructor. * * @param stringData String data * @param enc String data encoding */ public ByteBuffer(String stringData, String enc) { try { buffer = stringData.getBytes(enc); bytesInBuffer = buffer.length; } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * @param byteData the byte data to initialize buffer */ public ByteBuffer(byte[] byteData) { buffer = Arrays.copyOf(byteData, byteData.length); bytesInBuffer = byteData.length; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#getNativeBuffer() */ @Override public Object getNativeBuffer() { return buffer; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#length() */ @Override public int length() { return bytesInBuffer; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, io.apiman.gateway.engine.io.IApimanBuffer) */ @Override public void insert(int index, IApimanBuffer buffer) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, io.apiman.gateway.engine.io.IApimanBuffer, int, int) */ @Override public void insert(int index, IApimanBuffer buffer, int offset, int length) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(io.apiman.gateway.engine.io.IApimanBuffer) */ @Override public void append(IApimanBuffer buffer) { append(buffer, 0, buffer.length()); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(io.apiman.gateway.engine.io.IApimanBuffer, int, int) */ @Override public void append(IApimanBuffer buffer, int offset, int length) { int sizeToAppend = length; int newBufferSize = this.bytesInBuffer + sizeToAppend; if (this.buffer.length >= newBufferSize) { System.arraycopy(buffer.getBytes(), offset, this.buffer, bytesInBuffer, sizeToAppend); } else { byte [] newBuffer = new byte[newBufferSize]; System.arraycopy(this.buffer, 0, newBuffer, 0, bytesInBuffer); System.arraycopy(buffer.getBytes(), offset, newBuffer, bytesInBuffer, sizeToAppend); this.buffer = newBuffer; } this.bytesInBuffer = newBufferSize; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#get(int) */ @Override public byte get(int index) { return buffer[index]; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#set(int, byte) */ @Override public void set(int index, byte b) { buffer[index] = b; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(byte) */ @Override public void append(byte b) { byte [] bytes = new byte[1]; bytes[0] = b; append(bytes); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#getBytes() */ @Override public byte[] getBytes() { byte [] rval = new byte[bytesInBuffer]; System.arraycopy(buffer, 0, rval, 0, bytesInBuffer); return rval; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#getBytes(int, int) */ @Override public byte[] getBytes(int start, int end) { int size = end - start; byte [] rval = new byte[size]; System.arraycopy(buffer, start, rval, 0, size); return rval; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, byte[]) */ @Override public void insert(int index, byte[] b) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, byte[], int, int) */ @Override public void insert(int index, byte[] b, int offset, int length) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(byte[]) */ @Override public void append(byte[] bytes) { int requiredBytes = bytesInBuffer + bytes.length; if (requiredBytes > buffer.length) { byte [] oldbuffer = buffer; buffer = new byte[requiredBytes]; System.arraycopy(oldbuffer, 0, buffer, 0, bytesInBuffer); } System.arraycopy(bytes, 0, buffer, bytesInBuffer, bytes.length); bytesInBuffer = requiredBytes; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(byte[], int, int) */ @Override public void append(byte[] bytes, int offset, int length) { int requiredBytes = bytesInBuffer + length; if (requiredBytes > buffer.length) { byte [] oldbuffer = buffer; buffer = new byte[requiredBytes]; System.arraycopy(oldbuffer, 0, buffer, 0, bytesInBuffer); } System.arraycopy(bytes, offset, buffer, bytesInBuffer, length); bytesInBuffer = requiredBytes; } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#getString(int, int) */ @Override public String getString(int start, int end) { return new String(getBytes(start, end)); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#getString(int, int, java.lang.String) */ @Override public String getString(int start, int end, String encoding) { try { return new String(getBytes(start, end), encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, java.lang.String) */ @Override public void insert(int index, String string) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#insert(int, java.lang.String, java.lang.String) */ @Override public void insert(int index, String string, String encoding) { throw new RuntimeException("Not yet implemented"); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(java.lang.String) */ @Override public void append(String string) { byte[] bytes = string.getBytes(); append(bytes); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#append(java.lang.String, java.lang.String) */ @Override public void append(String string, String encoding) throws UnsupportedEncodingException { byte [] bytes = string.getBytes(encoding); append(bytes); } /** * @see io.apiman.gateway.engine.io.IApimanBuffer#toString(java.lang.String) */ @Override public String toString(String encoding) { try { return new String(buffer, 0, bytesInBuffer, encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * @see java.lang.Object#toString() */ @Override public String toString() { return new String(buffer, 0, bytesInBuffer); } /** * @return the bytesInBuffer */ public int getBytesInBuffer() { return bytesInBuffer; } /** * Reads from the input stream. * @param stream the input stream to read from * @throws IOException I/O error when reading from buffer * @return bytes read from buffer */ public int readFrom(InputStream stream) throws IOException { int bytesRead = stream.read(buffer); if (bytesRead < 0) { bytesInBuffer = 0; } else { bytesInBuffer = bytesRead; } return bytesRead; } }