Buffer.java
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class Buffer {
final byte[] tmp = new byte[4];
byte[] buffer;
int index;
int s;
public Buffer(int size) {
buffer = new byte[size];
index = 0;
s = 0;
}
public Buffer(byte[] buffer) {
this.buffer = buffer;
index = 0;
s = 0;
}
public Buffer() {
this(1024 * 10 * 2);
}
public void putByte(byte foo) {
buffer[index++] = foo;
}
public void putByte(byte[] foo) {
putByte(foo, 0, foo.length);
}
public void putByte(byte[] foo, int begin, int length) {
System.arraycopy(foo, begin, buffer, index, length);
index += length;
}
public void putString(byte[] foo) {
putString(foo, 0, foo.length);
}
public void putString(byte[] foo, int begin, int length) {
putInt(length);
putByte(foo, begin, length);
}
public void putInt(int val) {
tmp[0] = (byte) (val >>> 24);
tmp[1] = (byte) (val >>> 16);
tmp[2] = (byte) (val >>> 8);
tmp[3] = (byte) (val);
System.arraycopy(tmp, 0, buffer, index, 4);
index += 4;
}
public void putLong(long val) {
tmp[0] = (byte) (val >>> 56);
tmp[1] = (byte) (val >>> 48);
tmp[2] = (byte) (val >>> 40);
tmp[3] = (byte) (val >>> 32);
System.arraycopy(tmp, 0, buffer, index, 4);
tmp[0] = (byte) (val >>> 24);
tmp[1] = (byte) (val >>> 16);
tmp[2] = (byte) (val >>> 8);
tmp[3] = (byte) (val);
System.arraycopy(tmp, 0, buffer, index + 4, 4);
index += 8;
}
void skip(int n) {
index += n;
}
void putPad(int n) {
while (n > 0) {
buffer[index++] = (byte) 0;
n--;
}
}
public void putMPInt(byte[] foo) {
int i = foo.length;
if ((foo[0] & 0x80) != 0) {
i++;
putInt(i);
putByte((byte) 0);
} else {
putInt(i);
}
putByte(foo);
}
public int getLength() {
return index - s;
}
public int getOffSet() {
return s;
}
public void setOffSet(int s) {
this.s = s;
}
public long getLong() {
long foo = getInt() & 0xffffffffL;
foo = ((foo << 32)) | (getInt() & 0xffffffffL);
return foo;
}
public int getInt() {
int foo = getShort();
foo = ((foo << 16) & 0xffff0000) | (getShort() & 0xffff);
return foo;
}
public long getUInt() {
long foo = 0L;
long bar = 0L;
foo = getByte();
foo = ((foo << 8) & 0xff00) | (getByte() & 0xff);
bar = getByte();
bar = ((bar << 8) & 0xff00) | (getByte() & 0xff);
foo = ((foo << 16) & 0xffff0000) | (bar & 0xffff);
return foo;
}
int getShort() {
int foo = getByte();
foo = ((foo << 8) & 0xff00) | (getByte() & 0xff);
return foo;
}
public int getByte() {
return (buffer[s++] & 0xff);
}
public void getByte(byte[] foo) {
getByte(foo, 0, foo.length);
}
void getByte(byte[] foo, int start, int len) {
System.arraycopy(buffer, s, foo, start, len);
s += len;
}
public int getByte(int len) {
int foo = s;
s += len;
return foo;
}
public byte[] getMPInt() {
int i = getInt(); // uint32
if (i < 0 || // bigger than 0x7fffffff
i > 8 * 1024) {
// TODO: an exception should be thrown.
i = 8 * 1024; // the session will be broken, but working around OOME.
}
byte[] foo = new byte[i];
getByte(foo, 0, i);
return foo;
}
public byte[] getMPIntBits() {
int bits = getInt();
int bytes = (bits + 7) / 8;
byte[] foo = new byte[bytes];
getByte(foo, 0, bytes);
if ((foo[0] & 0x80) != 0) {
byte[] bar = new byte[foo.length + 1];
bar[0] = 0; // ??
System.arraycopy(foo, 0, bar, 1, foo.length);
foo = bar;
}
return foo;
}
public byte[] getString() {
int i = getInt(); // uint32
if (i < 0 || // bigger than 0x7fffffff
i > 256 * 1024) {
// TODO: an exception should be thrown.
i = 256 * 1024; // the session will be broken, but working around OOME.
}
byte[] foo = new byte[i];
getByte(foo, 0, i);
return foo;
}
byte[] getString(int[] start, int[] len) {
int i = getInt();
start[0] = getByte(i);
len[0] = i;
return buffer;
}
public void reset() {
index = 0;
s = 0;
}
public void shift() {
if (s == 0)
return;
System.arraycopy(buffer, s, buffer, 0, index - s);
index = index - s;
s = 0;
}
void rewind() {
s = 0;
}
byte getCommand() {
return buffer[5];
}
// Hardcode this since we can't use dynamic Session value
private static final int buffer_margin = 32 + // maximum padding length
64 + // maximum mac length
32; // margin for deflater; deflater may inflate data
void checkFreeSize(int n) {
int size = index + n + buffer_margin;
if (buffer.length < size) {
int i = buffer.length * 2;
if (i < size)
i = size;
byte[] tmp = new byte[i];
System.arraycopy(buffer, 0, tmp, 0, index);
buffer = tmp;
}
}
byte[][] getBytes(int n, String msg) throws JSchException {
byte[][] tmp = new byte[n][];
for (int i = 0; i < n; i++) {
int j = getInt();
if (getLength() < j) {
throw new JSchException(msg);
}
tmp[i] = new byte[j];
getByte(tmp[i]);
}
return tmp;
}
/*
* static Buffer fromBytes(byte[]... args){ int length = args.length*4; for(int i = 0; i <
* args.length; i++){ length += args[i].length; } Buffer buf = new Buffer(length); for(int i = 0;
* i < args.length; i++){ buf.putString(args[i]); } return buf; }
*/
static Buffer fromBytes(byte[][] args) {
int length = args.length * 4;
for (int i = 0; i < args.length; i++) {
length += args[i].length;
}
Buffer buf = new Buffer(length);
for (int i = 0; i < args.length; i++) {
buf.putString(args[i]);
}
return buf;
}
/*
* static String[] chars={ "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f" };
* static void dump_buffer(){ int foo; for(int i=0; i<tmp_buffer_index; i++){
* foo=tmp_buffer[i]&0xff; System.err.print(chars[(foo>>>4)&0xf]);
* System.err.print(chars[foo&0xf]); if(i%16==15){ System.err.println(""); continue; } if(i>0 &&
* i%2==1){ System.err.print(" "); } } System.err.println(""); } static void dump(byte[] b){
* dump(b, 0, b.length); } static void dump(byte[] b, int s, int l){ for(int i=s; i<s+l; i++){
* System.err.print(Integer.toHexString(b[i]&0xff)+":"); } System.err.println(""); }
*/
}