Home | History | Annotate | Download | only in packets
      1 /*
      2  * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
      3  * Please refer to the LICENSE.txt for licensing details.
      4  */
      5 package ch.ethz.ssh2.packets;
      6 
      7 import java.io.IOException;
      8 import java.math.BigInteger;
      9 
     10 import ch.ethz.ssh2.util.StringEncoder;
     11 import ch.ethz.ssh2.util.Tokenizer;
     12 
     13 /**
     14  * TypesReader.
     15  *
     16  * @author Christian Plattner
     17  * @version 2.50, 03/15/10
     18  */
     19 public class TypesReader
     20 {
     21 	byte[] arr;
     22 	int pos = 0;
     23 	int max = 0;
     24 
     25 	public TypesReader(byte[] arr)
     26 	{
     27 		this.arr = arr;
     28 		pos = 0;
     29 		max = arr.length;
     30 	}
     31 
     32 	public TypesReader(byte[] arr, int off)
     33 	{
     34 		this.arr = arr;
     35 		this.pos = off;
     36 		this.max = arr.length;
     37 
     38 		if ((pos < 0) || (pos > arr.length))
     39 			throw new IllegalArgumentException("Illegal offset.");
     40 	}
     41 
     42 	public TypesReader(byte[] arr, int off, int len)
     43 	{
     44 		this.arr = arr;
     45 		this.pos = off;
     46 		this.max = off + len;
     47 
     48 		if ((pos < 0) || (pos > arr.length))
     49 			throw new IllegalArgumentException("Illegal offset.");
     50 
     51 		if ((max < 0) || (max > arr.length))
     52 			throw new IllegalArgumentException("Illegal length.");
     53 	}
     54 
     55 	public int readByte() throws IOException
     56 	{
     57 		if (pos >= max)
     58 			throw new IOException("Packet too short.");
     59 
     60 		return (arr[pos++] & 0xff);
     61 	}
     62 
     63 	public byte[] readBytes(int len) throws IOException
     64 	{
     65 		if ((pos + len) > max)
     66 			throw new IOException("Packet too short.");
     67 
     68 		byte[] res = new byte[len];
     69 
     70 		System.arraycopy(arr, pos, res, 0, len);
     71 		pos += len;
     72 
     73 		return res;
     74 	}
     75 
     76 	public void readBytes(byte[] dst, int off, int len) throws IOException
     77 	{
     78 		if ((pos + len) > max)
     79 			throw new IOException("Packet too short.");
     80 
     81 		System.arraycopy(arr, pos, dst, off, len);
     82 		pos += len;
     83 	}
     84 
     85 	public boolean readBoolean() throws IOException
     86 	{
     87 		if (pos >= max)
     88 			throw new IOException("Packet too short.");
     89 
     90 		return (arr[pos++] != 0);
     91 	}
     92 
     93 	public int readUINT32() throws IOException
     94 	{
     95 		if ((pos + 4) > max)
     96 			throw new IOException("Packet too short.");
     97 
     98 		return ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
     99 				| (arr[pos++] & 0xff);
    100 	}
    101 
    102 	public long readUINT64() throws IOException
    103 	{
    104 		if ((pos + 8) > max)
    105 			throw new IOException("Packet too short.");
    106 
    107 		long high = ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
    108 				| (arr[pos++] & 0xff); /* sign extension may take place - will be shifted away =) */
    109 
    110 		long low = ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
    111 				| (arr[pos++] & 0xff); /* sign extension may take place - handle below */
    112 
    113 		return (high << 32) | (low & 0xffffffffl); /* see Java language spec (15.22.1, 5.6.2) */
    114 	}
    115 
    116 	public BigInteger readMPINT() throws IOException
    117 	{
    118 		BigInteger b;
    119 
    120 		byte raw[] = readByteString();
    121 
    122 		if (raw.length == 0)
    123 			b = BigInteger.ZERO;
    124 		else
    125 			b = new BigInteger(raw);
    126 
    127 		return b;
    128 	}
    129 
    130 	public byte[] readByteString() throws IOException
    131 	{
    132 		int len = readUINT32();
    133 
    134 		if ((len + pos) > max)
    135 			throw new IOException("Malformed SSH byte string.");
    136 
    137 		byte[] res = new byte[len];
    138 		System.arraycopy(arr, pos, res, 0, len);
    139 		pos += len;
    140 		return res;
    141 	}
    142 
    143 	public String readString(String charsetName) throws IOException
    144 	{
    145 		int len = readUINT32();
    146 
    147 		if ((len + pos) > max)
    148 			throw new IOException("Malformed SSH string.");
    149 
    150 		String res = (charsetName == null) ? new String(arr, pos, len) : new String(arr, pos, len, charsetName);
    151 		pos += len;
    152 
    153 		return res;
    154 	}
    155 
    156 	public String readString() throws IOException
    157 	{
    158 		int len = readUINT32();
    159 
    160 		if ((len + pos) > max)
    161 			throw new IOException("Malformed SSH string.");
    162 
    163 		String res = StringEncoder.GetString(arr, pos, len);
    164 		pos += len;
    165 
    166 		return res;
    167 	}
    168 
    169 	public String[] readNameList() throws IOException
    170 	{
    171 		return Tokenizer.parseTokens(readString(), ',');
    172 	}
    173 
    174 	public int remain()
    175 	{
    176 		return max - pos;
    177 	}
    178 
    179 }
    180