Mercurial > hg > Members > nobuyasu > tightVNCClient
comparison src/InStream.java @ 4:60a87e277536
indent
author | e085711 |
---|---|
date | Wed, 13 Apr 2011 08:00:53 +0900 |
parents | e04119c40b9b |
children |
comparison
equal
deleted
inserted
replaced
3:c930d146670f | 4:60a87e277536 |
---|---|
21 // Representation). | 21 // Representation). |
22 // | 22 // |
23 | 23 |
24 abstract public class InStream { | 24 abstract public class InStream { |
25 | 25 |
26 // check() ensures there is buffer data for at least one item of size | 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 | 27 // itemSize bytes. Returns the number of items in the buffer (up to a |
28 // maximum of nItems). | 28 // maximum of nItems). |
29 | 29 |
30 public final int check(int itemSize, int nItems) throws Exception { | 30 public final int check(int itemSize, int nItems) throws Exception { |
31 if (ptr + itemSize * nItems > end) { | 31 if (ptr + itemSize * nItems > end) { |
32 if (ptr + itemSize > end) | 32 if (ptr + itemSize > end) |
33 return overrun(itemSize, nItems); | 33 return overrun(itemSize, nItems); |
34 | 34 |
35 nItems = (end - ptr) / itemSize; | 35 nItems = (end - ptr) / itemSize; |
36 } | 36 } |
37 return nItems; | 37 return nItems; |
38 } | 38 } |
39 | 39 |
40 public final void check(int itemSize) throws Exception { | 40 public final void check(int itemSize) throws Exception { |
41 if (ptr + itemSize > end) | 41 if (ptr + itemSize > end) |
42 overrun(itemSize, 1); | 42 overrun(itemSize, 1); |
43 } | 43 } |
44 | 44 |
45 // readU/SN() methods read unsigned and signed N-bit integers. | 45 // readU/SN() methods read unsigned and signed N-bit integers. |
46 | 46 |
47 public final int readS8() throws Exception { | 47 public final int readS8() throws Exception { |
48 check(1); return b[ptr++]; | 48 check(1); |
49 } | 49 return b[ptr++]; |
50 | 50 } |
51 public final int readS16() throws Exception { | 51 |
52 check(2); int b0 = b[ptr++]; | 52 public final int readS16() throws Exception { |
53 int b1 = b[ptr++] & 0xff; return b0 << 8 | b1; | 53 check(2); |
54 } | 54 int b0 = b[ptr++]; |
55 | 55 int b1 = b[ptr++] & 0xff; |
56 public final int readS32() throws Exception { | 56 return b0 << 8 | b1; |
57 check(4); int b0 = b[ptr++]; | 57 } |
58 int b1 = b[ptr++] & 0xff; | 58 |
59 int b2 = b[ptr++] & 0xff; | 59 public final int readS32() throws Exception { |
60 int b3 = b[ptr++] & 0xff; | 60 check(4); |
61 return b0 << 24 | b1 << 16 | b2 << 8 | b3; | 61 int b0 = b[ptr++]; |
62 } | 62 int b1 = b[ptr++] & 0xff; |
63 | 63 int b2 = b[ptr++] & 0xff; |
64 public final int readU8() throws Exception { | 64 int b3 = b[ptr++] & 0xff; |
65 return readS8() & 0xff; | 65 return b0 << 24 | b1 << 16 | b2 << 8 | b3; |
66 } | 66 } |
67 | 67 |
68 public final int readU16() throws Exception { | 68 public final int readU8() throws Exception { |
69 return readS16() & 0xffff; | 69 return readS8() & 0xff; |
70 } | 70 } |
71 | 71 |
72 public final int readU32() throws Exception { | 72 public final int readU16() throws Exception { |
73 return readS32() & 0xffffffff; | 73 return readS16() & 0xffff; |
74 } | 74 } |
75 | 75 |
76 // readString() reads a string - a U32 length followed by the data. | 76 public final int readU32() throws Exception { |
77 | 77 return readS32() & 0xffffffff; |
78 public final String readString() throws Exception { | 78 } |
79 int len = readU32(); | 79 |
80 if (len > maxStringLength) | 80 // readString() reads a string - a U32 length followed by the data. |
81 throw new Exception("InStream max string length exceeded"); | 81 |
82 | 82 public final String readString() throws Exception { |
83 char[] str = new char[len]; | 83 int len = readU32(); |
84 int i = 0; | 84 if (len > maxStringLength) |
85 while (i < len) { | 85 throw new Exception("InStream max string length exceeded"); |
86 int j = i + check(1, len - i); | 86 |
87 while (i < j) { | 87 char[] str = new char[len]; |
88 str[i++] = (char)b[ptr++]; | 88 int i = 0; |
89 } | 89 while (i < len) { |
90 } | 90 int j = i + check(1, len - i); |
91 | 91 while (i < j) { |
92 return new String(str); | 92 str[i++] = (char) b[ptr++]; |
93 } | 93 } |
94 | 94 } |
95 // maxStringLength protects against allocating a huge buffer. Set it | 95 |
96 // higher if you need longer strings. | 96 return new String(str); |
97 | 97 } |
98 public static int maxStringLength = 65535; | 98 |
99 | 99 // maxStringLength protects against allocating a huge buffer. Set it |
100 public final void skip(int bytes) throws Exception { | 100 // higher if you need longer strings. |
101 while (bytes > 0) { | 101 |
102 int n = check(1, bytes); | 102 public static int maxStringLength = 65535; |
103 ptr += n; | 103 |
104 bytes -= n; | 104 public final void skip(int bytes) throws Exception { |
105 } | 105 while (bytes > 0) { |
106 } | 106 int n = check(1, bytes); |
107 | 107 ptr += n; |
108 // readBytes() reads an exact number of bytes into an array at an offset. | 108 bytes -= n; |
109 | 109 } |
110 public void readBytes(byte[] data, int offset, int length) throws Exception { | 110 } |
111 int offsetEnd = offset + length; | 111 |
112 while (offset < offsetEnd) { | 112 // readBytes() reads an exact number of bytes into an array at an offset. |
113 int n = check(1, offsetEnd - offset); | 113 |
114 System.arraycopy(b, ptr, data, offset, n); | 114 public void readBytes(byte[] data, int offset, int length) throws Exception { |
115 ptr += n; | 115 int offsetEnd = offset + length; |
116 offset += n; | 116 while (offset < offsetEnd) { |
117 } | 117 int n = check(1, offsetEnd - offset); |
118 } | 118 System.arraycopy(b, ptr, data, offset, n); |
119 | 119 ptr += n; |
120 // readOpaqueN() reads a quantity "without byte-swapping". Because java has | 120 offset += n; |
121 // no byte-ordering, we just use big-endian. | 121 } |
122 | 122 } |
123 public final int readOpaque8() throws Exception { | 123 |
124 return readU8(); | 124 // readOpaqueN() reads a quantity "without byte-swapping". Because java has |
125 } | 125 // no byte-ordering, we just use big-endian. |
126 | 126 |
127 public final int readOpaque16() throws Exception { | 127 public final int readOpaque8() throws Exception { |
128 return readU16(); | 128 return readU8(); |
129 } | 129 } |
130 | 130 |
131 public final int readOpaque32() throws Exception { | 131 public final int readOpaque16() throws Exception { |
132 return readU32(); | 132 return readU16(); |
133 } | 133 } |
134 | 134 |
135 public final int readOpaque24A() throws Exception { | 135 public final int readOpaque32() throws Exception { |
136 check(3); int b0 = b[ptr++]; | 136 return readU32(); |
137 int b1 = b[ptr++]; int b2 = b[ptr++]; | 137 } |
138 return b0 << 24 | b1 << 16 | b2 << 8; | 138 |
139 } | 139 public final int readOpaque24A() throws Exception { |
140 | 140 check(3); |
141 public final int readOpaque24B() throws Exception { | 141 int b0 = b[ptr++]; |
142 check(3); int b0 = b[ptr++]; | 142 int b1 = b[ptr++]; |
143 int b1 = b[ptr++]; int b2 = b[ptr++]; | 143 int b2 = b[ptr++]; |
144 return b0 << 16 | b1 << 8 | b2; | 144 return b0 << 24 | b1 << 16 | b2 << 8; |
145 } | 145 } |
146 | 146 |
147 // pos() returns the position in the stream. | 147 public final int readOpaque24B() throws Exception { |
148 | 148 check(3); |
149 abstract public int pos(); | 149 int b0 = b[ptr++]; |
150 | 150 int b1 = b[ptr++]; |
151 // bytesAvailable() returns true if at least one byte can be read from the | 151 int b2 = b[ptr++]; |
152 // stream without blocking. i.e. if false is returned then readU8() would | 152 return b0 << 16 | b1 << 8 | b2; |
153 // block. | 153 } |
154 | 154 |
155 public boolean bytesAvailable() { return end != ptr; } | 155 // pos() returns the position in the stream. |
156 | 156 |
157 // getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow | 157 abstract public int pos(); |
158 // you to manipulate the buffer directly. This is useful for a stream which | 158 |
159 // is a wrapper around an underlying stream. | 159 // bytesAvailable() returns true if at least one byte can be read from the |
160 | 160 // stream without blocking. i.e. if false is returned then readU8() would |
161 public final byte[] getbuf() { return b; } | 161 // block. |
162 public final int getptr() { return ptr; } | 162 |
163 public final int getend() { return end; } | 163 public boolean bytesAvailable() { |
164 public final void setptr(int p) { ptr = p; } | 164 return end != ptr; |
165 | 165 } |
166 // overrun() is implemented by a derived class to cope with buffer overrun. | 166 |
167 // It ensures there are at least itemSize bytes of buffer data. Returns | 167 // getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow |
168 // the number of items in the buffer (up to a maximum of nItems). itemSize | 168 // you to manipulate the buffer directly. This is useful for a stream which |
169 // is supposed to be "small" (a few bytes). | 169 // is a wrapper around an underlying stream. |
170 | 170 |
171 abstract protected int overrun(int itemSize, int nItems) throws Exception; | 171 public final byte[] getbuf() { |
172 | 172 return b; |
173 protected InStream() {} | 173 } |
174 protected byte[] b; | 174 |
175 protected int ptr; | 175 public final int getptr() { |
176 protected int end; | 176 return ptr; |
177 } | |
178 | |
179 public final int getend() { | |
180 return end; | |
181 } | |
182 | |
183 public final void setptr(int p) { | |
184 ptr = p; | |
185 } | |
186 | |
187 // overrun() is implemented by a derived class to cope with buffer overrun. | |
188 // It ensures there are at least itemSize bytes of buffer data. Returns | |
189 // the number of items in the buffer (up to a maximum of nItems). itemSize | |
190 // is supposed to be "small" (a few bytes). | |
191 | |
192 abstract protected int overrun(int itemSize, int nItems) throws Exception; | |
193 | |
194 protected InStream() { | |
195 } | |
196 | |
197 protected byte[] b; | |
198 protected int ptr; | |
199 protected int end; | |
177 } | 200 } |