/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.fs.jfat;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.jnode.util.LittleEndian;
import org.jnode.util.NumberUtils;
/**
* @author gvt
*/
public class FatMarshal {
private final byte[] array;
private boolean dirty = false;
public FatMarshal(byte[] array) {
if (array == null)
throw new NullPointerException("array cannot be null");
this.array = array;
}
public FatMarshal(int length) {
this.array = new byte[length];
Arrays.fill(this.array, 0, this.array.length, (byte) 0);
}
public static FatMarshal wrap(byte[] array) {
return new FatMarshal(array);
}
public byte[] getArray() {
return array;
}
public ByteBuffer getByteBuffer() {
ByteBuffer buf = ByteBuffer.wrap(array);
buf.clear();
return buf;
}
public int length() {
return array.length;
}
public boolean isDirty() {
return dirty;
}
public void setDirty() {
dirty = true;
}
public void flush() {
dirty = false;
}
private void checkOffset(int offset, int length) {
if (offset < 0)
throw new IndexOutOfBoundsException("offset[" + offset + "] cannot be negative");
if (length <= 0)
throw new IndexOutOfBoundsException("length[" + length + "] has to be positive");
if (offset > (array.length - length))
throw new IndexOutOfBoundsException("length[" + length + "] + offset[" + offset +
"] >" + "array.length[" + array.length + "]");
}
public byte get(int offset) {
checkOffset(offset, 1);
return array[offset];
}
public void put(int offset, byte value) {
checkOffset(offset, 1);
array[offset] = value;
setDirty();
}
public int getUInt8(int offset) {
checkOffset(offset, 1);
return LittleEndian.getUInt8(array, offset);
}
public void setUInt8(int offset, int value) {
checkOffset(offset, 1);
LittleEndian.setInt8(array, offset, value);
setDirty();
}
public int getUInt16(int offset) {
checkOffset(offset, 2);
return LittleEndian.getUInt16(array, offset);
}
public void setUInt16(int offset, int value) {
checkOffset(offset, 2);
LittleEndian.setInt16(array, offset, value);
setDirty();
}
public long getUInt32(int offset) {
checkOffset(offset, 4);
return LittleEndian.getUInt32(array, offset);
}
public void setUInt32(int offset, long value) {
checkOffset(offset, 4);
LittleEndian.setInt32(array, offset, (int) value);
setDirty();
}
public String getString(int offset, int length) {
checkOffset(offset, length);
StringBuilder b = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int v = array[offset + i];
b.append((char) v);
}
return b.toString();
}
public void setString(int offset, int length, String value) {
checkOffset(offset, length);
for (int i = 0; i < length; i++) {
char ch;
if (i < value.length())
ch = value.charAt(i);
else
ch = (char) 0;
LittleEndian.setInt8(array, offset + i, ch);
}
setDirty();
}
public char[] getChars(int offset, int length) {
checkOffset(offset, length);
char[] value = new char[length];
for (int i = 0; i < length; i++)
value[i] = (char) LittleEndian.getUInt8(array, offset + i);
return value;
}
public void setChars(int offset, int length, char[] value) {
checkOffset(offset, length);
for (int i = 0; i < length; i++)
LittleEndian.setInt8(array, offset + i, (int) value[i]);
setDirty();
}
public byte[] getBytes(int offset, int length) {
byte[] value = new byte[length];
getBytes(offset, length, 0, value);
return value;
}
public void setBytes(int offset, int length, byte[] value) {
setBytes(offset, length, 0, value);
}
public void getBytes(int offset, int length, int start, byte[] dst) {
checkOffset(offset, length);
System.arraycopy(array, offset, dst, start, length);
}
public void setBytes(int offset, int length, int start, byte[] src) {
checkOffset(offset, length);
System.arraycopy(src, start, array, offset, length);
setDirty();
}
@Override
public String toString() {
return String.format("FatMarshal %s", NumberUtils.hex(array));
}
public String toDebugString() {
StrWriter out = new StrWriter();
out.println("*************************************************");
out.println("Fat Marshal");
out.println("*************************************************");
out.println("length =\t" + length());
out.println("dirty =\t" + isDirty());
out.println("array");
out.println(array);
out.print("*************************************************");
return out.toString();
}
}