/* * Copyright 2010 NCHOVY * * 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 org.krakenapps.rrd.io; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; public class MemoryPersistentLayer extends PersistentLayer { private static final int DEFAULT_CAPACITY = 8192; private byte[] b; private ByteBuffer readbuf; private ByteBuffer writebuf; public MemoryPersistentLayer() { reallocate(); } public MemoryPersistentLayer(byte[] oldBuffer, int size) { reallocate(size / DEFAULT_CAPACITY * DEFAULT_CAPACITY); readbuf.put(oldBuffer, 0, size); } private void reallocate() { reallocate((readbuf != null) ? (readbuf.capacity() * 2) : DEFAULT_CAPACITY); } private void reallocate(int capacity) { if (b != null) b = Arrays.copyOf(b, capacity); else b = new byte[capacity]; int readpos = (readbuf != null) ? readbuf.position() : 0; readbuf = ByteBuffer.wrap(b); readbuf.position(readpos); int writepos = (writebuf != null) ? writebuf.position() : 0; writebuf = ByteBuffer.wrap(b); writebuf.position(writepos); setLimit(); } private void checkRemaining(int needs) { if (writebuf.remaining() < needs) reallocate(); } private void setLimit() { readbuf.limit(writebuf.position()); } @Override public void open(boolean read) { readbuf.position(0); writebuf.position(0); } @Override public void write(int b) throws IOException { checkRemaining(1); writebuf.put((byte) (b & 0xFF)); setLimit(); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { checkRemaining(len); writebuf.put(b, off, len); setLimit(); } @Override public void writeBoolean(boolean v) throws IOException { checkRemaining(1); writebuf.put((byte) (v ? 1 : 0)); setLimit(); } @Override public void writeByte(int v) throws IOException { checkRemaining(1); write(v); setLimit(); } @Override public void writeShort(int v) throws IOException { checkRemaining(2); writebuf.putShort((short) (v & 0xFFFF)); setLimit(); } @Override public void writeChar(int v) throws IOException { checkRemaining(2); writebuf.putChar((char) (v & 0xFFFF)); setLimit(); } @Override public void writeInt(int v) throws IOException { checkRemaining(4); writebuf.putInt(v); setLimit(); } @Override public void writeLong(long v) throws IOException { checkRemaining(8); writebuf.putLong(v); setLimit(); } @Override public void writeFloat(float v) throws IOException { checkRemaining(4); writebuf.putFloat(v); setLimit(); } @Override public void writeDouble(double v) throws IOException { checkRemaining(8); writebuf.putDouble(v); setLimit(); } @Override public void writeBytes(String s) throws IOException { byte[] bytes = s.getBytes("utf-8"); checkRemaining(2 + bytes.length); writebuf.putShort((short) bytes.length); writebuf.put(bytes); setLimit(); } @Override public void writeChars(String s) throws IOException { char[] charArray = s.toCharArray(); checkRemaining(charArray.length); for (char c : charArray) writebuf.putChar(c); setLimit(); } @Override public void writeUTF(String s) throws IOException { writeBytes(s); } @Override public void readFully(byte[] b) throws IOException { readbuf.get(b); } @Override public void readFully(byte[] b, int off, int len) throws IOException { readbuf.get(b, off, len); } @Override public int skipBytes(int n) throws IOException { readbuf.position(readbuf.position() + n); return n; } @Override public boolean readBoolean() throws IOException { return (readbuf.get() != (byte) 0x0); } @Override public byte readByte() throws IOException { return readbuf.get(); } @Override public int readUnsignedByte() throws IOException { return (readbuf.get() & 0xFFFFFFFF); } @Override public short readShort() throws IOException { return readbuf.getShort(); } @Override public int readUnsignedShort() throws IOException { return (readbuf.getShort() & 0xFFFFFFFF); } @Override public char readChar() throws IOException { return readbuf.getChar(); } @Override public int readInt() throws IOException { return readbuf.getInt(); } @Override public long readLong() throws IOException { return readbuf.getLong(); } @Override public float readFloat() throws IOException { return readbuf.getFloat(); } @Override public double readDouble() throws IOException { return readbuf.getDouble(); } @Override public String readLine() throws IOException { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } @Override public String readUTF() throws IOException { byte[] b = new byte[readbuf.getShort()]; read(b); return new String(b, "utf-8"); } @Override public void close() throws IOException { readbuf.position(0); writebuf.position(0); } @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } @Override public int read(byte[] b, int off, int len) throws IOException { len = Math.max(0, Math.min(len, readbuf.remaining() - off)); readbuf.get(b, off, len); return len; } }