1/*
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
3 * Please refer to the LICENSE.txt for licensing details.
4 */
5package ch.ethz.ssh2.packets;
6
7import java.io.UnsupportedEncodingException;
8import java.math.BigInteger;
9
10import ch.ethz.ssh2.util.StringEncoder;
11
12/**
13 * TypesWriter.
14 *
15 * @author Christian Plattner
16 * @version 2.50, 03/15/10
17 */
18public class TypesWriter
19{
20	byte arr[];
21	int pos;
22
23	public TypesWriter()
24	{
25		arr = new byte[256];
26		pos = 0;
27	}
28
29	private void resize(int len)
30	{
31		byte new_arr[] = new byte[len];
32		System.arraycopy(arr, 0, new_arr, 0, arr.length);
33		arr = new_arr;
34	}
35
36	public int length()
37	{
38		return pos;
39	}
40
41	public byte[] getBytes()
42	{
43		byte[] dst = new byte[pos];
44		System.arraycopy(arr, 0, dst, 0, pos);
45		return dst;
46	}
47
48	public void getBytes(byte dst[])
49	{
50		System.arraycopy(arr, 0, dst, 0, pos);
51	}
52
53	public void writeUINT32(int val, int off)
54	{
55		if ((off + 4) > arr.length)
56			resize(off + 32);
57
58		arr[off++] = (byte) (val >> 24);
59		arr[off++] = (byte) (val >> 16);
60		arr[off++] = (byte) (val >> 8);
61		arr[off++] = (byte) val;
62	}
63
64	public void writeUINT32(int val)
65	{
66		writeUINT32(val, pos);
67		pos += 4;
68	}
69
70	public void writeUINT64(long val)
71	{
72		if ((pos + 8) > arr.length)
73			resize(arr.length + 32);
74
75		arr[pos++] = (byte) (val >> 56);
76		arr[pos++] = (byte) (val >> 48);
77		arr[pos++] = (byte) (val >> 40);
78		arr[pos++] = (byte) (val >> 32);
79		arr[pos++] = (byte) (val >> 24);
80		arr[pos++] = (byte) (val >> 16);
81		arr[pos++] = (byte) (val >> 8);
82		arr[pos++] = (byte) val;
83	}
84
85	public void writeBoolean(boolean v)
86	{
87		if ((pos + 1) > arr.length)
88			resize(arr.length + 32);
89
90		arr[pos++] = v ? (byte) 1 : (byte) 0;
91	}
92
93	public void writeByte(int v, int off)
94	{
95		if ((off + 1) > arr.length)
96			resize(off + 32);
97
98		arr[off] = (byte) v;
99	}
100
101	public void writeByte(int v)
102	{
103		writeByte(v, pos);
104		pos++;
105	}
106
107	public void writeMPInt(BigInteger b)
108	{
109		byte raw[] = b.toByteArray();
110
111		if ((raw.length == 1) && (raw[0] == 0))
112			writeUINT32(0); /* String with zero bytes of data */
113		else
114			writeString(raw, 0, raw.length);
115	}
116
117	public void writeBytes(byte[] buff)
118	{
119		writeBytes(buff, 0, buff.length);
120	}
121
122	public void writeBytes(byte[] buff, int off, int len)
123	{
124		if ((pos + len) > arr.length)
125			resize(arr.length + len + 32);
126
127		System.arraycopy(buff, off, arr, pos, len);
128		pos += len;
129	}
130
131	public void writeString(byte[] buff, int off, int len)
132	{
133		writeUINT32(len);
134		writeBytes(buff, off, len);
135	}
136
137	public void writeString(String v)
138	{
139		byte[] b = StringEncoder.GetBytes(v);
140
141		writeUINT32(b.length);
142		writeBytes(b, 0, b.length);
143	}
144
145	public void writeString(String v, String charsetName) throws UnsupportedEncodingException
146	{
147		byte[] b = (charsetName == null) ? StringEncoder.GetBytes(v) : v.getBytes(charsetName);
148
149		writeUINT32(b.length);
150		writeBytes(b, 0, b.length);
151	}
152
153	public void writeNameList(String v[])
154	{
155		StringBuilder sb = new StringBuilder();
156		for (int i = 0; i < v.length; i++)
157		{
158			if (i > 0)
159				sb.append(',');
160			sb.append(v[i]);
161		}
162		writeString(sb.toString());
163	}
164}
165