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 }