/* * Copyright 2010-2017 Brian Pellin. * * This file is part of KeePassDroid. * * KeePassDroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * KeePassDroid 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with KeePassDroid. If not, see <http://www.gnu.org/licenses/>. * */ package com.keepassdroid.stream; import com.keepassdroid.utils.Types; import java.io.IOException; import java.io.InputStream; import java.util.UUID; /** Little endian version of the DataInputStream * @author bpellin * */ public class LEDataInputStream extends InputStream { public static final long INT_TO_LONG_MASK = 0xffffffffL; private InputStream baseStream; public LEDataInputStream(InputStream in) { baseStream = in; } /** Read a 32-bit value and return it as a long, so that it can * be interpreted as an unsigned integer. * @return * @throws IOException */ public long readUInt() throws IOException { return readUInt(baseStream); } public int readInt() throws IOException { return readInt(baseStream); } public long readLong() throws IOException { byte[] buf = readBytes(8); return readLong(buf, 0); } @Override public int available() throws IOException { return baseStream.available(); } @Override public void close() throws IOException { baseStream.close(); } @Override public void mark(int readlimit) { baseStream.mark(readlimit); } @Override public boolean markSupported() { return baseStream.markSupported(); } @Override public int read() throws IOException { return baseStream.read(); } @Override public int read(byte[] b, int offset, int length) throws IOException { return baseStream.read(b, offset, length); } @Override public int read(byte[] b) throws IOException { // TODO Auto-generated method stub return super.read(b); } @Override public synchronized void reset() throws IOException { baseStream.reset(); } @Override public long skip(long n) throws IOException { return baseStream.skip(n); } public byte[] readBytes(int length) throws IOException { byte[] buf = new byte[length]; int count = 0; while ( count < length ) { int read = read(buf, count, length - count); // Reached end if ( read == -1 ) { // Stop early byte[] early = new byte[count]; System.arraycopy(buf, 0, early, 0, count); return early; } count += read; } return buf; } public static int readUShort(InputStream is) throws IOException { byte[] buf = new byte[2]; is.read(buf, 0, 2); return readUShort(buf, 0); } public int readUShort() throws IOException { return readUShort(baseStream); } /** * Read an unsigned 16-bit value. * * @param buf * @param offset * @return */ public static int readUShort( byte[] buf, int offset ) { return (buf[offset + 0] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8); } public static long readLong( byte buf[], int offset ) { return ((long)buf[offset + 0] & 0xFF) + (((long)buf[offset + 1] & 0xFF) << 8) + (((long)buf[offset + 2] & 0xFF) << 16) + (((long)buf[offset + 3] & 0xFF) << 24) + (((long)buf[offset + 4] & 0xFF) << 32) + (((long)buf[offset + 5] & 0xFF) << 40) + (((long)buf[offset + 6] & 0xFF) << 48) + (((long)buf[offset + 7] & 0xFF) << 56); } public static long readUInt( byte buf[], int offset ) { return (readInt(buf, offset) & INT_TO_LONG_MASK); } public static int readInt(InputStream is) throws IOException { byte[] buf = new byte[4]; is.read(buf, 0, 4); return readInt(buf, 0); } public static long readUInt(InputStream is) throws IOException { return (readInt(is) & INT_TO_LONG_MASK); } /** * Read a 32-bit value. * * @param buf * @param offset * @return */ public static int readInt( byte buf[], int offset ) { return (buf[offset + 0] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8) + ((buf[offset + 2] & 0xFF) << 16) + ((buf[offset + 3] & 0xFF) << 24); } public UUID readUUID() throws IOException { byte[] buf = readBytes(16); return Types.bytestoUUID(buf); } }