Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: third_party/protobuf/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 17 matching lines...) Expand all
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf; 31 package com.google.protobuf;
32 32
33 import protobuf_unittest.UnittestProto.BoolMessage; 33 import protobuf_unittest.UnittestProto.BoolMessage;
34 import protobuf_unittest.UnittestProto.Int32Message; 34 import protobuf_unittest.UnittestProto.Int32Message;
35 import protobuf_unittest.UnittestProto.Int64Message; 35 import protobuf_unittest.UnittestProto.Int64Message;
36 import protobuf_unittest.UnittestProto.TestAllTypes; 36 import protobuf_unittest.UnittestProto.TestAllTypes;
37 import protobuf_unittest.UnittestProto.TestRecursiveMessage; 37 import protobuf_unittest.UnittestProto.TestRecursiveMessage;
38
39 import junit.framework.TestCase;
40
41 import java.io.ByteArrayInputStream; 38 import java.io.ByteArrayInputStream;
42 import java.io.ByteArrayOutputStream; 39 import java.io.ByteArrayOutputStream;
43 import java.io.FilterInputStream; 40 import java.io.FilterInputStream;
44 import java.io.IOException; 41 import java.io.IOException;
45 import java.io.InputStream; 42 import java.io.InputStream;
46 import java.nio.ByteBuffer; 43 import java.nio.ByteBuffer;
44 import junit.framework.TestCase;
47 45
48 /** 46 /**
49 * Unit test for {@link CodedInputStream}. 47 * Unit test for {@link CodedInputStream}.
50 * 48 *
51 * @author kenton@google.com Kenton Varda 49 * @author kenton@google.com Kenton Varda
52 */ 50 */
53 public class CodedInputStreamTest extends TestCase { 51 public class CodedInputStreamTest extends TestCase {
52 private enum InputType {
53 ARRAY {
54 @Override
55 CodedInputStream newDecoder(byte[] data, int blockSize) {
56 return CodedInputStream.newInstance(data);
57 }
58 },
59 NIO_HEAP {
60 @Override
61 CodedInputStream newDecoder(byte[] data, int blockSize) {
62 return CodedInputStream.newInstance(ByteBuffer.wrap(data));
63 }
64 },
65 NIO_DIRECT {
66 @Override
67 CodedInputStream newDecoder(byte[] data, int blockSize) {
68 ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
69 buffer.put(data);
70 buffer.flip();
71 return CodedInputStream.newInstance(buffer);
72 }
73 },
74 STREAM {
75 @Override
76 CodedInputStream newDecoder(byte[] data, int blockSize) {
77 return CodedInputStream.newInstance(new SmallBlockInputStream(data, bloc kSize));
78 }
79 };
80
81 CodedInputStream newDecoder(byte[] data) {
82 return newDecoder(data, data.length);
83 }
84
85 abstract CodedInputStream newDecoder(byte[] data, int blockSize);
86 }
87
54 /** 88 /**
55 * Helper to construct a byte array from a bunch of bytes. The inputs are 89 * Helper to construct a byte array from a bunch of bytes. The inputs are actu ally ints so that I
56 * actually ints so that I can use hex notation and not get stupid errors 90 * can use hex notation and not get stupid errors about precision.
57 * about precision.
58 */ 91 */
59 private byte[] bytes(int... bytesAsInts) { 92 private byte[] bytes(int... bytesAsInts) {
60 byte[] bytes = new byte[bytesAsInts.length]; 93 byte[] bytes = new byte[bytesAsInts.length];
61 for (int i = 0; i < bytesAsInts.length; i++) { 94 for (int i = 0; i < bytesAsInts.length; i++) {
62 bytes[i] = (byte) bytesAsInts[i]; 95 bytes[i] = (byte) bytesAsInts[i];
63 } 96 }
64 return bytes; 97 return bytes;
65 } 98 }
66 99
67 /** 100 /**
68 * An InputStream which limits the number of bytes it reads at a time. 101 * An InputStream which limits the number of bytes it reads at a time. We use this to make sure
69 * We use this to make sure that CodedInputStream doesn't screw up when 102 * that CodedInputStream doesn't screw up when reading in small blocks.
70 * reading in small blocks.
71 */ 103 */
72 private static final class SmallBlockInputStream extends FilterInputStream { 104 private static final class SmallBlockInputStream extends FilterInputStream {
73 private final int blockSize; 105 private final int blockSize;
74 106
75 public SmallBlockInputStream(byte[] data, int blockSize) { 107 public SmallBlockInputStream(byte[] data, int blockSize) {
76 this(new ByteArrayInputStream(data), blockSize); 108 super(new ByteArrayInputStream(data));
77 }
78
79 public SmallBlockInputStream(InputStream in, int blockSize) {
80 super(in);
81 this.blockSize = blockSize; 109 this.blockSize = blockSize;
82 } 110 }
83 111
84 @Override 112 @Override
85 public int read(byte[] b) throws IOException { 113 public int read(byte[] b) throws IOException {
86 return super.read(b, 0, Math.min(b.length, blockSize)); 114 return super.read(b, 0, Math.min(b.length, blockSize));
87 } 115 }
88 116
89 @Override 117 @Override
90 public int read(byte[] b, int off, int len) throws IOException { 118 public int read(byte[] b, int off, int len) throws IOException {
91 return super.read(b, off, Math.min(len, blockSize)); 119 return super.read(b, off, Math.min(len, blockSize));
92 } 120 }
93 } 121 }
94 122
95 private void assertDataConsumed(byte[] data, CodedInputStream input) 123 private void assertDataConsumed(String msg, byte[] data, CodedInputStream inpu t)
96 throws IOException { 124 throws IOException {
97 assertEquals(data.length, input.getTotalBytesRead()); 125 assertEquals(msg, data.length, input.getTotalBytesRead());
98 assertTrue(input.isAtEnd()); 126 assertTrue(msg, input.isAtEnd());
99 } 127 }
100 128
101 /** 129 /**
102 * Parses the given bytes using readRawVarint32() and readRawVarint64() and 130 * Parses the given bytes using readRawVarint32() and readRawVarint64() and ch ecks that the result
103 * checks that the result matches the given value. 131 * matches the given value.
104 */ 132 */
105 private void assertReadVarint(byte[] data, long value) throws Exception { 133 private void assertReadVarint(byte[] data, long value) throws Exception {
106 CodedInputStream input = CodedInputStream.newInstance(data); 134 for (InputType inputType : InputType.values()) {
107 assertEquals((int) value, input.readRawVarint32()); 135 // Try different block sizes.
108 assertDataConsumed(data, input); 136 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
137 CodedInputStream input = inputType.newDecoder(data, blockSize);
138 assertEquals(inputType.name(), (int) value, input.readRawVarint32());
139 assertDataConsumed(inputType.name(), data, input);
109 140
110 input = CodedInputStream.newInstance(data); 141 input = inputType.newDecoder(data, blockSize);
111 assertEquals(value, input.readRawVarint64()); 142 assertEquals(inputType.name(), value, input.readRawVarint64());
112 assertDataConsumed(data, input); 143 assertDataConsumed(inputType.name(), data, input);
113 144
114 input = CodedInputStream.newInstance(data); 145 input = inputType.newDecoder(data, blockSize);
115 assertEquals(value, input.readRawVarint64SlowPath()); 146 assertEquals(inputType.name(), value, input.readRawVarint64SlowPath());
116 assertDataConsumed(data, input); 147 assertDataConsumed(inputType.name(), data, input);
117 148
118 input = CodedInputStream.newInstance(data); 149 input = inputType.newDecoder(data, blockSize);
119 assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT)); 150 assertTrue(inputType.name(), input.skipField(WireFormat.WIRETYPE_VARINT) );
120 assertDataConsumed(data, input); 151 assertDataConsumed(inputType.name(), data, input);
121 152 }
122 // Try different block sizes.
123 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
124 input = CodedInputStream.newInstance(
125 new SmallBlockInputStream(data, blockSize));
126 assertEquals((int) value, input.readRawVarint32());
127 assertDataConsumed(data, input);
128
129 input = CodedInputStream.newInstance(
130 new SmallBlockInputStream(data, blockSize));
131 assertEquals(value, input.readRawVarint64());
132 assertDataConsumed(data, input);
133
134 input = CodedInputStream.newInstance(
135 new SmallBlockInputStream(data, blockSize));
136 assertEquals(value, input.readRawVarint64SlowPath());
137 assertDataConsumed(data, input);
138
139 input = CodedInputStream.newInstance(
140 new SmallBlockInputStream(data, blockSize));
141 assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
142 assertDataConsumed(data, input);
143 } 153 }
144 154
145 // Try reading direct from an InputStream. We want to verify that it 155 // Try reading direct from an InputStream. We want to verify that it
146 // doesn't read past the end of the input, so we copy to a new, bigger 156 // doesn't read past the end of the input, so we copy to a new, bigger
147 // array first. 157 // array first.
148 byte[] longerData = new byte[data.length + 1]; 158 byte[] longerData = new byte[data.length + 1];
149 System.arraycopy(data, 0, longerData, 0, data.length); 159 System.arraycopy(data, 0, longerData, 0, data.length);
150 InputStream rawInput = new ByteArrayInputStream(longerData); 160 InputStream rawInput = new ByteArrayInputStream(longerData);
151 assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput)); 161 assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput));
152 assertEquals(1, rawInput.available()); 162 assertEquals(1, rawInput.available());
153 } 163 }
154 164
155 /** 165 /**
156 * Parses the given bytes using readRawVarint32() and readRawVarint64() and 166 * Parses the given bytes using readRawVarint32() and readRawVarint64() and ex pects them to fail
157 * expects them to fail with an InvalidProtocolBufferException whose 167 * with an InvalidProtocolBufferException whose description matches the given one.
158 * description matches the given one.
159 */ 168 */
160 private void assertReadVarintFailure( 169 private void assertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
161 InvalidProtocolBufferException expected, byte[] data)
162 throws Exception { 170 throws Exception {
163 CodedInputStream input = CodedInputStream.newInstance(data); 171 for (InputType inputType : InputType.values()) {
164 try { 172 try {
165 input.readRawVarint32(); 173 CodedInputStream input = inputType.newDecoder(data);
166 fail("Should have thrown an exception."); 174 input.readRawVarint32();
167 } catch (InvalidProtocolBufferException e) { 175 fail(inputType.name() + ": Should have thrown an exception.");
168 assertEquals(expected.getMessage(), e.getMessage()); 176 } catch (InvalidProtocolBufferException e) {
169 } 177 assertEquals(inputType.name(), expected.getMessage(), e.getMessage());
170 178 }
171 input = CodedInputStream.newInstance(data); 179 try {
172 try { 180 CodedInputStream input = inputType.newDecoder(data);
173 input.readRawVarint64(); 181 input.readRawVarint64();
174 fail("Should have thrown an exception."); 182 fail(inputType.name() + ": Should have thrown an exception.");
175 } catch (InvalidProtocolBufferException e) { 183 } catch (InvalidProtocolBufferException e) {
176 assertEquals(expected.getMessage(), e.getMessage()); 184 assertEquals(inputType.name(), expected.getMessage(), e.getMessage());
177 } 185 }
178
179 input = CodedInputStream.newInstance(data);
180 try {
181 input.readRawVarint64SlowPath();
182 fail("Should have thrown an exception.");
183 } catch (InvalidProtocolBufferException e) {
184 assertEquals(expected.getMessage(), e.getMessage());
185 } 186 }
186 187
187 // Make sure we get the same error when reading direct from an InputStream. 188 // Make sure we get the same error when reading direct from an InputStream.
188 try { 189 try {
189 CodedInputStream.readRawVarint32(new ByteArrayInputStream(data)); 190 CodedInputStream.readRawVarint32(new ByteArrayInputStream(data));
190 fail("Should have thrown an exception."); 191 fail("Should have thrown an exception.");
191 } catch (InvalidProtocolBufferException e) { 192 } catch (InvalidProtocolBufferException e) {
192 assertEquals(expected.getMessage(), e.getMessage()); 193 assertEquals(expected.getMessage(), e.getMessage());
193 } 194 }
194 } 195 }
195 196
196 /** Tests readRawVarint32() and readRawVarint64(). */ 197 /** Tests readRawVarint32() and readRawVarint64(). */
197 public void testReadVarint() throws Exception { 198 public void testReadVarint() throws Exception {
198 assertReadVarint(bytes(0x00), 0); 199 assertReadVarint(bytes(0x00), 0);
199 assertReadVarint(bytes(0x01), 1); 200 assertReadVarint(bytes(0x01), 1);
200 assertReadVarint(bytes(0x7f), 127); 201 assertReadVarint(bytes(0x7f), 127);
201 // 14882 202 // 14882
202 assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7)); 203 assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
203 // 2961488830 204 // 2961488830
204 assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b), 205 assertReadVarint(
205 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | 206 bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
206 (0x0bL << 28)); 207 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x0bL << 28)) ;
207 208
208 // 64-bit 209 // 64-bit
209 // 7256456126 210 // 7256456126
210 assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b), 211 assertReadVarint(
211 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | 212 bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
212 (0x1bL << 28)); 213 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x1bL << 28)) ;
213 // 41256202580718336 214 // 41256202580718336
214 assertReadVarint( 215 assertReadVarint(
215 bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49), 216 bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
216 (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | 217 (0x00 << 0)
217 (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49)); 218 | (0x66 << 7)
219 | (0x6b << 14)
220 | (0x1c << 21)
221 | (0x43L << 28)
222 | (0x49L << 35)
223 | (0x24L << 42)
224 | (0x49L << 49));
218 // 11964378330978735131 225 // 11964378330978735131
219 assertReadVarint( 226 assertReadVarint(
220 bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01), 227 bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
221 (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | 228 (0x1b << 0)
222 (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) | 229 | (0x28 << 7)
223 (0x05L << 49) | (0x26L << 56) | (0x01L << 63)); 230 | (0x79 << 14)
231 | (0x42 << 21)
232 | (0x3bL << 28)
233 | (0x56L << 35)
234 | (0x00L << 42)
235 | (0x05L << 49)
236 | (0x26L << 56)
237 | (0x01L << 63));
224 238
225 // Failures 239 // Failures
226 assertReadVarintFailure( 240 assertReadVarintFailure(
227 InvalidProtocolBufferException.malformedVarint(), 241 InvalidProtocolBufferException.malformedVarint(),
228 bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 242 bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)) ;
229 0x00)); 243 assertReadVarintFailure(InvalidProtocolBufferException.truncatedMessage(), b ytes(0x80));
230 assertReadVarintFailure(
231 InvalidProtocolBufferException.truncatedMessage(),
232 bytes(0x80));
233 } 244 }
234 245
235 /** 246 /**
236 * Parses the given bytes using readRawLittleEndian32() and checks 247 * Parses the given bytes using readRawLittleEndian32() and checks that the re sult matches the
237 * that the result matches the given value. 248 * given value.
238 */ 249 */
239 private void assertReadLittleEndian32(byte[] data, int value) 250 private void assertReadLittleEndian32(byte[] data, int value) throws Exception {
240 throws Exception { 251 for (InputType inputType : InputType.values()) {
241 CodedInputStream input = CodedInputStream.newInstance(data); 252 // Try different block sizes.
242 assertEquals(value, input.readRawLittleEndian32()); 253 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
243 assertTrue(input.isAtEnd()); 254 CodedInputStream input = inputType.newDecoder(data, blockSize);
244 255 assertEquals(inputType.name(), value, input.readRawLittleEndian32());
245 // Try different block sizes. 256 assertTrue(inputType.name(), input.isAtEnd());
246 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { 257 }
247 input = CodedInputStream.newInstance(
248 new SmallBlockInputStream(data, blockSize));
249 assertEquals(value, input.readRawLittleEndian32());
250 assertTrue(input.isAtEnd());
251 } 258 }
252 } 259 }
253 260
254 /** 261 /**
255 * Parses the given bytes using readRawLittleEndian64() and checks 262 * Parses the given bytes using readRawLittleEndian64() and checks that the re sult matches the
256 * that the result matches the given value. 263 * given value.
257 */ 264 */
258 private void assertReadLittleEndian64(byte[] data, long value) 265 private void assertReadLittleEndian64(byte[] data, long value) throws Exceptio n {
259 throws Exception { 266 for (InputType inputType : InputType.values()) {
260 CodedInputStream input = CodedInputStream.newInstance(data); 267 // Try different block sizes.
261 assertEquals(value, input.readRawLittleEndian64()); 268 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
262 assertTrue(input.isAtEnd()); 269 CodedInputStream input = inputType.newDecoder(data, blockSize);
263 270 assertEquals(inputType.name(), value, input.readRawLittleEndian64());
264 // Try different block sizes. 271 assertTrue(inputType.name(), input.isAtEnd());
265 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { 272 }
266 input = CodedInputStream.newInstance(
267 new SmallBlockInputStream(data, blockSize));
268 assertEquals(value, input.readRawLittleEndian64());
269 assertTrue(input.isAtEnd());
270 } 273 }
271 } 274 }
272 275
273 /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */ 276 /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */
274 public void testReadLittleEndian() throws Exception { 277 public void testReadLittleEndian() throws Exception {
275 assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); 278 assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
276 assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); 279 assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
277 280
278 assertReadLittleEndian64( 281 assertReadLittleEndian64(
279 bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 282 bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 0x123456789abcdef 0L);
280 0x123456789abcdef0L);
281 assertReadLittleEndian64( 283 assertReadLittleEndian64(
282 bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 284 bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef01234567 8L);
283 0x9abcdef012345678L);
284 } 285 }
285 286
286 /** Test decodeZigZag32() and decodeZigZag64(). */ 287 /** Test decodeZigZag32() and decodeZigZag64(). */
287 public void testDecodeZigZag() throws Exception { 288 public void testDecodeZigZag() throws Exception {
288 assertEquals( 0, CodedInputStream.decodeZigZag32(0)); 289 assertEquals(0, CodedInputStream.decodeZigZag32(0));
289 assertEquals(-1, CodedInputStream.decodeZigZag32(1)); 290 assertEquals(-1, CodedInputStream.decodeZigZag32(1));
290 assertEquals( 1, CodedInputStream.decodeZigZag32(2)); 291 assertEquals(1, CodedInputStream.decodeZigZag32(2));
291 assertEquals(-2, CodedInputStream.decodeZigZag32(3)); 292 assertEquals(-2, CodedInputStream.decodeZigZag32(3));
292 assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE)); 293 assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE));
293 assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF)); 294 assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF));
294 assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE)); 295 assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE));
295 assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF)); 296 assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF));
296 297
297 assertEquals( 0, CodedInputStream.decodeZigZag64(0)); 298 assertEquals(0, CodedInputStream.decodeZigZag64(0));
298 assertEquals(-1, CodedInputStream.decodeZigZag64(1)); 299 assertEquals(-1, CodedInputStream.decodeZigZag64(1));
299 assertEquals( 1, CodedInputStream.decodeZigZag64(2)); 300 assertEquals(1, CodedInputStream.decodeZigZag64(2));
300 assertEquals(-2, CodedInputStream.decodeZigZag64(3)); 301 assertEquals(-2, CodedInputStream.decodeZigZag64(3));
301 assertEquals(0x000000003FFFFFFFL, 302 assertEquals(0x000000003FFFFFFFL, CodedInputStream.decodeZigZag64(0x00000000 7FFFFFFEL));
302 CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL)); 303 assertEquals(0xFFFFFFFFC0000000L, CodedInputStream.decodeZigZag64(0x00000000 7FFFFFFFL));
303 assertEquals(0xFFFFFFFFC0000000L, 304 assertEquals(0x000000007FFFFFFFL, CodedInputStream.decodeZigZag64(0x00000000 FFFFFFFEL));
304 CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL)); 305 assertEquals(0xFFFFFFFF80000000L, CodedInputStream.decodeZigZag64(0x00000000 FFFFFFFFL));
305 assertEquals(0x000000007FFFFFFFL, 306 assertEquals(0x7FFFFFFFFFFFFFFFL, CodedInputStream.decodeZigZag64(0xFFFFFFFF FFFFFFFEL));
306 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL)); 307 assertEquals(0x8000000000000000L, CodedInputStream.decodeZigZag64(0xFFFFFFFF FFFFFFFFL));
307 assertEquals(0xFFFFFFFF80000000L,
308 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL));
309 assertEquals(0x7FFFFFFFFFFFFFFFL,
310 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL));
311 assertEquals(0x8000000000000000L,
312 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL));
313 } 308 }
314 309
315 /** Tests reading and parsing a whole message with every field type. */ 310 /** Tests reading and parsing a whole message with every field type. */
316 public void testReadWholeMessage() throws Exception { 311 public void testReadWholeMessage() throws Exception {
317 TestAllTypes message = TestUtil.getAllSet(); 312 TestAllTypes message = TestUtil.getAllSet();
318 313
319 byte[] rawBytes = message.toByteArray(); 314 byte[] rawBytes = message.toByteArray();
320 assertEquals(rawBytes.length, message.getSerializedSize()); 315 assertEquals(rawBytes.length, message.getSerializedSize());
321 316
322 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); 317 for (InputType inputType : InputType.values()) {
323 TestUtil.assertAllFieldsSet(message2); 318 // Try different block sizes.
324 319 for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
325 // Try different block sizes. 320 TestAllTypes message2 = TestAllTypes.parseFrom(inputType.newDecoder(rawB ytes, blockSize));
326 for (int blockSize = 1; blockSize < 256; blockSize *= 2) { 321 TestUtil.assertAllFieldsSet(message2);
327 message2 = TestAllTypes.parseFrom( 322 }
328 new SmallBlockInputStream(rawBytes, blockSize));
329 TestUtil.assertAllFieldsSet(message2);
330 } 323 }
331 } 324 }
332 325
333 /** Tests skipField(). */ 326 /** Tests skipField(). */
334 public void testSkipWholeMessage() throws Exception { 327 public void testSkipWholeMessage() throws Exception {
335 TestAllTypes message = TestUtil.getAllSet(); 328 TestAllTypes message = TestUtil.getAllSet();
336 byte[] rawBytes = message.toByteArray(); 329 byte[] rawBytes = message.toByteArray();
337 330
338 // Create two parallel inputs. Parse one as unknown fields while using 331 InputType[] inputTypes = InputType.values();
339 // skipField() to skip each field on the other. Expect the same tags. 332 CodedInputStream[] inputs = new CodedInputStream[inputTypes.length];
340 CodedInputStream input1 = CodedInputStream.newInstance(rawBytes); 333 for (int i = 0; i < inputs.length; ++i) {
341 CodedInputStream input2 = CodedInputStream.newInstance(rawBytes); 334 inputs[i] = inputTypes[i].newDecoder(rawBytes);
335 }
342 UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); 336 UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();
343 337
344 while (true) { 338 while (true) {
339 CodedInputStream input1 = inputs[0];
345 int tag = input1.readTag(); 340 int tag = input1.readTag();
346 assertEquals(tag, input2.readTag()); 341 // Ensure that the rest match.
342 for (int i = 1; i < inputs.length; ++i) {
343 assertEquals(inputTypes[i].name(), tag, inputs[i].readTag());
344 }
347 if (tag == 0) { 345 if (tag == 0) {
348 break; 346 break;
349 } 347 }
350 unknownFields.mergeFieldFrom(tag, input1); 348 unknownFields.mergeFieldFrom(tag, input1);
351 input2.skipField(tag); 349 // Skip the field for the rest of the inputs.
350 for (int i = 1; i < inputs.length; ++i) {
351 inputs[i].skipField(tag);
352 }
352 } 353 }
353 } 354 }
354 355
355 356
356 /** 357 /**
357 * Test that a bug in skipRawBytes() has been fixed: if the skip skips 358 * Test that a bug in skipRawBytes() has been fixed: if the skip skips exactly up to a limit, this
358 * exactly up to a limit, this should not break things. 359 * should not break things.
359 */ 360 */
360 public void testSkipRawBytesBug() throws Exception { 361 public void testSkipRawBytesBug() throws Exception {
361 byte[] rawBytes = new byte[] { 1, 2 }; 362 byte[] rawBytes = new byte[] {1, 2};
362 CodedInputStream input = CodedInputStream.newInstance(rawBytes); 363 for (InputType inputType : InputType.values()) {
363 364 CodedInputStream input = inputType.newDecoder(rawBytes);
364 int limit = input.pushLimit(1); 365 int limit = input.pushLimit(1);
365 input.skipRawBytes(1); 366 input.skipRawBytes(1);
366 input.popLimit(limit); 367 input.popLimit(limit);
367 assertEquals(2, input.readRawByte()); 368 assertEquals(inputType.name(), 2, input.readRawByte());
369 }
368 } 370 }
369 371
370 /** 372 /**
371 * Test that a bug in skipRawBytes() has been fixed: if the skip skips 373 * Test that a bug in skipRawBytes() has been fixed: if the skip skips past th e end of a buffer
372 * past the end of a buffer with a limit that has been set past the end of 374 * with a limit that has been set past the end of that buffer, this should not break things.
373 * that buffer, this should not break things.
374 */ 375 */
375 public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception { 376 public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
376 byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 }; 377 byte[] rawBytes = new byte[] {1, 2, 3, 4, 5};
377 CodedInputStream input = CodedInputStream.newInstance( 378 for (InputType inputType : InputType.values()) {
378 new SmallBlockInputStream(rawBytes, 3)); 379 CodedInputStream input = inputType.newDecoder(rawBytes);
379 380 int limit = input.pushLimit(4);
380 int limit = input.pushLimit(4); 381 // In order to expose the bug we need to read at least one byte to prime t he
381 // In order to expose the bug we need to read at least one byte to prime the 382 // buffer inside the CodedInputStream.
382 // buffer inside the CodedInputStream. 383 assertEquals(inputType.name(), 1, input.readRawByte());
383 assertEquals(1, input.readRawByte()); 384 // Skip to the end of the limit.
384 // Skip to the end of the limit. 385 input.skipRawBytes(3);
385 input.skipRawBytes(3); 386 assertTrue(inputType.name(), input.isAtEnd());
386 assertTrue(input.isAtEnd()); 387 input.popLimit(limit);
387 input.popLimit(limit); 388 assertEquals(inputType.name(), 5, input.readRawByte());
388 assertEquals(5, input.readRawByte()); 389 }
389 } 390 }
390 391
391 public void testReadHugeBlob() throws Exception { 392 public void testReadHugeBlob() throws Exception {
392 // Allocate and initialize a 1MB blob. 393 // Allocate and initialize a 1MB blob.
393 byte[] blob = new byte[1 << 20]; 394 byte[] blob = new byte[1 << 20];
394 for (int i = 0; i < blob.length; i++) { 395 for (int i = 0; i < blob.length; i++) {
395 blob[i] = (byte) i; 396 blob[i] = (byte) i;
396 } 397 }
397 398
398 // Make a message containing it. 399 // Make a message containing it.
399 TestAllTypes.Builder builder = TestAllTypes.newBuilder(); 400 TestAllTypes.Builder builder = TestAllTypes.newBuilder();
400 TestUtil.setAllFields(builder); 401 TestUtil.setAllFields(builder);
401 builder.setOptionalBytes(ByteString.copyFrom(blob)); 402 builder.setOptionalBytes(ByteString.copyFrom(blob));
402 TestAllTypes message = builder.build(); 403 TestAllTypes message = builder.build();
403 404
404 // Serialize and parse it. Make sure to parse from an InputStream, not 405 byte[] data = message.toByteArray();
405 // directly from a ByteString, so that CodedInputStream uses buffered 406 for (InputType inputType : InputType.values()) {
406 // reading. 407 // Serialize and parse it. Make sure to parse from an InputStream, not
407 TestAllTypes message2 = 408 // directly from a ByteString, so that CodedInputStream uses buffered
408 TestAllTypes.parseFrom(message.toByteString().newInput()); 409 // reading.
410 TestAllTypes message2 = TestAllTypes.parseFrom(inputType.newDecoder(data)) ;
409 411
410 assertEquals(message.getOptionalBytes(), message2.getOptionalBytes()); 412 assertEquals(inputType.name(), message.getOptionalBytes(), message2.getOpt ionalBytes());
411 413
412 // Make sure all the other fields were parsed correctly. 414 // Make sure all the other fields were parsed correctly.
413 TestAllTypes message3 = TestAllTypes.newBuilder(message2) 415 TestAllTypes message3 =
414 .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes()) 416 TestAllTypes.newBuilder(message2)
415 .build(); 417 .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes())
416 TestUtil.assertAllFieldsSet(message3); 418 .build();
419 TestUtil.assertAllFieldsSet(message3);
420 }
417 } 421 }
418 422
419 public void testReadMaliciouslyLargeBlob() throws Exception { 423 public void testReadMaliciouslyLargeBlob() throws Exception {
420 ByteString.Output rawOutput = ByteString.newOutput(); 424 ByteString.Output rawOutput = ByteString.newOutput();
421 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 425 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
422 426
423 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 427 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
424 output.writeRawVarint32(tag); 428 output.writeRawVarint32(tag);
425 output.writeRawVarint32(0x7FFFFFFF); 429 output.writeRawVarint32(0x7FFFFFFF);
426 output.writeRawBytes(new byte[32]); // Pad with a few random bytes. 430 output.writeRawBytes(new byte[32]); // Pad with a few random bytes.
427 output.flush(); 431 output.flush();
428 432
429 CodedInputStream input = rawOutput.toByteString().newCodedInput(); 433 byte[] data = rawOutput.toByteString().toByteArray();
430 assertEquals(tag, input.readTag()); 434 for (InputType inputType : InputType.values()) {
431 435 CodedInputStream input = inputType.newDecoder(data);
432 try { 436 assertEquals(tag, input.readTag());
433 input.readBytes(); 437 try {
434 fail("Should have thrown an exception!"); 438 input.readBytes();
435 } catch (InvalidProtocolBufferException e) { 439 fail(inputType.name() + ": Should have thrown an exception!");
436 // success. 440 } catch (InvalidProtocolBufferException e) {
441 // success.
442 }
437 } 443 }
438 } 444 }
439 445
446 /**
447 * Test we can do messages that are up to CodedInputStream#DEFAULT_SIZE_LIMIT
448 * in size (2G or Integer#MAX_SIZE).
449 * @throws IOException
450 */
451 public void testParseMessagesCloseTo2G() throws IOException {
452 byte[] serializedMessage = getBigSerializedMessage();
453 // How many of these big messages do we need to take us near our 2G limit?
454 int count = Integer.MAX_VALUE / serializedMessage.length;
455 // Now make an inputstream that will fake a near 2G message of messages
456 // returning our big serialized message 'count' times.
457 InputStream is = new RepeatingInputStream(serializedMessage, count);
458 // Parse should succeed!
459 TestAllTypes.parseFrom(is);
460 }
461
462 /**
463 * Test there is an exception if a message exceeds
464 * CodedInputStream#DEFAULT_SIZE_LIMIT in size (2G or Integer#MAX_SIZE).
465 * @throws IOException
466 */
467 public void testParseMessagesOver2G() throws IOException {
468 byte[] serializedMessage = getBigSerializedMessage();
469 // How many of these big messages do we need to take us near our 2G limit?
470 int count = Integer.MAX_VALUE / serializedMessage.length;
471 // Now add one to take us over the limit
472 count++;
473 // Now make an inputstream that will fake a near 2G message of messages
474 // returning our big serialized message 'count' times.
475 InputStream is = new RepeatingInputStream(serializedMessage, count);
476 try {
477 TestAllTypes.parseFrom(is);
478 fail("Should have thrown an exception!");
479 } catch (InvalidProtocolBufferException e) {
480 assertTrue(e.getMessage().contains("too large"));
481 }
482 }
483
484 /*
485 * @return A serialized big message.
486 */
487 private static byte[] getBigSerializedMessage() {
488 byte[] value = new byte[16 * 1024 * 1024];
489 ByteString bsValue = ByteString.wrap(value);
490 return TestAllTypes.newBuilder().setOptionalBytes(bsValue).build().toByteArr ay();
491 }
492
493 /*
494 * An input stream that repeats a byte arrays' content a number of times.
495 * Simulates really large input without consuming loads of memory. Used above
496 * to test the parsing behavior when the input size exceeds 2G or close to it.
497 */
498 private static class RepeatingInputStream extends InputStream {
499 private final byte[] serializedMessage;
500 private final int count;
501 private int index = 0;
502 private int offset = 0;
503
504 RepeatingInputStream(byte[] serializedMessage, int count) {
505 this.serializedMessage = serializedMessage;
506 this.count = count;
507 }
508
509 @Override
510 public int read() throws IOException {
511 if (this.offset == this.serializedMessage.length) {
512 this.index++;
513 this.offset = 0;
514 }
515 if (this.index == this.count) {
516 return -1;
517 }
518 return this.serializedMessage[offset++];
519 }
520 }
521
440 private TestRecursiveMessage makeRecursiveMessage(int depth) { 522 private TestRecursiveMessage makeRecursiveMessage(int depth) {
441 if (depth == 0) { 523 if (depth == 0) {
442 return TestRecursiveMessage.newBuilder().setI(5).build(); 524 return TestRecursiveMessage.newBuilder().setI(5).build();
443 } else { 525 } else {
444 return TestRecursiveMessage.newBuilder() 526 return TestRecursiveMessage.newBuilder().setA(makeRecursiveMessage(depth - 1)).build();
445 .setA(makeRecursiveMessage(depth - 1)).build();
446 } 527 }
447 } 528 }
448 529
449 private void assertMessageDepth(TestRecursiveMessage message, int depth) { 530 private void assertMessageDepth(String msg, TestRecursiveMessage message, int depth) {
450 if (depth == 0) { 531 if (depth == 0) {
451 assertFalse(message.hasA()); 532 assertFalse(msg, message.hasA());
452 assertEquals(5, message.getI()); 533 assertEquals(msg, 5, message.getI());
453 } else { 534 } else {
454 assertTrue(message.hasA()); 535 assertTrue(msg, message.hasA());
455 assertMessageDepth(message.getA(), depth - 1); 536 assertMessageDepth(msg, message.getA(), depth - 1);
456 } 537 }
457 } 538 }
458 539
459 public void testMaliciousRecursion() throws Exception { 540 public void testMaliciousRecursion() throws Exception {
460 ByteString data100 = makeRecursiveMessage(100).toByteString(); 541 byte[] data100 = makeRecursiveMessage(100).toByteArray();
461 ByteString data101 = makeRecursiveMessage(101).toByteString(); 542 byte[] data101 = makeRecursiveMessage(101).toByteArray();
462 543
463 assertMessageDepth(TestRecursiveMessage.parseFrom(data100), 100); 544 for (InputType inputType : InputType.values()) {
545 assertMessageDepth(
546 inputType.name(), TestRecursiveMessage.parseFrom(inputType.newDecoder( data100)), 100);
464 547
465 try { 548 try {
466 TestRecursiveMessage.parseFrom(data101); 549 TestRecursiveMessage.parseFrom(inputType.newDecoder(data101));
467 fail("Should have thrown an exception!"); 550 fail("Should have thrown an exception!");
468 } catch (InvalidProtocolBufferException e) { 551 } catch (InvalidProtocolBufferException e) {
469 // success. 552 // success.
470 } 553 }
471 554
472 CodedInputStream input = data100.newCodedInput(); 555 CodedInputStream input = inputType.newDecoder(data100);
473 input.setRecursionLimit(8); 556 input.setRecursionLimit(8);
474 try { 557 try {
475 TestRecursiveMessage.parseFrom(input); 558 TestRecursiveMessage.parseFrom(input);
476 fail("Should have thrown an exception!"); 559 fail(inputType.name() + ": Should have thrown an exception!");
477 } catch (InvalidProtocolBufferException e) { 560 } catch (InvalidProtocolBufferException e) {
478 // success. 561 // success.
562 }
479 } 563 }
480 } 564 }
481 565
482 private void checkSizeLimitExceeded(InvalidProtocolBufferException e) { 566 private void checkSizeLimitExceeded(InvalidProtocolBufferException e) {
483 assertEquals( 567 assertEquals(InvalidProtocolBufferException.sizeLimitExceeded().getMessage() , e.getMessage());
484 InvalidProtocolBufferException.sizeLimitExceeded().getMessage(),
485 e.getMessage());
486 } 568 }
487 569
488 public void testSizeLimit() throws Exception { 570 public void testSizeLimit() throws Exception {
489 CodedInputStream input = CodedInputStream.newInstance( 571 // NOTE: Size limit only applies to the stream-backed CIS.
490 new SmallBlockInputStream( 572 CodedInputStream input =
491 TestUtil.getAllSet().toByteString().newInput(), 16)); 573 CodedInputStream.newInstance(
574 new SmallBlockInputStream(TestUtil.getAllSet().toByteArray(), 16));
492 input.setSizeLimit(16); 575 input.setSizeLimit(16);
493 576
494 try { 577 try {
495 TestAllTypes.parseFrom(input); 578 TestAllTypes.parseFrom(input);
496 fail("Should have thrown an exception!"); 579 fail("Should have thrown an exception!");
497 } catch (InvalidProtocolBufferException expected) { 580 } catch (InvalidProtocolBufferException expected) {
498 checkSizeLimitExceeded(expected); 581 checkSizeLimitExceeded(expected);
499 } 582 }
500 } 583 }
501 584
502 public void testResetSizeCounter() throws Exception { 585 public void testResetSizeCounter() throws Exception {
503 CodedInputStream input = CodedInputStream.newInstance( 586 // NOTE: Size limit only applies to the stream-backed CIS.
504 new SmallBlockInputStream(new byte[256], 8)); 587 CodedInputStream input =
588 CodedInputStream.newInstance(new SmallBlockInputStream(new byte[256], 8) );
505 input.setSizeLimit(16); 589 input.setSizeLimit(16);
506 input.readRawBytes(16); 590 input.readRawBytes(16);
507 assertEquals(16, input.getTotalBytesRead()); 591 assertEquals(16, input.getTotalBytesRead());
508 592
509 try { 593 try {
510 input.readRawByte(); 594 input.readRawByte();
511 fail("Should have thrown an exception!"); 595 fail("Should have thrown an exception!");
512 } catch (InvalidProtocolBufferException expected) { 596 } catch (InvalidProtocolBufferException expected) {
513 checkSizeLimitExceeded(expected); 597 checkSizeLimitExceeded(expected);
514 } 598 }
515 599
516 input.resetSizeCounter(); 600 input.resetSizeCounter();
517 assertEquals(0, input.getTotalBytesRead()); 601 assertEquals(0, input.getTotalBytesRead());
518 input.readRawByte(); // No exception thrown. 602 input.readRawByte(); // No exception thrown.
519 input.resetSizeCounter(); 603 input.resetSizeCounter();
520 assertEquals(0, input.getTotalBytesRead()); 604 assertEquals(0, input.getTotalBytesRead());
521 input.readRawBytes(16); 605 input.readRawBytes(16);
522 assertEquals(16, input.getTotalBytesRead()); 606 assertEquals(16, input.getTotalBytesRead());
523 input.resetSizeCounter(); 607 input.resetSizeCounter();
524 608
525 try { 609 try {
526 input.readRawBytes(17); // Hits limit again. 610 input.readRawBytes(17); // Hits limit again.
527 fail("Should have thrown an exception!"); 611 fail("Should have thrown an exception!");
528 } catch (InvalidProtocolBufferException expected) { 612 } catch (InvalidProtocolBufferException expected) {
529 checkSizeLimitExceeded(expected); 613 checkSizeLimitExceeded(expected);
530 } 614 }
531 } 615 }
532 616
533 public void testSizeLimitMultipleMessages() throws Exception { 617 public void testSizeLimitMultipleMessages() throws Exception {
618 // NOTE: Size limit only applies to the stream-backed CIS.
534 byte[] bytes = new byte[256]; 619 byte[] bytes = new byte[256];
535 for (int i = 0; i < bytes.length; i++) { 620 for (int i = 0; i < bytes.length; i++) {
536 bytes[i] = (byte) i; 621 bytes[i] = (byte) i;
537 } 622 }
538 CodedInputStream input = CodedInputStream.newInstance( 623 CodedInputStream input = CodedInputStream.newInstance(new SmallBlockInputStr eam(bytes, 7));
539 new SmallBlockInputStream(bytes, 7));
540 input.setSizeLimit(16); 624 input.setSizeLimit(16);
541 for (int i = 0; i < 256 / 16; i++) { 625 for (int i = 0; i < 256 / 16; i++) {
542 byte[] message = input.readRawBytes(16); 626 byte[] message = input.readRawBytes(16);
543 for (int j = 0; j < message.length; j++) { 627 for (int j = 0; j < message.length; j++) {
544 assertEquals(i * 16 + j, message[j] & 0xff); 628 assertEquals(i * 16 + j, message[j] & 0xff);
545 } 629 }
546 assertEquals(16, input.getTotalBytesRead()); 630 assertEquals(16, input.getTotalBytesRead());
547 input.resetSizeCounter(); 631 input.resetSizeCounter();
548 assertEquals(0, input.getTotalBytesRead()); 632 assertEquals(0, input.getTotalBytesRead());
549 } 633 }
550 } 634 }
551 635
552 public void testReadString() throws Exception { 636 public void testReadString() throws Exception {
553 String lorem = "Lorem ipsum dolor sit amet "; 637 String lorem = "Lorem ipsum dolor sit amet ";
554 StringBuilder builder = new StringBuilder(); 638 StringBuilder builder = new StringBuilder();
555 for (int i = 0; i < 4096; i += lorem.length()) { 639 for (int i = 0; i < 4096; i += lorem.length()) {
556 builder.append(lorem); 640 builder.append(lorem);
557 } 641 }
558 lorem = builder.toString().substring(0, 4096); 642 lorem = builder.toString().substring(0, 4096);
559 byte[] bytes = lorem.getBytes("UTF-8"); 643 byte[] bytes = lorem.getBytes("UTF-8");
560 ByteString.Output rawOutput = ByteString.newOutput(); 644 ByteString.Output rawOutput = ByteString.newOutput();
561 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth); 645 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth);
562 646
563 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 647 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
564 output.writeRawVarint32(tag); 648 output.writeRawVarint32(tag);
565 output.writeRawVarint32(bytes.length); 649 output.writeRawVarint32(bytes.length);
566 output.writeRawBytes(bytes); 650 output.writeRawBytes(bytes);
567 output.flush(); 651 output.flush();
568 652
569 CodedInputStream input = 653 byte[] rawInput = rawOutput.toByteString().toByteArray();
570 CodedInputStream.newInstance( 654 for (InputType inputType : InputType.values()) {
571 new ByteArrayInputStream(rawOutput.toByteString().toByteArray())); 655 CodedInputStream input = inputType.newDecoder(rawInput);
572 assertEquals(tag, input.readTag()); 656 assertEquals(inputType.name(), tag, input.readTag());
573 String text = input.readString(); 657 String text = input.readString();
574 assertEquals(lorem, text); 658 assertEquals(inputType.name(), lorem, text);
659 }
575 } 660 }
576 661
577 public void testReadStringRequireUtf8() throws Exception { 662 public void testReadStringRequireUtf8() throws Exception {
578 String lorem = "Lorem ipsum dolor sit amet "; 663 String lorem = "Lorem ipsum dolor sit amet ";
579 StringBuilder builder = new StringBuilder(); 664 StringBuilder builder = new StringBuilder();
580 for (int i = 0; i < 4096; i += lorem.length()) { 665 for (int i = 0; i < 4096; i += lorem.length()) {
581 builder.append(lorem); 666 builder.append(lorem);
582 } 667 }
583 lorem = builder.toString().substring(0, 4096); 668 lorem = builder.toString().substring(0, 4096);
584 byte[] bytes = lorem.getBytes("UTF-8"); 669 byte[] bytes = lorem.getBytes("UTF-8");
585 ByteString.Output rawOutput = ByteString.newOutput(); 670 ByteString.Output rawOutput = ByteString.newOutput();
586 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth); 671 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth);
587 672
588 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 673 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
589 output.writeRawVarint32(tag); 674 output.writeRawVarint32(tag);
590 output.writeRawVarint32(bytes.length); 675 output.writeRawVarint32(bytes.length);
591 output.writeRawBytes(bytes); 676 output.writeRawBytes(bytes);
592 output.flush(); 677 output.flush();
593 678
594 CodedInputStream input = 679 byte[] rawInput = rawOutput.toByteString().toByteArray();
595 CodedInputStream.newInstance( 680 for (InputType inputType : InputType.values()) {
596 new ByteArrayInputStream(rawOutput.toByteString().toByteArray())); 681 CodedInputStream input = inputType.newDecoder(rawInput);
597 assertEquals(tag, input.readTag()); 682 assertEquals(inputType.name(), tag, input.readTag());
598 String text = input.readStringRequireUtf8(); 683 String text = input.readStringRequireUtf8();
599 assertEquals(lorem, text); 684 assertEquals(inputType.name(), lorem, text);
685 }
600 } 686 }
601 687
602 /** 688 /**
603 * Tests that if we readString invalid UTF-8 bytes, no exception 689 * Tests that if we readString invalid UTF-8 bytes, no exception is thrown. In stead, the invalid
604 * is thrown. Instead, the invalid bytes are replaced with the Unicode 690 * bytes are replaced with the Unicode "replacement character" U+FFFD.
605 * "replacement character" U+FFFD.
606 */ 691 */
607 public void testReadStringInvalidUtf8() throws Exception { 692 public void testReadStringInvalidUtf8() throws Exception {
608 ByteString.Output rawOutput = ByteString.newOutput(); 693 ByteString.Output rawOutput = ByteString.newOutput();
609 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 694 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
610 695
611 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 696 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
612 output.writeRawVarint32(tag); 697 output.writeRawVarint32(tag);
613 output.writeRawVarint32(1); 698 output.writeRawVarint32(1);
614 output.writeRawBytes(new byte[] { (byte) 0x80 }); 699 output.writeRawBytes(new byte[] {(byte) 0x80});
615 output.flush(); 700 output.flush();
616 701
617 CodedInputStream input = rawOutput.toByteString().newCodedInput(); 702 byte[] rawInput = rawOutput.toByteString().toByteArray();
618 assertEquals(tag, input.readTag()); 703 for (InputType inputType : InputType.values()) {
619 String text = input.readString(); 704 CodedInputStream input = inputType.newDecoder(rawInput);
620 assertEquals(0xfffd, text.charAt(0)); 705 assertEquals(inputType.name(), tag, input.readTag());
706 String text = input.readString();
707 assertEquals(inputType.name(), 0xfffd, text.charAt(0));
708 }
621 } 709 }
622 710
623 /** 711 /**
624 * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an 712 * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an InvalidProto colBufferException
625 * InvalidProtocolBufferException is thrown. 713 * is thrown.
626 */ 714 */
627 public void testReadStringRequireUtf8InvalidUtf8() throws Exception { 715 public void testReadStringRequireUtf8InvalidUtf8() throws Exception {
628 ByteString.Output rawOutput = ByteString.newOutput(); 716 ByteString.Output rawOutput = ByteString.newOutput();
629 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 717 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
630 718
631 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 719 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
632 output.writeRawVarint32(tag); 720 output.writeRawVarint32(tag);
633 output.writeRawVarint32(1); 721 output.writeRawVarint32(1);
634 output.writeRawBytes(new byte[] { (byte) 0x80 }); 722 output.writeRawBytes(new byte[] {(byte) 0x80});
635 output.flush(); 723 output.flush();
636 724
637 CodedInputStream input = rawOutput.toByteString().newCodedInput(); 725 byte[] rawInput = rawOutput.toByteString().toByteArray();
638 assertEquals(tag, input.readTag()); 726 for (InputType inputType : InputType.values()) {
639 try { 727 CodedInputStream input = inputType.newDecoder(rawInput);
640 input.readStringRequireUtf8(); 728 assertEquals(tag, input.readTag());
641 fail("Expected invalid UTF-8 exception."); 729 try {
642 } catch (InvalidProtocolBufferException exception) { 730 input.readStringRequireUtf8();
643 assertEquals("Protocol message had invalid UTF-8.", exception.getMessage() ); 731 fail(inputType.name() + ": Expected invalid UTF-8 exception.");
732 } catch (InvalidProtocolBufferException exception) {
733 assertEquals(
734 inputType.name(), "Protocol message had invalid UTF-8.", exception.g etMessage());
735 }
644 } 736 }
645 } 737 }
646 738
647 public void testReadFromSlice() throws Exception { 739 public void testReadFromSlice() throws Exception {
648 byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); 740 byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
649 CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); 741 CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5);
650 assertEquals(0, in.getTotalBytesRead()); 742 assertEquals(0, in.getTotalBytesRead());
651 for (int i = 3; i < 8; i++) { 743 for (int i = 3; i < 8; i++) {
652 assertEquals(i, in.readRawByte()); 744 assertEquals(i, in.readRawByte());
653 assertEquals(i - 2, in.getTotalBytesRead()); 745 assertEquals(i - 2, in.getTotalBytesRead());
654 } 746 }
655 // eof 747 // eof
656 assertEquals(0, in.readTag()); 748 assertEquals(0, in.readTag());
657 assertEquals(5, in.getTotalBytesRead()); 749 assertEquals(5, in.getTotalBytesRead());
658 } 750 }
659 751
660 public void testInvalidTag() throws Exception { 752 public void testInvalidTag() throws Exception {
661 // Any tag number which corresponds to field number zero is invalid and 753 // Any tag number which corresponds to field number zero is invalid and
662 // should throw InvalidProtocolBufferException. 754 // should throw InvalidProtocolBufferException.
663 for (int i = 0; i < 8; i++) { 755 for (InputType inputType : InputType.values()) {
664 try { 756 for (int i = 0; i < 8; i++) {
665 CodedInputStream.newInstance(bytes(i)).readTag(); 757 try {
666 fail("Should have thrown an exception."); 758 inputType.newDecoder(bytes(i)).readTag();
667 } catch (InvalidProtocolBufferException e) { 759 fail(inputType.name() + ": Should have thrown an exception.");
668 assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(), 760 } catch (InvalidProtocolBufferException e) {
669 e.getMessage()); 761 assertEquals(
762 inputType.name(),
763 InvalidProtocolBufferException.invalidTag().getMessage(),
764 e.getMessage());
765 }
670 } 766 }
671 } 767 }
672 } 768 }
673 769
674 public void testReadByteArray() throws Exception { 770 public void testReadByteArray() throws Exception {
675 ByteString.Output rawOutput = ByteString.newOutput(); 771 ByteString.Output rawOutput = ByteString.newOutput();
676 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 772 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
677 // Zero-sized bytes field. 773 // Zero-sized bytes field.
678 output.writeRawVarint32(0); 774 output.writeRawVarint32(0);
679 // One one-byte bytes field 775 // One one-byte bytes field
680 output.writeRawVarint32(1); 776 output.writeRawVarint32(1);
681 output.writeRawBytes(new byte[] { (byte) 23 }); 777 output.writeRawBytes(new byte[] {(byte) 23});
682 // Another one-byte bytes field 778 // Another one-byte bytes field
683 output.writeRawVarint32(1); 779 output.writeRawVarint32(1);
684 output.writeRawBytes(new byte[] { (byte) 45 }); 780 output.writeRawBytes(new byte[] {(byte) 45});
685 // A bytes field large enough that won't fit into the 4K buffer. 781 // A bytes field large enough that won't fit into the 4K buffer.
686 final int bytesLength = 16 * 1024; 782 final int bytesLength = 16 * 1024;
687 byte[] bytes = new byte[bytesLength]; 783 byte[] bytes = new byte[bytesLength];
688 bytes[0] = (byte) 67; 784 bytes[0] = (byte) 67;
689 bytes[bytesLength - 1] = (byte) 89; 785 bytes[bytesLength - 1] = (byte) 89;
690 output.writeRawVarint32(bytesLength); 786 output.writeRawVarint32(bytesLength);
691 output.writeRawBytes(bytes); 787 output.writeRawBytes(bytes);
692 788
693 output.flush(); 789 output.flush();
694 CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
695 790
696 byte[] result = inputStream.readByteArray(); 791 byte[] rawInput = rawOutput.toByteString().toByteArray();
697 assertEquals(0, result.length); 792 for (InputType inputType : InputType.values()) {
698 result = inputStream.readByteArray(); 793 CodedInputStream inputStream = inputType.newDecoder(rawInput);
699 assertEquals(1, result.length); 794
700 assertEquals((byte) 23, result[0]); 795 byte[] result = inputStream.readByteArray();
701 result = inputStream.readByteArray(); 796 assertEquals(inputType.name(), 0, result.length);
702 assertEquals(1, result.length); 797 result = inputStream.readByteArray();
703 assertEquals((byte) 45, result[0]); 798 assertEquals(inputType.name(), 1, result.length);
704 result = inputStream.readByteArray(); 799 assertEquals(inputType.name(), (byte) 23, result[0]);
705 assertEquals(bytesLength, result.length); 800 result = inputStream.readByteArray();
706 assertEquals((byte) 67, result[0]); 801 assertEquals(inputType.name(), 1, result.length);
707 assertEquals((byte) 89, result[bytesLength - 1]); 802 assertEquals(inputType.name(), (byte) 45, result[0]);
803 result = inputStream.readByteArray();
804 assertEquals(inputType.name(), bytesLength, result.length);
805 assertEquals(inputType.name(), (byte) 67, result[0]);
806 assertEquals(inputType.name(), (byte) 89, result[bytesLength - 1]);
807 }
708 } 808 }
709 809
710 public void testReadByteBuffer() throws Exception { 810 public void testReadByteBuffer() throws Exception {
711 ByteString.Output rawOutput = ByteString.newOutput(); 811 ByteString.Output rawOutput = ByteString.newOutput();
712 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 812 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
713 // Zero-sized bytes field. 813 // Zero-sized bytes field.
714 output.writeRawVarint32(0); 814 output.writeRawVarint32(0);
715 // One one-byte bytes field 815 // One one-byte bytes field
716 output.writeRawVarint32(1); 816 output.writeRawVarint32(1);
717 output.writeRawBytes(new byte[]{(byte) 23}); 817 output.writeRawBytes(new byte[] {(byte) 23});
718 // Another one-byte bytes field 818 // Another one-byte bytes field
719 output.writeRawVarint32(1); 819 output.writeRawVarint32(1);
720 output.writeRawBytes(new byte[]{(byte) 45}); 820 output.writeRawBytes(new byte[] {(byte) 45});
721 // A bytes field large enough that won't fit into the 4K buffer. 821 // A bytes field large enough that won't fit into the 4K buffer.
722 final int bytesLength = 16 * 1024; 822 final int bytesLength = 16 * 1024;
723 byte[] bytes = new byte[bytesLength]; 823 byte[] bytes = new byte[bytesLength];
724 bytes[0] = (byte) 67; 824 bytes[0] = (byte) 67;
725 bytes[bytesLength - 1] = (byte) 89; 825 bytes[bytesLength - 1] = (byte) 89;
726 output.writeRawVarint32(bytesLength); 826 output.writeRawVarint32(bytesLength);
727 output.writeRawBytes(bytes); 827 output.writeRawBytes(bytes);
728 828
729 output.flush(); 829 output.flush();
730 CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
731 830
732 ByteBuffer result = inputStream.readByteBuffer(); 831 byte[] rawInput = rawOutput.toByteString().toByteArray();
733 assertEquals(0, result.capacity()); 832 for (InputType inputType : InputType.values()) {
734 result = inputStream.readByteBuffer(); 833 CodedInputStream inputStream = inputType.newDecoder(rawInput);
735 assertEquals(1, result.capacity()); 834
736 assertEquals((byte) 23, result.get()); 835 ByteBuffer result = inputStream.readByteBuffer();
737 result = inputStream.readByteBuffer(); 836 assertEquals(inputType.name(), 0, result.capacity());
738 assertEquals(1, result.capacity()); 837 result = inputStream.readByteBuffer();
739 assertEquals((byte) 45, result.get()); 838 assertEquals(inputType.name(), 1, result.capacity());
740 result = inputStream.readByteBuffer(); 839 assertEquals(inputType.name(), (byte) 23, result.get());
741 assertEquals(bytesLength, result.capacity()); 840 result = inputStream.readByteBuffer();
742 assertEquals((byte) 67, result.get()); 841 assertEquals(inputType.name(), 1, result.capacity());
743 result.position(bytesLength - 1); 842 assertEquals(inputType.name(), (byte) 45, result.get());
744 assertEquals((byte) 89, result.get()); 843 result = inputStream.readByteBuffer();
844 assertEquals(inputType.name(), bytesLength, result.capacity());
845 assertEquals(inputType.name(), (byte) 67, result.get());
846 result.position(bytesLength - 1);
847 assertEquals(inputType.name(), (byte) 89, result.get());
848 }
745 } 849 }
746 850
747 public void testReadByteBufferAliasing() throws Exception { 851 public void testReadByteBufferAliasing() throws Exception {
748 ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); 852 ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
749 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream); 853 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
750 // Zero-sized bytes field. 854 // Zero-sized bytes field.
751 output.writeRawVarint32(0); 855 output.writeRawVarint32(0);
752 // One one-byte bytes field 856 // One one-byte bytes field
753 output.writeRawVarint32(1); 857 output.writeRawVarint32(1);
754 output.writeRawBytes(new byte[]{(byte) 23}); 858 output.writeRawBytes(new byte[] {(byte) 23});
755 // Another one-byte bytes field 859 // Another one-byte bytes field
756 output.writeRawVarint32(1); 860 output.writeRawVarint32(1);
757 output.writeRawBytes(new byte[]{(byte) 45}); 861 output.writeRawBytes(new byte[] {(byte) 45});
758 // A bytes field large enough that won't fit into the 4K buffer. 862 // A bytes field large enough that won't fit into the 4K buffer.
759 final int bytesLength = 16 * 1024; 863 final int bytesLength = 16 * 1024;
760 byte[] bytes = new byte[bytesLength]; 864 byte[] bytes = new byte[bytesLength];
761 bytes[0] = (byte) 67; 865 bytes[0] = (byte) 67;
762 bytes[bytesLength - 1] = (byte) 89; 866 bytes[bytesLength - 1] = (byte) 89;
763 output.writeRawVarint32(bytesLength); 867 output.writeRawVarint32(bytesLength);
764 output.writeRawBytes(bytes); 868 output.writeRawBytes(bytes);
765 output.flush(); 869 output.flush();
870
766 byte[] data = byteArrayStream.toByteArray(); 871 byte[] data = byteArrayStream.toByteArray();
767 872
768 // Without aliasing 873 for (InputType inputType : InputType.values()) {
769 CodedInputStream inputStream = CodedInputStream.newInstance(data); 874 if (inputType == InputType.STREAM) {
770 ByteBuffer result = inputStream.readByteBuffer(); 875 // Aliasing doesn't apply to stream-backed CIS.
771 assertEquals(0, result.capacity()); 876 continue;
772 result = inputStream.readByteBuffer(); 877 }
773 assertTrue(result.array() != data);
774 assertEquals(1, result.capacity());
775 assertEquals((byte) 23, result.get());
776 result = inputStream.readByteBuffer();
777 assertTrue(result.array() != data);
778 assertEquals(1, result.capacity());
779 assertEquals((byte) 45, result.get());
780 result = inputStream.readByteBuffer();
781 assertTrue(result.array() != data);
782 assertEquals(bytesLength, result.capacity());
783 assertEquals((byte) 67, result.get());
784 result.position(bytesLength - 1);
785 assertEquals((byte) 89, result.get());
786 878
787 // Enable aliasing 879 // Without aliasing
788 inputStream = CodedInputStream.newInstance(data); 880 CodedInputStream inputStream = inputType.newDecoder(data);
789 inputStream.enableAliasing(true); 881 ByteBuffer result = inputStream.readByteBuffer();
790 result = inputStream.readByteBuffer(); 882 assertEquals(inputType.name(), 0, result.capacity());
791 assertEquals(0, result.capacity()); 883 result = inputStream.readByteBuffer();
792 result = inputStream.readByteBuffer(); 884 assertTrue(inputType.name(), result.array() != data);
793 assertTrue(result.array() == data); 885 assertEquals(inputType.name(), 1, result.capacity());
794 assertEquals(1, result.capacity()); 886 assertEquals(inputType.name(), (byte) 23, result.get());
795 assertEquals((byte) 23, result.get()); 887 result = inputStream.readByteBuffer();
796 result = inputStream.readByteBuffer(); 888 assertTrue(inputType.name(), result.array() != data);
797 assertTrue(result.array() == data); 889 assertEquals(inputType.name(), 1, result.capacity());
798 assertEquals(1, result.capacity()); 890 assertEquals(inputType.name(), (byte) 45, result.get());
799 assertEquals((byte) 45, result.get()); 891 result = inputStream.readByteBuffer();
800 result = inputStream.readByteBuffer(); 892 assertTrue(inputType.name(), result.array() != data);
801 assertTrue(result.array() == data); 893 assertEquals(inputType.name(), bytesLength, result.capacity());
802 assertEquals(bytesLength, result.capacity()); 894 assertEquals(inputType.name(), (byte) 67, result.get());
803 assertEquals((byte) 67, result.get()); 895 result.position(bytesLength - 1);
804 result.position(bytesLength - 1); 896 assertEquals(inputType.name(), (byte) 89, result.get());
805 assertEquals((byte) 89, result.get()); 897
898 // Enable aliasing
899 inputStream = inputType.newDecoder(data);
900 inputStream.enableAliasing(true);
901 result = inputStream.readByteBuffer();
902 assertEquals(inputType.name(), 0, result.capacity());
903 result = inputStream.readByteBuffer();
904 if (result.hasArray()) {
905 assertTrue(inputType.name(), result.array() == data);
906 }
907 assertEquals(inputType.name(), 1, result.capacity());
908 assertEquals(inputType.name(), (byte) 23, result.get());
909 result = inputStream.readByteBuffer();
910 if (result.hasArray()) {
911 assertTrue(inputType.name(), result.array() == data);
912 }
913 assertEquals(inputType.name(), 1, result.capacity());
914 assertEquals(inputType.name(), (byte) 45, result.get());
915 result = inputStream.readByteBuffer();
916 if (result.hasArray()) {
917 assertTrue(inputType.name(), result.array() == data);
918 }
919 assertEquals(inputType.name(), bytesLength, result.capacity());
920 assertEquals(inputType.name(), (byte) 67, result.get());
921 result.position(bytesLength - 1);
922 assertEquals(inputType.name(), (byte) 89, result.get());
923 }
806 } 924 }
807 925
808 public void testCompatibleTypes() throws Exception { 926 public void testCompatibleTypes() throws Exception {
809 long data = 0x100000000L; 927 long data = 0x100000000L;
810 Int64Message message = Int64Message.newBuilder().setData(data).build(); 928 Int64Message message = Int64Message.newBuilder().setData(data).build();
811 ByteString serialized = message.toByteString(); 929 byte[] serialized = message.toByteArray();
930 for (InputType inputType : InputType.values()) {
931 CodedInputStream inputStream = inputType.newDecoder(serialized);
812 932
813 // Test int64(long) is compatible with bool(boolean) 933 // Test int64(long) is compatible with bool(boolean)
814 BoolMessage msg2 = BoolMessage.parseFrom(serialized); 934 BoolMessage msg2 = BoolMessage.parseFrom(inputStream);
815 assertTrue(msg2.getData()); 935 assertTrue(msg2.getData());
816 936
817 // Test int64(long) is compatible with int32(int) 937 // Test int64(long) is compatible with int32(int)
818 Int32Message msg3 = Int32Message.parseFrom(serialized); 938 inputStream = inputType.newDecoder(serialized);
819 assertEquals((int) data, msg3.getData()); 939 Int32Message msg3 = Int32Message.parseFrom(inputStream);
940 assertEquals((int) data, msg3.getData());
941 }
942 }
943
944 public void testSkipInvalidVarint_FastPath() throws Exception {
945 // Fast path: We have >= 10 bytes available. Ensure we properly recognize a non-ending varint.
946 byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0};
947 for (InputType inputType : InputType.values()) {
948 try {
949 CodedInputStream input = inputType.newDecoder(data);
950 input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT));
951 fail(inputType.name() + ": Should have thrown an exception.");
952 } catch (InvalidProtocolBufferException e) {
953 // Expected
954 }
955 }
956 }
957
958 public void testSkipInvalidVarint_SlowPath() throws Exception {
959 // Slow path: < 10 bytes available. Ensure we properly recognize a non-endin g varint.
960 byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1};
961 for (InputType inputType : InputType.values()) {
962 try {
963 CodedInputStream input = inputType.newDecoder(data);
964 input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT));
965 fail(inputType.name() + ": Should have thrown an exception.");
966 } catch (InvalidProtocolBufferException e) {
967 // Expected
968 }
969 }
820 } 970 }
821 } 971 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698