source: trunk/packages/invirt-vnc-client/InStream.java @ 2766

Last change on this file since 2766 was 1334, checked in by broder, 16 years ago

sipb-xen-vnc-client -> invirt-vnc-client

File size: 5.1 KB
Line 
1/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16 * USA.
17 */
18
19//
20// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data
21// Representation).
22//
23
24abstract public class InStream {
25
26  // check() ensures there is buffer data for at least one item of size
27  // itemSize bytes.  Returns the number of items in the buffer (up to a
28  // maximum of nItems).
29
30  public final int check(int itemSize, int nItems) throws Exception {
31    if (ptr + itemSize * nItems > end) {
32      if (ptr + itemSize > end)
33        return overrun(itemSize, nItems);
34
35      nItems = (end - ptr) / itemSize;
36    }
37    return nItems;
38  }
39
40  public final void check(int itemSize) throws Exception {
41    if (ptr + itemSize > end)
42      overrun(itemSize, 1);
43  }
44
45  // readU/SN() methods read unsigned and signed N-bit integers.
46
47  public final int readS8() throws Exception {
48    check(1); return b[ptr++];
49  }
50
51  public final int readS16() throws Exception {
52    check(2); int b0 = b[ptr++];
53    int b1 = b[ptr++] & 0xff; return b0 << 8 | b1;
54  }
55
56  public final int readS32() throws Exception {
57    check(4); int b0 = b[ptr++];
58    int b1 = b[ptr++] & 0xff;
59    int b2 = b[ptr++] & 0xff;
60    int b3 = b[ptr++] & 0xff;
61    return b0 << 24 | b1 << 16 | b2 << 8 | b3;
62  }
63
64  public final int readU8() throws Exception {
65    return readS8() & 0xff;
66  }
67
68  public final int readU16() throws Exception {
69    return readS16() & 0xffff;
70  }
71
72  public final int readU32() throws Exception {
73    return readS32() & 0xffffffff;
74  }
75
76  // readString() reads a string - a U32 length followed by the data.
77
78  public final String readString() throws Exception {
79    int len = readU32();
80    if (len > maxStringLength)
81      throw new Exception("InStream max string length exceeded");
82
83    char[] str = new char[len];
84    int i = 0;
85    while (i < len) {
86      int j = i + check(1, len - i);
87      while (i < j) {
88        str[i++] = (char)b[ptr++];
89      }
90    }
91
92    return new String(str);
93  }
94
95  // maxStringLength protects against allocating a huge buffer.  Set it
96  // higher if you need longer strings.
97
98  public static int maxStringLength = 65535;
99
100  public final void skip(int bytes) throws Exception {
101    while (bytes > 0) {
102      int n = check(1, bytes);
103      ptr += n;
104      bytes -= n;
105    }
106  }
107
108  // readBytes() reads an exact number of bytes into an array at an offset.
109
110  public void readBytes(byte[] data, int offset, int length) throws Exception {
111    int offsetEnd = offset + length;
112    while (offset < offsetEnd) {
113      int n = check(1, offsetEnd - offset);
114      System.arraycopy(b, ptr, data, offset, n);
115      ptr += n;
116      offset += n;
117    }
118  }
119
120  // readOpaqueN() reads a quantity "without byte-swapping".  Because java has
121  // no byte-ordering, we just use big-endian.
122
123  public final int readOpaque8() throws Exception {
124    return readU8();
125  }
126
127  public final int readOpaque16() throws Exception {
128    return readU16();
129  }
130
131  public final int readOpaque32() throws Exception {
132    return readU32();
133  }
134
135  public final int readOpaque24A() throws Exception {
136    check(3); int b0 = b[ptr++];
137    int b1 = b[ptr++]; int b2 = b[ptr++];
138    return b0 << 24 | b1 << 16 | b2 << 8;
139  }
140
141  public final int readOpaque24B() throws Exception {
142    check(3); int b0 = b[ptr++];
143    int b1 = b[ptr++]; int b2 = b[ptr++];
144    return b0 << 16 | b1 << 8 | b2;
145  }
146
147  // pos() returns the position in the stream.
148
149  abstract public int pos();
150
151  // bytesAvailable() returns true if at least one byte can be read from the
152  // stream without blocking.  i.e. if false is returned then readU8() would
153  // block.
154
155  public boolean bytesAvailable() { return end != ptr; }
156
157  // getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow
158  // you to manipulate the buffer directly.  This is useful for a stream which
159  // is a wrapper around an underlying stream.
160
161  public final byte[] getbuf() { return b; }
162  public final int getptr() { return ptr; }
163  public final int getend() { return end; }
164  public final void setptr(int p) { ptr = p; }
165
166  // overrun() is implemented by a derived class to cope with buffer overrun.
167  // It ensures there are at least itemSize bytes of buffer data.  Returns
168  // the number of items in the buffer (up to a maximum of nItems).  itemSize
169  // is supposed to be "small" (a few bytes).
170
171  abstract protected int overrun(int itemSize, int nItems) throws Exception;
172
173  protected InStream() {}
174  protected byte[] b;
175  protected int ptr;
176  protected int end;
177}
Note: See TracBrowser for help on using the repository browser.