15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h> 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/test_util_lite.h> 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/unittest_lite.pb.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace std; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace { 43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Helper methods to test parsing merge behavior. 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(message.optional_int32() == 3); 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(message.optional_int64() == 2); 47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(message.optional_string() == "hello"); 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid AssignParsingMergeMessages( 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg1, 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg2, 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg3) { 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg1->set_optional_int32(1); 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg2->set_optional_int64(2); 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg3->set_optional_int32(3); 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg3->set_optional_string("hello"); 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char* argv[]) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string data, packed_data; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protobuf_unittest::TestAllTypesLite message, message2, message3; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectClear(message); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::SetAllFields(&message); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message2.CopyFrom(message); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = message.SerializeAsString(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message3.ParseFromString(data); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.Clear(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectClear(message); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protobuf_unittest::TestAllExtensionsLite message, message2, message3; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::SetAllExtensions(&message); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message2.CopyFrom(message); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string extensions_data = message.SerializeAsString(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(extensions_data == data); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message3.ParseFromString(extensions_data); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.Clear(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protobuf_unittest::TestPackedTypesLite message, message2, message3; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedClear(message); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::SetPackedFields(&message); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message2.CopyFrom(message); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packed_data = message.SerializeAsString(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message3.ParseFromString(packed_data); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ModifyPackedFields(&message); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.Clear(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedClear(message); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protobuf_unittest::TestPackedExtensionsLite message, message2, message3; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::SetPackedExtensions(&message); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message2.CopyFrom(message); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string packed_extensions_data = message.SerializeAsString(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(packed_extensions_data == packed_data); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message3.ParseFromString(packed_extensions_data); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.Clear(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch { 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Test that if an optional or required message/group field appears multiple 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // times in the input, they need to be merged. 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator; 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg1; 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg2; 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestAllTypesLite* msg3; 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define ASSIGN_REPEATED_FIELD(FIELD) \ 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg1 = generator.add_##FIELD(); \ 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg2 = generator.add_##FIELD(); \ 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg3 = generator.add_##FIELD(); \ 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AssignParsingMergeMessages(msg1, msg2, msg3) 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_FIELD(field1); 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_FIELD(field2); 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_FIELD(field3); 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_FIELD(ext1); 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_FIELD(ext2); 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#undef ASSIGN_REPEATED_FIELD 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define ASSIGN_REPEATED_GROUP(FIELD) \ 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg1 = generator.add_##FIELD()->mutable_field1(); \ 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg2 = generator.add_##FIELD()->mutable_field1(); \ 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch msg3 = generator.add_##FIELD()->mutable_field1(); \ 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AssignParsingMergeMessages(msg1, msg2, msg3) 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_GROUP(group1); 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ASSIGN_REPEATED_GROUP(group2); 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#undef ASSIGN_REPEATED_GROUP 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string buffer; 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch generator.SerializeToString(&buffer); 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestParsingMergeLite parsing_merge; 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch parsing_merge.ParseFromString(buffer); 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Required and optional fields should be merged. 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExpectMessageMerged(parsing_merge.required_all_types()); 170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExpectMessageMerged(parsing_merge.optional_all_types()); 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExpectMessageMerged( 172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch parsing_merge.optionalgroup().optional_group_all_types()); 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExpectMessageMerged(parsing_merge.GetExtension( 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestParsingMergeLite::optional_ext)); 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Repeated fields should not be merged. 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3); 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3); 179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(parsing_merge.ExtensionSize( 180ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3); 181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 182ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cout << "PASS" << endl; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 186