blob: af4130b28cd868959c9828cd02df3a2ba149775c [file] [log] [blame]
Michael Wachenschwanzd3538562019-03-14 12:02:50 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.test.protoinputstream;
18
19import android.util.proto.ProtoInputStream;
20import android.util.proto.ProtoStream;
21import android.util.proto.WireTypeMismatchException;
22
23import com.android.test.protoinputstream.nano.Test;
24
25import com.google.protobuf.nano.MessageNano;
26
27import junit.framework.TestCase;
28
29import java.io.ByteArrayInputStream;
30import java.io.IOException;
31import java.io.InputStream;
32
33public class ProtoInputStreamFixed64Test extends TestCase {
34
35 public void testRead() throws IOException {
36 testRead(0);
37 testRead(1);
38 testRead(5);
39 }
40
41 private void testRead(int chunkSize) throws IOException {
42 final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
43
44 final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
45 final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
46 final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
47 final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
48 final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
49 final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
50 final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
51 final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
52
53 final byte[] protobuf = new byte[]{
54 // 1 -> 0 - default value, not written
55 // 2 -> 1
56 (byte) 0x11,
57 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
58 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
59 // 6 -> 1
60 (byte) 0x41,
61 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
62 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
63 // 3 -> -1
64 (byte) 0x19,
65 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
66 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
67 // 4 -> Integer.MIN_VALUE
68 (byte) 0x21,
69 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
70 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
71 // 5 -> Integer.MAX_VALUE
72 (byte) 0x29,
73 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
74 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
75 // 6 -> Long.MIN_VALUE
76 (byte) 0x31,
77 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
78 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
79 // 7 -> Long.MAX_VALUE
80 (byte) 0x39,
81 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
82 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
83 };
84
85 InputStream stream = new ByteArrayInputStream(protobuf);
86 final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
87 long[] results = new long[7];
88 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
89 switch (pi.getFieldNumber()) {
90 case (int) fieldId1:
91 fail("Should never reach this");
92 break;
93 case (int) fieldId2:
94 results[1] = pi.readLong(fieldId2);
95 break;
96 case (int) fieldId3:
97 results[2] = pi.readLong(fieldId3);
98 break;
99 case (int) fieldId4:
100 results[3] = pi.readLong(fieldId4);
101 break;
102 case (int) fieldId5:
103 results[4] = pi.readLong(fieldId5);
104 break;
105 case (int) fieldId6:
106 results[5] = pi.readLong(fieldId6);
107 break;
108 case (int) fieldId7:
109 results[6] = pi.readLong(fieldId7);
110 break;
111 case (int) fieldId8:
112 // Intentionally don't read the data. Parse should continue normally
113 break;
114 default:
115 fail("Unexpected field id " + pi.getFieldNumber());
116 }
117 }
118 stream.close();
119
120 assertEquals(0, results[0]);
121 assertEquals(1, results[1]);
122 assertEquals(-1, results[2]);
123 assertEquals(Integer.MIN_VALUE, results[3]);
124 assertEquals(Integer.MAX_VALUE, results[4]);
125 assertEquals(Long.MIN_VALUE, results[5]);
126 assertEquals(Long.MAX_VALUE, results[6]);
127 }
128
129 /**
130 * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
131 */
132 public void testReadCompat() throws Exception {
133 testReadCompat(0);
134 testReadCompat(1);
135 testReadCompat(-1);
136 testReadCompat(Integer.MIN_VALUE);
137 testReadCompat(Integer.MAX_VALUE);
138 testReadCompat(Long.MIN_VALUE);
139 testReadCompat(Long.MAX_VALUE);
140 }
141
142 /**
143 * Implementation of testReadCompat with a given value.
144 */
145 private void testReadCompat(long val) throws Exception {
146 final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
147 final long fieldId = fieldFlags | ((long) 100 & 0x0ffffffffL);
148
149 final Test.All all = new Test.All();
150 all.fixed64Field = val;
151
152 final byte[] proto = MessageNano.toByteArray(all);
153
154 final ProtoInputStream pi = new ProtoInputStream(proto);
155 final Test.All readback = Test.All.parseFrom(proto);
156
157 long result = 0; // start off with default value
158 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
159 switch (pi.getFieldNumber()) {
160 case (int) fieldId:
161 result = pi.readLong(fieldId);
162 break;
163 default:
164 fail("Unexpected field id " + pi.getFieldNumber());
165 }
166 }
167
168 assertEquals(readback.fixed64Field, result);
169 }
170
171 public void testRepeated() throws IOException {
172 testRepeated(0);
173 testRepeated(1);
174 testRepeated(5);
175 }
176
177 private void testRepeated(int chunkSize) throws IOException {
178 final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
179
180 final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
181 final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
182 final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
183 final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
184 final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
185 final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
186 final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
187 final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
188
189 final byte[] protobuf = new byte[]{
190 // 1 -> 0 - default value, written when repeated
191 (byte) 0x09,
192 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
193 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
194 // 2 -> 1
195 (byte) 0x11,
196 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
197 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
198 // 3 -> -1
199 (byte) 0x19,
200 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
201 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
202 // 4 -> Integer.MIN_VALUE
203 (byte) 0x21,
204 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
205 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
206 // 5 -> Integer.MAX_VALUE
207 (byte) 0x29,
208 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
209 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
210 // 6 -> Long.MIN_VALUE
211 (byte) 0x31,
212 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
213 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
214 // 7 -> Long.MAX_VALUE
215 (byte) 0x39,
216 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
217 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
218
219 // 8 -> 1
220 (byte) 0x41,
221 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
222 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
223
224 // 1 -> 0 - default value, written when repeated
225 (byte) 0x09,
226 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
227 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
228 // 2 -> 1
229 (byte) 0x11,
230 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
231 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
232 // 3 -> -1
233 (byte) 0x19,
234 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
235 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
236 // 4 -> Integer.MIN_VALUE
237 (byte) 0x21,
238 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
239 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
240 // 5 -> Integer.MAX_VALUE
241 (byte) 0x29,
242 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
243 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
244 // 6 -> Long.MIN_VALUE
245 (byte) 0x31,
246 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
247 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
248 // 7 -> Long.MAX_VALUE
249 (byte) 0x39,
250 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
251 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
252 };
253
254 InputStream stream = new ByteArrayInputStream(protobuf);
255 final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
256 long[][] results = new long[7][2];
257 int[] indices = new int[7];
258 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
259
260 switch (pi.getFieldNumber()) {
261 case (int) fieldId1:
262 results[0][indices[0]++] = pi.readLong(fieldId1);
263 break;
264 case (int) fieldId2:
265 results[1][indices[1]++] = pi.readLong(fieldId2);
266 break;
267 case (int) fieldId3:
268 results[2][indices[2]++] = pi.readLong(fieldId3);
269 break;
270 case (int) fieldId4:
271 results[3][indices[3]++] = pi.readLong(fieldId4);
272 break;
273 case (int) fieldId5:
274 results[4][indices[4]++] = pi.readLong(fieldId5);
275 break;
276 case (int) fieldId6:
277 results[5][indices[5]++] = pi.readLong(fieldId6);
278 break;
279 case (int) fieldId7:
280 results[6][indices[6]++] = pi.readLong(fieldId7);
281 break;
282 case (int) fieldId8:
283 // Intentionally don't read the data. Parse should continue normally
284 break;
285 default:
286 fail("Unexpected field id " + pi.getFieldNumber());
287 }
288 }
289 stream.close();
290
291 assertEquals(0, results[0][0]);
292 assertEquals(0, results[0][1]);
293 assertEquals(1, results[1][0]);
294 assertEquals(1, results[1][1]);
295 assertEquals(-1, results[2][0]);
296 assertEquals(-1, results[2][1]);
297 assertEquals(Integer.MIN_VALUE, results[3][0]);
298 assertEquals(Integer.MIN_VALUE, results[3][1]);
299 assertEquals(Integer.MAX_VALUE, results[4][0]);
300 assertEquals(Integer.MAX_VALUE, results[4][1]);
301 assertEquals(Long.MIN_VALUE, results[5][0]);
302 assertEquals(Long.MIN_VALUE, results[5][1]);
303 assertEquals(Long.MAX_VALUE, results[6][0]);
304 assertEquals(Long.MAX_VALUE, results[6][1]);
305 }
306
307 /**
308 * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
309 */
310 public void testRepeatedCompat() throws Exception {
311 testRepeatedCompat(new long[0]);
312 testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
313 }
314
315 /**
316 * Implementation of testRepeatedCompat with a given value.
317 */
318 private void testRepeatedCompat(long[] val) throws Exception {
319 final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
320 final long fieldId = fieldFlags | ((long) 101 & 0x0ffffffffL);
321
322 final Test.All all = new Test.All();
323 all.fixed64FieldRepeated = val;
324
325 final byte[] proto = MessageNano.toByteArray(all);
326
327 final ProtoInputStream pi = new ProtoInputStream(proto);
328 final Test.All readback = Test.All.parseFrom(proto);
329
330 long[] result = new long[val.length];
331 int index = 0;
332 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
333 switch (pi.getFieldNumber()) {
334 case (int) fieldId:
335 result[index++] = pi.readLong(fieldId);
336 break;
337 default:
338 fail("Unexpected field id " + pi.getFieldNumber());
339 }
340 }
341
342 assertEquals(readback.fixed64FieldRepeated.length, result.length);
343 for (int i = 0; i < result.length; i++) {
344 assertEquals(readback.fixed64FieldRepeated[i], result[i]);
345 }
346 }
347
348 public void testPacked() throws IOException {
349 testPacked(0);
350 testPacked(1);
351 testPacked(5);
352 }
353
354 private void testPacked(int chunkSize) throws IOException {
355 final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_FIXED64;
356
357 final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
358 final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
359 final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
360 final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
361 final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
362 final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
363 final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
364 final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
365
366 final byte[] protobuf = new byte[]{
367 // 1 -> 0 - default value, written when repeated
368 (byte) 0x0a,
369 (byte) 0x10,
370 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
371 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
372 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
373 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
374 // 2 -> 1
375 (byte) 0x12,
376 (byte) 0x10,
377 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
378 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
379 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
380 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
381 // 8 -> 1
382 (byte) 0x42,
383 (byte) 0x10,
384 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
385 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
386 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
387 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
388 // 3 -> -1
389 (byte) 0x1a,
390 (byte) 0x10,
391 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
392 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
393 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
394 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
395 // 4 -> Integer.MIN_VALUE
396 (byte) 0x22,
397 (byte) 0x10,
398 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
399 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
400 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
401 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
402 // 5 -> Integer.MAX_VALUE
403 (byte) 0x2a,
404 (byte) 0x10,
405 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
406 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
407 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
408 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
409 // 6 -> Long.MIN_VALUE
410 (byte) 0x32,
411 (byte) 0x10,
412 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
413 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
414 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
415 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
416 // 7 -> Long.MAX_VALUE
417 (byte) 0x3a,
418 (byte) 0x10,
419 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
420 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
421 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
422 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
423 };
424
425 InputStream stream = new ByteArrayInputStream(protobuf);
426 final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
427 long[][] results = new long[7][2];
428 int[] indices = new int[7];
429 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
430
431 switch (pi.getFieldNumber()) {
432 case (int) fieldId1:
433 results[0][indices[0]++] = pi.readLong(fieldId1);
434 break;
435 case (int) fieldId2:
436 results[1][indices[1]++] = pi.readLong(fieldId2);
437 break;
438 case (int) fieldId3:
439 results[2][indices[2]++] = pi.readLong(fieldId3);
440 break;
441 case (int) fieldId4:
442 results[3][indices[3]++] = pi.readLong(fieldId4);
443 break;
444 case (int) fieldId5:
445 results[4][indices[4]++] = pi.readLong(fieldId5);
446 break;
447 case (int) fieldId6:
448 results[5][indices[5]++] = pi.readLong(fieldId6);
449 break;
450 case (int) fieldId7:
451 results[6][indices[6]++] = pi.readLong(fieldId7);
452 break;
453 case (int) fieldId8:
454 // Intentionally don't read the data. Parse should continue normally
455 break;
456 default:
457 fail("Unexpected field id " + pi.getFieldNumber());
458 }
459 }
460 stream.close();
461
462 assertEquals(0, results[0][0]);
463 assertEquals(0, results[0][1]);
464 assertEquals(1, results[1][0]);
465 assertEquals(1, results[1][1]);
466 assertEquals(-1, results[2][0]);
467 assertEquals(-1, results[2][1]);
468 assertEquals(Integer.MIN_VALUE, results[3][0]);
469 assertEquals(Integer.MIN_VALUE, results[3][1]);
470 assertEquals(Integer.MAX_VALUE, results[4][0]);
471 assertEquals(Integer.MAX_VALUE, results[4][1]);
472 assertEquals(Long.MIN_VALUE, results[5][0]);
473 assertEquals(Long.MIN_VALUE, results[5][1]);
474 assertEquals(Long.MAX_VALUE, results[6][0]);
475 assertEquals(Long.MAX_VALUE, results[6][1]);
476 }
477
478 /**
479 * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
480 */
481 public void testPackedCompat() throws Exception {
482 testPackedCompat(new long[0]);
483 testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
484 }
485
486 /**
487 * Implementation of testRepeatedCompat with a given value.
488 */
489 private void testPackedCompat(long[] val) throws Exception {
490 final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
491 final long fieldId = fieldFlags | ((long) 102 & 0x0ffffffffL);
492
493 final Test.All all = new Test.All();
494 all.fixed64FieldPacked = val;
495
496 final byte[] proto = MessageNano.toByteArray(all);
497
498 final ProtoInputStream pi = new ProtoInputStream(proto);
499 final Test.All readback = Test.All.parseFrom(proto);
500
501 long[] result = new long[val.length];
502 int index = 0;
503 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
504 switch (pi.getFieldNumber()) {
505 case (int) fieldId:
506 result[index++] = pi.readLong(fieldId);
507 break;
508 default:
509 fail("Unexpected field id " + pi.getFieldNumber());
510 }
511 }
512
513 assertEquals(readback.fixed64FieldPacked.length, result.length);
514 for (int i = 0; i < result.length; i++) {
515 assertEquals(readback.fixed64FieldPacked[i], result[i]);
516 }
517 }
518
519 /**
520 * Test that using the wrong read method throws an exception
521 */
522 public void testBadReadType() throws IOException {
523 final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
524
525 final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
526
527 final byte[] protobuf = new byte[]{
528 // 1 -> 1
529 (byte) 0x09,
530 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
531 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
532 };
533
534 ProtoInputStream pi = new ProtoInputStream(protobuf);
535 pi.isNextField(fieldId1);
536 try {
537 pi.readFloat(fieldId1);
538 fail("Should have throw IllegalArgumentException");
539 } catch (IllegalArgumentException iae) {
540 // good
541 }
542
543 pi = new ProtoInputStream(protobuf);
544 pi.isNextField(fieldId1);
545 try {
546 pi.readDouble(fieldId1);
547 fail("Should have throw IllegalArgumentException");
548 } catch (IllegalArgumentException iae) {
549 // good
550 }
551
552 pi = new ProtoInputStream(protobuf);
553 pi.isNextField(fieldId1);
554 try {
555 pi.readInt(fieldId1);
556 fail("Should have throw IllegalArgumentException");
557 } catch (IllegalArgumentException iae) {
558 // good
559 }
560
561 pi = new ProtoInputStream(protobuf);
562 pi.isNextField(fieldId1);
563 try {
564 pi.readBoolean(fieldId1);
565 fail("Should have throw IllegalArgumentException");
566 } catch (IllegalArgumentException iae) {
567 // good
568 }
569
570 pi = new ProtoInputStream(protobuf);
571 pi.isNextField(fieldId1);
572 try {
573 pi.readBytes(fieldId1);
574 fail("Should have throw IllegalArgumentException");
575 } catch (IllegalArgumentException iae) {
576 // good
577 }
578
579 pi = new ProtoInputStream(protobuf);
580 pi.isNextField(fieldId1);
581 try {
582 pi.readString(fieldId1);
583 fail("Should have throw IllegalArgumentException");
584 } catch (IllegalArgumentException iae) {
585 // good
586 }
587 }
588
589 /**
590 * Test that unexpected wrong wire types will throw an exception
591 */
592 public void testBadWireType() throws IOException {
593 final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
594
595 final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
596 final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
597 final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
598 final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
599
600 final byte[] protobuf = new byte[]{
601 // 1 : varint -> 1
602 (byte) 0x08,
603 (byte) 0x01,
604 // 2 : fixed64 -> 0x1
605 (byte) 0x11,
606 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
607 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
608 // 3 : length delimited -> { 1 }
609 (byte) 0x1a,
610 (byte) 0x08,
611 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
612 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
613 // 6 : fixed32
614 (byte) 0x35,
615 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
616 };
617
618 InputStream stream = new ByteArrayInputStream(protobuf);
619 final ProtoInputStream pi = new ProtoInputStream(stream);
620
621 while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
622 try {
623 switch (pi.getFieldNumber()) {
624 case (int) fieldId1:
625 pi.readLong(fieldId1);
626 fail("Should have thrown a WireTypeMismatchException");
627 break;
628 case (int) fieldId2:
629 pi.readLong(fieldId2);
630 // don't fail, fixed64 is ok
631 break;
632 case (int) fieldId3:
633 pi.readLong(fieldId3);
634 // don't fail, length delimited is ok (represents packed fixed64)
635 break;
636 case (int) fieldId6:
637 pi.readLong(fieldId6);
638 fail("Should have thrown a WireTypeMismatchException");
639 break;
640 default:
641 fail("Unexpected field id " + pi.getFieldNumber());
642 }
643 } catch (WireTypeMismatchException wtme) {
644 // good
645 }
646 }
647 stream.close();
648 }
649}