1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 30 31 package com.google.protobuf; 32 33 import protobuf_unittest.UnittestProto; 34 import java.io.IOException; 35 import junit.framework.TestCase; 36 37 /** 38 * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to strings works correctly. 39 * 40 * @author jonp@google.com (Jon Perlow) 41 */ 42 public class LazyStringEndToEndTest extends TestCase { 43 44 private static final ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 = 45 ByteString.copyFrom( 46 new byte[] { 47 114, 4, -1, 0, -1, 0, -30, 2, 4, -1, 48 0, -1, 0, -30, 2, 4, -1, 0, -1, 0, 49 }); 50 51 private ByteString encodedTestAllTypes; 52 53 @Override setUp()54 protected void setUp() throws Exception { 55 super.setUp(); 56 this.encodedTestAllTypes = 57 UnittestProto.TestAllTypes.newBuilder() 58 .setOptionalString("foo") 59 .addRepeatedString("bar") 60 .addRepeatedString("baz") 61 .build() 62 .toByteString(); 63 } 64 65 /** Tests that an invalid UTF8 string will roundtrip through a parse and serialization. */ testParseAndSerialize()66 public void testParseAndSerialize() throws InvalidProtocolBufferException { 67 UnittestProto.TestAllTypes tV2 = 68 UnittestProto.TestAllTypes.parseFrom(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); 69 ByteString bytes = tV2.toByteString(); 70 assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); 71 72 tV2.getOptionalString(); 73 bytes = tV2.toByteString(); 74 assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); 75 } 76 testParseAndWrite()77 public void testParseAndWrite() throws IOException { 78 UnittestProto.TestAllTypes tV2 = 79 UnittestProto.TestAllTypes.parseFrom(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); 80 byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()]; 81 CodedOutputStream outputStream = CodedOutputStream.newInstance(sink); 82 tV2.writeTo(outputStream); 83 outputStream.flush(); 84 assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, ByteString.copyFrom(sink)); 85 } 86 testCaching()87 public void testCaching() { 88 String a = "a"; 89 String b = "b"; 90 String c = "c"; 91 UnittestProto.TestAllTypes proto = 92 UnittestProto.TestAllTypes.newBuilder() 93 .setOptionalString(a) 94 .addRepeatedString(b) 95 .addRepeatedString(c) 96 .build(); 97 98 // String should be the one we passed it. 99 assertSame(a, proto.getOptionalString()); 100 assertSame(b, proto.getRepeatedString(0)); 101 assertSame(c, proto.getRepeatedString(1)); 102 103 // Ensure serialization keeps strings cached. 104 proto.toByteString(); 105 106 // And now the string should stay cached. 107 assertSame(a, proto.getOptionalString()); 108 assertSame(b, proto.getRepeatedString(0)); 109 assertSame(c, proto.getRepeatedString(1)); 110 } 111 testNoStringCachingIfOnlyBytesAccessed()112 public void testNoStringCachingIfOnlyBytesAccessed() throws Exception { 113 UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.parseFrom(encodedTestAllTypes); 114 ByteString optional = proto.getOptionalStringBytes(); 115 assertSame(optional, proto.getOptionalStringBytes()); 116 assertSame(optional, proto.toBuilder().getOptionalStringBytes()); 117 118 ByteString repeated0 = proto.getRepeatedStringBytes(0); 119 ByteString repeated1 = proto.getRepeatedStringBytes(1); 120 assertSame(repeated0, proto.getRepeatedStringBytes(0)); 121 assertSame(repeated1, proto.getRepeatedStringBytes(1)); 122 assertSame(repeated0, proto.toBuilder().getRepeatedStringBytes(0)); 123 assertSame(repeated1, proto.toBuilder().getRepeatedStringBytes(1)); 124 } 125 } 126