From 596cd889fac4e74dfd5785b24ea3cceded038970 Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Sun, 8 Jan 2012 23:12:10 -0600 Subject: [PATCH] Removed NetHook. --- Resources/NetHook/DataDumper.cpp | 145 - Resources/NetHook/DataDumper.h | 40 - Resources/NetHook/NetHook.sln | 20 - Resources/NetHook/NetHook.vcproj | 863 -- Resources/NetHook/NetHook.vcxproj | 268 - Resources/NetHook/NetHook.vcxproj.filters | 526 -- Resources/NetHook/clientapp.cpp | 43 - Resources/NetHook/clientapp.h | 31 - Resources/NetHook/crypto.cpp | 173 - Resources/NetHook/crypto.h | 43 - Resources/NetHook/csimpledetour.cpp | 34 - Resources/NetHook/csimpledetour.h | 56 - Resources/NetHook/csimplescan.cpp | 44 - Resources/NetHook/csimplescan.h | 25 - Resources/NetHook/detours.h | 532 -- Resources/NetHook/detours.lib | Bin 202552 -> 0 bytes .../NetHook/google/protobuf/descriptor.cc | 4401 ----------- .../NetHook/google/protobuf/descriptor.h | 1367 ---- .../NetHook/google/protobuf/descriptor.pb.cc | 7029 ----------------- .../NetHook/google/protobuf/descriptor.pb.h | 4355 ---------- .../NetHook/google/protobuf/descriptor.proto | 433 - .../google/protobuf/descriptor_database.cc | 541 -- .../google/protobuf/descriptor_database.h | 366 - .../protobuf/descriptor_database_unittest.cc | 748 -- .../google/protobuf/descriptor_unittest.cc | 3956 ---------- .../google/protobuf/dynamic_message.cc | 558 -- .../NetHook/google/protobuf/dynamic_message.h | 136 - .../protobuf/dynamic_message_unittest.cc | 162 - .../NetHook/google/protobuf/extension_set.cc | 1452 ---- .../NetHook/google/protobuf/extension_set.h | 902 --- .../google/protobuf/extension_set_heavy.cc | 457 -- .../google/protobuf/extension_set_unittest.cc | 642 -- .../protobuf/generated_message_reflection.cc | 1231 --- .../protobuf/generated_message_reflection.h | 424 - .../generated_message_reflection_unittest.cc | 384 - .../google/protobuf/generated_message_util.cc | 53 - .../google/protobuf/generated_message_util.h | 77 - .../google/protobuf/io/coded_stream.cc | 830 -- .../NetHook/google/protobuf/io/coded_stream.h | 1090 --- .../google/protobuf/io/coded_stream_inl.h | 64 - .../protobuf/io/coded_stream_unittest.cc | 1103 --- .../NetHook/google/protobuf/io/gzip_stream.cc | 320 - .../NetHook/google/protobuf/io/gzip_stream.h | 207 - .../protobuf/io/gzip_stream_unittest.sh | 44 - .../NetHook/google/protobuf/io/package_info.h | 54 - .../NetHook/google/protobuf/io/printer.cc | 188 - .../NetHook/google/protobuf/io/printer.h | 132 - .../google/protobuf/io/printer_unittest.cc | 261 - .../NetHook/google/protobuf/io/tokenizer.cc | 691 -- .../NetHook/google/protobuf/io/tokenizer.h | 303 - .../google/protobuf/io/tokenizer_unittest.cc | 743 -- .../google/protobuf/io/zero_copy_stream.cc | 48 - .../google/protobuf/io/zero_copy_stream.h | 238 - .../protobuf/io/zero_copy_stream_impl.cc | 470 -- .../protobuf/io/zero_copy_stream_impl.h | 357 - .../protobuf/io/zero_copy_stream_impl_lite.cc | 393 - .../protobuf/io/zero_copy_stream_impl_lite.h | 340 - .../protobuf/io/zero_copy_stream_unittest.cc | 721 -- .../NetHook/google/protobuf/lite_unittest.cc | 112 - Resources/NetHook/google/protobuf/message.cc | 318 - Resources/NetHook/google/protobuf/message.h | 710 -- .../NetHook/google/protobuf/message_lite.cc | 334 - .../NetHook/google/protobuf/message_lite.h | 239 - .../google/protobuf/message_unittest.cc | 281 - .../NetHook/google/protobuf/package_info.h | 64 - .../NetHook/google/protobuf/reflection_ops.cc | 262 - .../NetHook/google/protobuf/reflection_ops.h | 80 - .../protobuf/reflection_ops_unittest.cc | 405 - .../NetHook/google/protobuf/repeated_field.cc | 95 - .../NetHook/google/protobuf/repeated_field.h | 1248 --- .../protobuf/repeated_field_unittest.cc | 986 --- Resources/NetHook/google/protobuf/service.cc | 46 - Resources/NetHook/google/protobuf/service.h | 291 - .../NetHook/google/protobuf/stubs/common.cc | 365 - .../NetHook/google/protobuf/stubs/common.h | 1155 --- .../google/protobuf/stubs/common_unittest.cc | 345 - .../NetHook/google/protobuf/stubs/hash.cc | 41 - .../NetHook/google/protobuf/stubs/hash.h | 220 - .../NetHook/google/protobuf/stubs/map-util.h | 119 - .../NetHook/google/protobuf/stubs/once.cc | 88 - .../NetHook/google/protobuf/stubs/once.h | 123 - .../google/protobuf/stubs/once_unittest.cc | 253 - .../google/protobuf/stubs/stl_util-inl.h | 121 - .../protobuf/stubs/structurally_valid.cc | 536 -- .../stubs/structurally_valid_unittest.cc | 40 - .../NetHook/google/protobuf/stubs/strutil.cc | 1166 --- .../NetHook/google/protobuf/stubs/strutil.h | 459 -- .../google/protobuf/stubs/strutil_unittest.cc | 83 - .../google/protobuf/stubs/substitute.cc | 134 - .../google/protobuf/stubs/substitute.h | 170 - .../NetHook/google/protobuf/test_util.cc | 2854 ------- Resources/NetHook/google/protobuf/test_util.h | 174 - .../NetHook/google/protobuf/test_util_lite.cc | 1502 ---- .../NetHook/google/protobuf/test_util_lite.h | 101 - .../NetHook/google/protobuf/text_format.cc | 1241 --- .../NetHook/google/protobuf/text_format.h | 264 - .../google/protobuf/text_format_unittest.cc | 1074 --- .../NetHook/google/protobuf/unittest.proto | 612 -- .../protobuf/unittest_custom_options.proto | 275 - .../unittest_embed_optimize_for.proto | 50 - .../google/protobuf/unittest_empty.proto | 37 - .../unittest_enormous_descriptor.proto | 1046 --- .../google/protobuf/unittest_import.proto | 61 - .../protobuf/unittest_import_lite.proto | 49 - .../google/protobuf/unittest_lite.proto | 312 - .../unittest_lite_imports_nonlite.proto | 43 - .../google/protobuf/unittest_mset.proto | 72 - .../unittest_no_generic_services.proto | 54 - .../protobuf/unittest_optimize_for.proto | 61 - .../google/protobuf/unknown_field_set.cc | 204 - .../google/protobuf/unknown_field_set.h | 268 - .../protobuf/unknown_field_set_unittest.cc | 512 -- .../NetHook/google/protobuf/wire_format.cc | 1069 --- .../NetHook/google/protobuf/wire_format.h | 304 - .../google/protobuf/wire_format_lite.cc | 359 - .../google/protobuf/wire_format_lite.h | 620 -- .../google/protobuf/wire_format_lite_inl.h | 747 -- .../google/protobuf/wire_format_unittest.cc | 905 --- Resources/NetHook/libprotobuf.lib | Bin 17150514 -> 0 bytes Resources/NetHook/logger.cpp | 106 - Resources/NetHook/logger.h | 42 - Resources/NetHook/mathlib/IceKey.H | 62 - Resources/NetHook/mathlib/amd3dx.h | 1187 --- Resources/NetHook/mathlib/anorms.h | 25 - Resources/NetHook/mathlib/bumpvects.h | 37 - .../NetHook/mathlib/compressed_3d_unitvec.h | 284 - .../NetHook/mathlib/compressed_light_cube.h | 24 - Resources/NetHook/mathlib/compressed_vector.h | 608 -- Resources/NetHook/mathlib/halton.h | 70 - Resources/NetHook/mathlib/lightdesc.h | 167 - Resources/NetHook/mathlib/math_pfns.h | 72 - Resources/NetHook/mathlib/mathlib.h | 2073 ----- Resources/NetHook/mathlib/noise.h | 35 - Resources/NetHook/mathlib/polyhedron.h | 73 - Resources/NetHook/mathlib/quantize.h | 141 - Resources/NetHook/mathlib/simdvectormatrix.h | 142 - .../NetHook/mathlib/spherical_geometry.h | 73 - Resources/NetHook/mathlib/ssemath.h | 3098 -------- Resources/NetHook/mathlib/ssequaternion.h | 367 - Resources/NetHook/mathlib/vector.h | 2226 ------ Resources/NetHook/mathlib/vector2d.h | 670 -- Resources/NetHook/mathlib/vector4d.h | 690 -- Resources/NetHook/mathlib/vmatrix.h | 938 --- Resources/NetHook/mathlib/vplane.h | 182 - Resources/NetHook/public/bitvec.h | 1417 ---- Resources/NetHook/public/coordsize.h | 98 - Resources/NetHook/public/worldsize.h | 42 - Resources/NetHook/sigscan.cpp | 124 - Resources/NetHook/sigscan.h | 66 - Resources/NetHook/steam/clientmsgs.h | 90 - Resources/NetHook/steam/csteamid.h | 515 -- Resources/NetHook/steam/emsg.h | 348 - Resources/NetHook/steam/steamtypes.h | 306 - Resources/NetHook/steam/udppkt.h | 121 - Resources/NetHook/steammessages_base.pb.cc | 1289 --- Resources/NetHook/steammessages_base.pb.h | 759 -- Resources/NetHook/tier0.lib | Bin 85916 -> 0 bytes Resources/NetHook/tier0/EventMasks.h | 480 -- Resources/NetHook/tier0/EventModes.h | 1787 ----- Resources/NetHook/tier0/IOCTLCodes.h | 29 - .../NetHook/tier0/K8PerformanceCounters.h | 2028 ----- .../NetHook/tier0/P4PerformanceCounters.h | 322 - .../NetHook/tier0/P5P6PerformanceCounters.h | 225 - Resources/NetHook/tier0/PMELib.h | 195 - Resources/NetHook/tier0/afxmem_override.cpp | 460 -- Resources/NetHook/tier0/basetypes.h | 372 - Resources/NetHook/tier0/commonmacros.h | 144 - Resources/NetHook/tier0/dbg.h | 714 -- Resources/NetHook/tier0/dbgflag.h | 65 - Resources/NetHook/tier0/fasttimer.h | 591 -- Resources/NetHook/tier0/ia32detect.h | 351 - Resources/NetHook/tier0/icommandline.h | 53 - Resources/NetHook/tier0/l2cache.h | 46 - Resources/NetHook/tier0/mem.h | 45 - Resources/NetHook/tier0/memalloc.h | 353 - Resources/NetHook/tier0/memdbgoff.h | 25 - Resources/NetHook/tier0/memdbgon.h | 243 - Resources/NetHook/tier0/memoverride.cpp | 1385 ---- Resources/NetHook/tier0/minidump.h | 53 - Resources/NetHook/tier0/platform.h | 1168 --- Resources/NetHook/tier0/pmc360.h | 73 - Resources/NetHook/tier0/progressbar.h | 23 - Resources/NetHook/tier0/protected_things.h | 284 - Resources/NetHook/tier0/systeminformation.h | 56 - Resources/NetHook/tier0/testthread.h | 60 - Resources/NetHook/tier0/threadtools.h | 1577 ---- Resources/NetHook/tier0/tslist.h | 794 -- Resources/NetHook/tier0/validator.h | 73 - Resources/NetHook/tier0/valobject.h | 72 - Resources/NetHook/tier0/valve_minmax_off.h | 8 - Resources/NetHook/tier0/valve_minmax_on.h | 8 - Resources/NetHook/tier0/valve_off.h | 30 - Resources/NetHook/tier0/valve_on.h | 31 - Resources/NetHook/tier0/vcr_shared.h | 54 - Resources/NetHook/tier0/vcrmode.h | 306 - Resources/NetHook/tier0/vprof.h | 1187 --- Resources/NetHook/tier0/wchartypes.h | 101 - .../NetHook/tier0/xbox_codeline_defines.h | 16 - Resources/NetHook/tier1/CommandBuffer.h | 160 - Resources/NetHook/tier1/KeyValues.cpp | 2516 ------ Resources/NetHook/tier1/KeyValues.h | 357 - Resources/NetHook/tier1/NetAdr.cpp | 331 - Resources/NetHook/tier1/UtlSortVector.h | 311 - Resources/NetHook/tier1/UtlStringMap.h | 99 - Resources/NetHook/tier1/bitbuf.cpp | 1269 --- Resources/NetHook/tier1/bitbuf.h | 1500 ---- Resources/NetHook/tier1/byteswap.cpp | 90 - Resources/NetHook/tier1/byteswap.h | 249 - Resources/NetHook/tier1/callqueue.h | 203 - Resources/NetHook/tier1/characterset.cpp | 41 - Resources/NetHook/tier1/characterset.h | 43 - Resources/NetHook/tier1/checksum_crc.cpp | 180 - Resources/NetHook/tier1/checksum_crc.h | 31 - Resources/NetHook/tier1/checksum_md5.cpp | 271 - Resources/NetHook/tier1/checksum_md5.h | 33 - Resources/NetHook/tier1/commandbuffer.cpp | 636 -- Resources/NetHook/tier1/convar.cpp | 1241 --- Resources/NetHook/tier1/convar.h | 671 -- .../NetHook/tier1/convar_serverbounded.h | 53 - Resources/NetHook/tier1/datamanager.cpp | 410 - Resources/NetHook/tier1/datamanager.h | 277 - Resources/NetHook/tier1/delegates.h | 99 - Resources/NetHook/tier1/diff.cpp | 547 -- Resources/NetHook/tier1/diff.h | 29 - Resources/NetHook/tier1/fmtstr.h | 82 - Resources/NetHook/tier1/functors.h | 617 -- Resources/NetHook/tier1/generichash.cpp | 303 - Resources/NetHook/tier1/generichash.h | 92 - Resources/NetHook/tier1/iconvar.h | 114 - Resources/NetHook/tier1/interface.cpp | 462 -- Resources/NetHook/tier1/interface.h | 219 - Resources/NetHook/tier1/lzmaDecoder.h | 42 - Resources/NetHook/tier1/lzss.h | 71 - Resources/NetHook/tier1/mempool.cpp | 312 - Resources/NetHook/tier1/mempool.h | 541 -- Resources/NetHook/tier1/memstack.cpp | 297 - Resources/NetHook/tier1/memstack.h | 204 - Resources/NetHook/tier1/netadr.h | 70 - Resources/NetHook/tier1/newbitbuf.cpp | 713 -- Resources/NetHook/tier1/processor_detect.cpp | 278 - Resources/NetHook/tier1/processor_detect.h | 12 - .../NetHook/tier1/processor_detect_linux.cpp | 47 - Resources/NetHook/tier1/rangecheckedvar.cpp | 41 - Resources/NetHook/tier1/rangecheckedvar.h | 113 - Resources/NetHook/tier1/refcount.h | 385 - Resources/NetHook/tier1/smartptr.h | 279 - Resources/NetHook/tier1/stringpool.cpp | 334 - Resources/NetHook/tier1/stringpool.h | 91 - Resources/NetHook/tier1/strtools.cpp | 2015 ----- Resources/NetHook/tier1/strtools.h | 462 -- Resources/NetHook/tier1/tier1.cpp | 63 - Resources/NetHook/tier1/tier1.h | 106 - Resources/NetHook/tier1/tokenreader.cpp | 480 -- Resources/NetHook/tier1/tokenreader.h | 105 - Resources/NetHook/tier1/undiff.cpp | 94 - Resources/NetHook/tier1/uniqueid.cpp | 177 - Resources/NetHook/tier1/uniqueid.h | 56 - Resources/NetHook/tier1/utlbidirectionalset.h | 381 - Resources/NetHook/tier1/utlblockmemory.h | 349 - Resources/NetHook/tier1/utlbuffer.cpp | 1747 ---- Resources/NetHook/tier1/utlbuffer.h | 1028 --- Resources/NetHook/tier1/utlbufferutil.cpp | 559 -- Resources/NetHook/tier1/utlbufferutil.h | 192 - Resources/NetHook/tier1/utldict.h | 320 - Resources/NetHook/tier1/utlenvelope.h | 240 - Resources/NetHook/tier1/utlfixedmemory.h | 356 - Resources/NetHook/tier1/utlflags.h | 124 - Resources/NetHook/tier1/utlhandletable.h | 586 -- Resources/NetHook/tier1/utlhash.h | 936 --- Resources/NetHook/tier1/utlhashdict.h | 342 - Resources/NetHook/tier1/utlintrusivelist.h | 772 -- Resources/NetHook/tier1/utllinkedlist.h | 1018 --- Resources/NetHook/tier1/utlmap.h | 203 - Resources/NetHook/tier1/utlmemory.h | 925 --- Resources/NetHook/tier1/utlmultilist.h | 725 -- Resources/NetHook/tier1/utlntree.h | 624 -- Resources/NetHook/tier1/utlobjectreference.h | 165 - Resources/NetHook/tier1/utlpriorityqueue.h | 198 - Resources/NetHook/tier1/utlqueue.h | 114 - Resources/NetHook/tier1/utlrbtree.h | 1557 ---- Resources/NetHook/tier1/utlsoacontainer.h | 334 - Resources/NetHook/tier1/utlstack.h | 331 - Resources/NetHook/tier1/utlstring.cpp | 334 - Resources/NetHook/tier1/utlstring.h | 160 - Resources/NetHook/tier1/utlsymbol.cpp | 395 - Resources/NetHook/tier1/utlsymbol.h | 261 - Resources/NetHook/tier1/utlvector.h | 794 -- Resources/NetHook/utils.cpp | 6527 --------------- Resources/NetHook/utils.h | 36 - Resources/NetHook/zdll.lib | Bin 38996 -> 0 bytes Resources/NetHook/zip.cpp | 73 - Resources/NetHook/zip.h | 25 - Resources/NetHook/zlib.def | 74 - Resources/NetHook/zlib.lib | Bin 247310 -> 0 bytes Resources/NetHook/zlib/zconf.h | 428 - Resources/NetHook/zlib/zlib.h | 1613 ---- Resources/NetHook/zlib1.dll | Bin 100352 -> 0 bytes 297 files changed, 147097 deletions(-) delete mode 100644 Resources/NetHook/DataDumper.cpp delete mode 100644 Resources/NetHook/DataDumper.h delete mode 100644 Resources/NetHook/NetHook.sln delete mode 100644 Resources/NetHook/NetHook.vcproj delete mode 100644 Resources/NetHook/NetHook.vcxproj delete mode 100644 Resources/NetHook/NetHook.vcxproj.filters delete mode 100644 Resources/NetHook/clientapp.cpp delete mode 100644 Resources/NetHook/clientapp.h delete mode 100644 Resources/NetHook/crypto.cpp delete mode 100644 Resources/NetHook/crypto.h delete mode 100644 Resources/NetHook/csimpledetour.cpp delete mode 100644 Resources/NetHook/csimpledetour.h delete mode 100644 Resources/NetHook/csimplescan.cpp delete mode 100644 Resources/NetHook/csimplescan.h delete mode 100644 Resources/NetHook/detours.h delete mode 100644 Resources/NetHook/detours.lib delete mode 100644 Resources/NetHook/google/protobuf/descriptor.cc delete mode 100644 Resources/NetHook/google/protobuf/descriptor.h delete mode 100644 Resources/NetHook/google/protobuf/descriptor.pb.cc delete mode 100644 Resources/NetHook/google/protobuf/descriptor.pb.h delete mode 100644 Resources/NetHook/google/protobuf/descriptor.proto delete mode 100644 Resources/NetHook/google/protobuf/descriptor_database.cc delete mode 100644 Resources/NetHook/google/protobuf/descriptor_database.h delete mode 100644 Resources/NetHook/google/protobuf/descriptor_database_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/descriptor_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/dynamic_message.cc delete mode 100644 Resources/NetHook/google/protobuf/dynamic_message.h delete mode 100644 Resources/NetHook/google/protobuf/dynamic_message_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/extension_set.cc delete mode 100644 Resources/NetHook/google/protobuf/extension_set.h delete mode 100644 Resources/NetHook/google/protobuf/extension_set_heavy.cc delete mode 100644 Resources/NetHook/google/protobuf/extension_set_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/generated_message_reflection.cc delete mode 100644 Resources/NetHook/google/protobuf/generated_message_reflection.h delete mode 100644 Resources/NetHook/google/protobuf/generated_message_reflection_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/generated_message_util.cc delete mode 100644 Resources/NetHook/google/protobuf/generated_message_util.h delete mode 100644 Resources/NetHook/google/protobuf/io/coded_stream.cc delete mode 100644 Resources/NetHook/google/protobuf/io/coded_stream.h delete mode 100644 Resources/NetHook/google/protobuf/io/coded_stream_inl.h delete mode 100644 Resources/NetHook/google/protobuf/io/coded_stream_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/io/gzip_stream.cc delete mode 100644 Resources/NetHook/google/protobuf/io/gzip_stream.h delete mode 100644 Resources/NetHook/google/protobuf/io/gzip_stream_unittest.sh delete mode 100644 Resources/NetHook/google/protobuf/io/package_info.h delete mode 100644 Resources/NetHook/google/protobuf/io/printer.cc delete mode 100644 Resources/NetHook/google/protobuf/io/printer.h delete mode 100644 Resources/NetHook/google/protobuf/io/printer_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/io/tokenizer.cc delete mode 100644 Resources/NetHook/google/protobuf/io/tokenizer.h delete mode 100644 Resources/NetHook/google/protobuf/io/tokenizer_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream.cc delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream.h delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.cc delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.h delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.cc delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.h delete mode 100644 Resources/NetHook/google/protobuf/io/zero_copy_stream_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/lite_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/message.cc delete mode 100644 Resources/NetHook/google/protobuf/message.h delete mode 100644 Resources/NetHook/google/protobuf/message_lite.cc delete mode 100644 Resources/NetHook/google/protobuf/message_lite.h delete mode 100644 Resources/NetHook/google/protobuf/message_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/package_info.h delete mode 100644 Resources/NetHook/google/protobuf/reflection_ops.cc delete mode 100644 Resources/NetHook/google/protobuf/reflection_ops.h delete mode 100644 Resources/NetHook/google/protobuf/reflection_ops_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/repeated_field.cc delete mode 100644 Resources/NetHook/google/protobuf/repeated_field.h delete mode 100644 Resources/NetHook/google/protobuf/repeated_field_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/service.cc delete mode 100644 Resources/NetHook/google/protobuf/service.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/common.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/common.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/common_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/hash.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/hash.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/map-util.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/once.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/once.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/once_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/stl_util-inl.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/structurally_valid.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/structurally_valid_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/strutil.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/strutil.h delete mode 100644 Resources/NetHook/google/protobuf/stubs/strutil_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/substitute.cc delete mode 100644 Resources/NetHook/google/protobuf/stubs/substitute.h delete mode 100644 Resources/NetHook/google/protobuf/test_util.cc delete mode 100644 Resources/NetHook/google/protobuf/test_util.h delete mode 100644 Resources/NetHook/google/protobuf/test_util_lite.cc delete mode 100644 Resources/NetHook/google/protobuf/test_util_lite.h delete mode 100644 Resources/NetHook/google/protobuf/text_format.cc delete mode 100644 Resources/NetHook/google/protobuf/text_format.h delete mode 100644 Resources/NetHook/google/protobuf/text_format_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/unittest.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_custom_options.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_embed_optimize_for.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_empty.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_enormous_descriptor.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_import.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_import_lite.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_lite.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_lite_imports_nonlite.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_mset.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_no_generic_services.proto delete mode 100644 Resources/NetHook/google/protobuf/unittest_optimize_for.proto delete mode 100644 Resources/NetHook/google/protobuf/unknown_field_set.cc delete mode 100644 Resources/NetHook/google/protobuf/unknown_field_set.h delete mode 100644 Resources/NetHook/google/protobuf/unknown_field_set_unittest.cc delete mode 100644 Resources/NetHook/google/protobuf/wire_format.cc delete mode 100644 Resources/NetHook/google/protobuf/wire_format.h delete mode 100644 Resources/NetHook/google/protobuf/wire_format_lite.cc delete mode 100644 Resources/NetHook/google/protobuf/wire_format_lite.h delete mode 100644 Resources/NetHook/google/protobuf/wire_format_lite_inl.h delete mode 100644 Resources/NetHook/google/protobuf/wire_format_unittest.cc delete mode 100644 Resources/NetHook/libprotobuf.lib delete mode 100644 Resources/NetHook/logger.cpp delete mode 100644 Resources/NetHook/logger.h delete mode 100644 Resources/NetHook/mathlib/IceKey.H delete mode 100644 Resources/NetHook/mathlib/amd3dx.h delete mode 100644 Resources/NetHook/mathlib/anorms.h delete mode 100644 Resources/NetHook/mathlib/bumpvects.h delete mode 100644 Resources/NetHook/mathlib/compressed_3d_unitvec.h delete mode 100644 Resources/NetHook/mathlib/compressed_light_cube.h delete mode 100644 Resources/NetHook/mathlib/compressed_vector.h delete mode 100644 Resources/NetHook/mathlib/halton.h delete mode 100644 Resources/NetHook/mathlib/lightdesc.h delete mode 100644 Resources/NetHook/mathlib/math_pfns.h delete mode 100644 Resources/NetHook/mathlib/mathlib.h delete mode 100644 Resources/NetHook/mathlib/noise.h delete mode 100644 Resources/NetHook/mathlib/polyhedron.h delete mode 100644 Resources/NetHook/mathlib/quantize.h delete mode 100644 Resources/NetHook/mathlib/simdvectormatrix.h delete mode 100644 Resources/NetHook/mathlib/spherical_geometry.h delete mode 100644 Resources/NetHook/mathlib/ssemath.h delete mode 100644 Resources/NetHook/mathlib/ssequaternion.h delete mode 100644 Resources/NetHook/mathlib/vector.h delete mode 100644 Resources/NetHook/mathlib/vector2d.h delete mode 100644 Resources/NetHook/mathlib/vector4d.h delete mode 100644 Resources/NetHook/mathlib/vmatrix.h delete mode 100644 Resources/NetHook/mathlib/vplane.h delete mode 100644 Resources/NetHook/public/bitvec.h delete mode 100644 Resources/NetHook/public/coordsize.h delete mode 100644 Resources/NetHook/public/worldsize.h delete mode 100644 Resources/NetHook/sigscan.cpp delete mode 100644 Resources/NetHook/sigscan.h delete mode 100644 Resources/NetHook/steam/clientmsgs.h delete mode 100644 Resources/NetHook/steam/csteamid.h delete mode 100644 Resources/NetHook/steam/emsg.h delete mode 100644 Resources/NetHook/steam/steamtypes.h delete mode 100644 Resources/NetHook/steam/udppkt.h delete mode 100644 Resources/NetHook/steammessages_base.pb.cc delete mode 100644 Resources/NetHook/steammessages_base.pb.h delete mode 100644 Resources/NetHook/tier0.lib delete mode 100644 Resources/NetHook/tier0/EventMasks.h delete mode 100644 Resources/NetHook/tier0/EventModes.h delete mode 100644 Resources/NetHook/tier0/IOCTLCodes.h delete mode 100644 Resources/NetHook/tier0/K8PerformanceCounters.h delete mode 100644 Resources/NetHook/tier0/P4PerformanceCounters.h delete mode 100644 Resources/NetHook/tier0/P5P6PerformanceCounters.h delete mode 100644 Resources/NetHook/tier0/PMELib.h delete mode 100644 Resources/NetHook/tier0/afxmem_override.cpp delete mode 100644 Resources/NetHook/tier0/basetypes.h delete mode 100644 Resources/NetHook/tier0/commonmacros.h delete mode 100644 Resources/NetHook/tier0/dbg.h delete mode 100644 Resources/NetHook/tier0/dbgflag.h delete mode 100644 Resources/NetHook/tier0/fasttimer.h delete mode 100644 Resources/NetHook/tier0/ia32detect.h delete mode 100644 Resources/NetHook/tier0/icommandline.h delete mode 100644 Resources/NetHook/tier0/l2cache.h delete mode 100644 Resources/NetHook/tier0/mem.h delete mode 100644 Resources/NetHook/tier0/memalloc.h delete mode 100644 Resources/NetHook/tier0/memdbgoff.h delete mode 100644 Resources/NetHook/tier0/memdbgon.h delete mode 100644 Resources/NetHook/tier0/memoverride.cpp delete mode 100644 Resources/NetHook/tier0/minidump.h delete mode 100644 Resources/NetHook/tier0/platform.h delete mode 100644 Resources/NetHook/tier0/pmc360.h delete mode 100644 Resources/NetHook/tier0/progressbar.h delete mode 100644 Resources/NetHook/tier0/protected_things.h delete mode 100644 Resources/NetHook/tier0/systeminformation.h delete mode 100644 Resources/NetHook/tier0/testthread.h delete mode 100644 Resources/NetHook/tier0/threadtools.h delete mode 100644 Resources/NetHook/tier0/tslist.h delete mode 100644 Resources/NetHook/tier0/validator.h delete mode 100644 Resources/NetHook/tier0/valobject.h delete mode 100644 Resources/NetHook/tier0/valve_minmax_off.h delete mode 100644 Resources/NetHook/tier0/valve_minmax_on.h delete mode 100644 Resources/NetHook/tier0/valve_off.h delete mode 100644 Resources/NetHook/tier0/valve_on.h delete mode 100644 Resources/NetHook/tier0/vcr_shared.h delete mode 100644 Resources/NetHook/tier0/vcrmode.h delete mode 100644 Resources/NetHook/tier0/vprof.h delete mode 100644 Resources/NetHook/tier0/wchartypes.h delete mode 100644 Resources/NetHook/tier0/xbox_codeline_defines.h delete mode 100644 Resources/NetHook/tier1/CommandBuffer.h delete mode 100644 Resources/NetHook/tier1/KeyValues.cpp delete mode 100644 Resources/NetHook/tier1/KeyValues.h delete mode 100644 Resources/NetHook/tier1/NetAdr.cpp delete mode 100644 Resources/NetHook/tier1/UtlSortVector.h delete mode 100644 Resources/NetHook/tier1/UtlStringMap.h delete mode 100644 Resources/NetHook/tier1/bitbuf.cpp delete mode 100644 Resources/NetHook/tier1/bitbuf.h delete mode 100644 Resources/NetHook/tier1/byteswap.cpp delete mode 100644 Resources/NetHook/tier1/byteswap.h delete mode 100644 Resources/NetHook/tier1/callqueue.h delete mode 100644 Resources/NetHook/tier1/characterset.cpp delete mode 100644 Resources/NetHook/tier1/characterset.h delete mode 100644 Resources/NetHook/tier1/checksum_crc.cpp delete mode 100644 Resources/NetHook/tier1/checksum_crc.h delete mode 100644 Resources/NetHook/tier1/checksum_md5.cpp delete mode 100644 Resources/NetHook/tier1/checksum_md5.h delete mode 100644 Resources/NetHook/tier1/commandbuffer.cpp delete mode 100644 Resources/NetHook/tier1/convar.cpp delete mode 100644 Resources/NetHook/tier1/convar.h delete mode 100644 Resources/NetHook/tier1/convar_serverbounded.h delete mode 100644 Resources/NetHook/tier1/datamanager.cpp delete mode 100644 Resources/NetHook/tier1/datamanager.h delete mode 100644 Resources/NetHook/tier1/delegates.h delete mode 100644 Resources/NetHook/tier1/diff.cpp delete mode 100644 Resources/NetHook/tier1/diff.h delete mode 100644 Resources/NetHook/tier1/fmtstr.h delete mode 100644 Resources/NetHook/tier1/functors.h delete mode 100644 Resources/NetHook/tier1/generichash.cpp delete mode 100644 Resources/NetHook/tier1/generichash.h delete mode 100644 Resources/NetHook/tier1/iconvar.h delete mode 100644 Resources/NetHook/tier1/interface.cpp delete mode 100644 Resources/NetHook/tier1/interface.h delete mode 100644 Resources/NetHook/tier1/lzmaDecoder.h delete mode 100644 Resources/NetHook/tier1/lzss.h delete mode 100644 Resources/NetHook/tier1/mempool.cpp delete mode 100644 Resources/NetHook/tier1/mempool.h delete mode 100644 Resources/NetHook/tier1/memstack.cpp delete mode 100644 Resources/NetHook/tier1/memstack.h delete mode 100644 Resources/NetHook/tier1/netadr.h delete mode 100644 Resources/NetHook/tier1/newbitbuf.cpp delete mode 100644 Resources/NetHook/tier1/processor_detect.cpp delete mode 100644 Resources/NetHook/tier1/processor_detect.h delete mode 100644 Resources/NetHook/tier1/processor_detect_linux.cpp delete mode 100644 Resources/NetHook/tier1/rangecheckedvar.cpp delete mode 100644 Resources/NetHook/tier1/rangecheckedvar.h delete mode 100644 Resources/NetHook/tier1/refcount.h delete mode 100644 Resources/NetHook/tier1/smartptr.h delete mode 100644 Resources/NetHook/tier1/stringpool.cpp delete mode 100644 Resources/NetHook/tier1/stringpool.h delete mode 100644 Resources/NetHook/tier1/strtools.cpp delete mode 100644 Resources/NetHook/tier1/strtools.h delete mode 100644 Resources/NetHook/tier1/tier1.cpp delete mode 100644 Resources/NetHook/tier1/tier1.h delete mode 100644 Resources/NetHook/tier1/tokenreader.cpp delete mode 100644 Resources/NetHook/tier1/tokenreader.h delete mode 100644 Resources/NetHook/tier1/undiff.cpp delete mode 100644 Resources/NetHook/tier1/uniqueid.cpp delete mode 100644 Resources/NetHook/tier1/uniqueid.h delete mode 100644 Resources/NetHook/tier1/utlbidirectionalset.h delete mode 100644 Resources/NetHook/tier1/utlblockmemory.h delete mode 100644 Resources/NetHook/tier1/utlbuffer.cpp delete mode 100644 Resources/NetHook/tier1/utlbuffer.h delete mode 100644 Resources/NetHook/tier1/utlbufferutil.cpp delete mode 100644 Resources/NetHook/tier1/utlbufferutil.h delete mode 100644 Resources/NetHook/tier1/utldict.h delete mode 100644 Resources/NetHook/tier1/utlenvelope.h delete mode 100644 Resources/NetHook/tier1/utlfixedmemory.h delete mode 100644 Resources/NetHook/tier1/utlflags.h delete mode 100644 Resources/NetHook/tier1/utlhandletable.h delete mode 100644 Resources/NetHook/tier1/utlhash.h delete mode 100644 Resources/NetHook/tier1/utlhashdict.h delete mode 100644 Resources/NetHook/tier1/utlintrusivelist.h delete mode 100644 Resources/NetHook/tier1/utllinkedlist.h delete mode 100644 Resources/NetHook/tier1/utlmap.h delete mode 100644 Resources/NetHook/tier1/utlmemory.h delete mode 100644 Resources/NetHook/tier1/utlmultilist.h delete mode 100644 Resources/NetHook/tier1/utlntree.h delete mode 100644 Resources/NetHook/tier1/utlobjectreference.h delete mode 100644 Resources/NetHook/tier1/utlpriorityqueue.h delete mode 100644 Resources/NetHook/tier1/utlqueue.h delete mode 100644 Resources/NetHook/tier1/utlrbtree.h delete mode 100644 Resources/NetHook/tier1/utlsoacontainer.h delete mode 100644 Resources/NetHook/tier1/utlstack.h delete mode 100644 Resources/NetHook/tier1/utlstring.cpp delete mode 100644 Resources/NetHook/tier1/utlstring.h delete mode 100644 Resources/NetHook/tier1/utlsymbol.cpp delete mode 100644 Resources/NetHook/tier1/utlsymbol.h delete mode 100644 Resources/NetHook/tier1/utlvector.h delete mode 100644 Resources/NetHook/utils.cpp delete mode 100644 Resources/NetHook/utils.h delete mode 100644 Resources/NetHook/zdll.lib delete mode 100644 Resources/NetHook/zip.cpp delete mode 100644 Resources/NetHook/zip.h delete mode 100644 Resources/NetHook/zlib.def delete mode 100644 Resources/NetHook/zlib.lib delete mode 100644 Resources/NetHook/zlib/zconf.h delete mode 100644 Resources/NetHook/zlib/zlib.h delete mode 100644 Resources/NetHook/zlib1.dll diff --git a/Resources/NetHook/DataDumper.cpp b/Resources/NetHook/DataDumper.cpp deleted file mode 100644 index f9e91a7a..00000000 --- a/Resources/NetHook/DataDumper.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "DataDumper.h" -#include "logger.h" -#include "utils.h" - -#include "zip.h" -#include "bitbuf.h" - -#include "steam/clientmsgs.h" -#include "steammessages_base.pb.h" - -CDataDumper::CDataDumper() : - m_uiMsgNum(0) -{ - time_t tCurrentTime; - time(&tCurrentTime); - - sprintf_s(m_szSessionDir, sizeof( m_szSessionDir ), "%d\\", tCurrentTime); - - g_Logger->CreateDir(m_szSessionDir); -} - -void CDataDumper::DataEncrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData) -{ - this->HandleNetMsg(k_eNetOutgoing, (EMsg) *(short *) pubPlaintextData, pubPlaintextData, cubPlaintextData); -} - -void CDataDumper::DataDecrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData) -{ - this->HandleNetMsg(k_eNetIncoming, (EMsg) *(short *) pubPlaintextData, pubPlaintextData, cubPlaintextData); -} - -bool CDataDumper::HandleNetMsg( ENetDirection eDirection, EMsg eMsg, const uint8 *pData, uint32 cubData ) -{ - eMsg = (EMsg)((int)eMsg & (~0x80000000)); - - if ( eMsg == k_EMsgMulti ) - return this->MultiplexMsgMulti(eDirection, pData, cubData); - - const char* szFile = this->GetFileName(eDirection, eMsg); - g_Logger->LogFileData(szFile, pData, cubData); - - g_Logger->LogConsole("Wrote %d bytes to %s\n", cubData, szFile); - - return true; -} - -const char* CDataDumper::GetFileName(ENetDirection eDirection, EMsg eMsg) -{ - static char szFileName[MAX_PATH]; - - sprintf_s(szFileName, sizeof( szFileName ), "%s%d_%s_%d_%s.bin", m_szSessionDir, - ++m_uiMsgNum, (eDirection == k_eNetIncoming ? "in" : "out"), eMsg, - g_Crypto->GetMessage(eMsg)); - - return szFileName; -} - -const char* CDataDumper::GetFileName( const char* file ) -{ - static char szFileName[MAX_PATH]; - - sprintf_s(szFileName, sizeof( szFileName ), "%s%s", m_szSessionDir, - file); - - return szFileName; -} - -bool CDataDumper::MultiplexMsgMulti( ENetDirection eDirection, const uint8 *pData, uint32 cubData ) -{ - struct ProtoHdr - { - EMsg msg; - int headerLength; - }; - - - ProtoHdr *pProtoHdr = (ProtoHdr*) pData; - - g_Logger->LogConsole("Multi: msg %d length %d\n", (pProtoHdr->msg & (~0x80000000)), pProtoHdr->headerLength ); - - CMsgProtoBufHeader protoheader; - protoheader.ParseFromArray( pData + 8, pProtoHdr->headerLength ); - - g_Logger->LogConsole("MultiProto\n"); - - CMsgMulti multi; - multi.ParseFromArray( pData + 8 + pProtoHdr->headerLength, cubData - 8 - pProtoHdr->headerLength ); - - g_Logger->LogConsole("MultiMsg: %d %d\n", multi.size_unzipped(), multi.message_body().length() ); - - uint8 *pMsgData = NULL; - uint32 cubMsgData = 0; - bool bDecomp = false; - - if ( multi.has_size_unzipped() && multi.size_unzipped() != 0 ) - { - // decompress our data - - uint8 *pDecompressed = new uint8[ multi.size_unzipped() ]; - uint8 *pCompressed = (uint8 *)( multi.message_body().c_str() ); - uint32 cubCompressed = multi.message_body().length(); - - g_Logger->LogConsole("decomp: %x comp: %x cubcomp: %d unzipped: %d\n", pDecompressed, pCompressed, cubCompressed, multi.size_unzipped()); - - bool bZip = CZip::Inflate( pCompressed, cubCompressed, pDecompressed, multi.size_unzipped() ); - - if ( !bZip ) - { - delete [] pDecompressed; - - g_Logger->LogConsole("Unable to decompress buffer\n"); - - return true; - } - - pMsgData = pDecompressed; - cubMsgData = multi.size_unzipped(); - bDecomp = bZip; - } - else - { - pMsgData = (uint8 *)( multi.message_body().c_str() ); - cubMsgData = multi.message_body().length(); - } - - bf_read reader( pMsgData, cubMsgData ); - - while ( reader.GetNumBytesLeft() > 0 ) - { - uint32 cubPayload = (uint32)reader.ReadLong(); - int off = reader.GetNumBitsRead() >> 3; - - uint8 *pPayload = (uint8 *)( pMsgData + off ); - EMsg *pEMsg = (EMsg *)pPayload; - - reader.SeekRelative( cubPayload << 3 ); - - this->HandleNetMsg( eDirection, *pEMsg, pPayload, cubPayload ); - } - - if ( bDecomp ) - delete [] pMsgData; - - return true; -} \ No newline at end of file diff --git a/Resources/NetHook/DataDumper.h b/Resources/NetHook/DataDumper.h deleted file mode 100644 index 85dace47..00000000 --- a/Resources/NetHook/DataDumper.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef DATADUMPER_H_ -#define DATADUMPER_H_ -#ifdef _WIN32 -#pragma once -#endif - -#include "time.h" - -#include "crypto.h" -#include "steam/emsg.h" - -enum ENetDirection -{ - k_eNetIncoming, - k_eNetOutgoing, -}; - -class CDataDumper : public ICryptoCallback -{ -public: - CDataDumper(); - - void DataEncrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData); - void DataDecrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData); - - const char* GetFileName( const char* file ); - -private: - bool HandleNetMsg( ENetDirection eDirection, EMsg eMsg, const uint8 *pData, uint32 cubData ); - bool MultiplexMsgMulti( ENetDirection eDirection, const uint8 *pData, uint32 cubData ); - - const char* GetFileName( ENetDirection eDirection, EMsg eMsg ); - - char m_szSessionDir[MAX_PATH]; - uint32 m_uiMsgNum; -}; - -extern CDataDumper* g_Dumper; - -#endif // !DATADUMPER_H_ \ No newline at end of file diff --git a/Resources/NetHook/NetHook.sln b/Resources/NetHook/NetHook.sln deleted file mode 100644 index 33b2d704..00000000 --- a/Resources/NetHook/NetHook.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetHook", "NetHook.vcxproj", "{04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8}.Debug|Win32.ActiveCfg = Debug|Win32 - {04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8}.Debug|Win32.Build.0 = Debug|Win32 - {04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8}.Release|Win32.ActiveCfg = Release|Win32 - {04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Resources/NetHook/NetHook.vcproj b/Resources/NetHook/NetHook.vcproj deleted file mode 100644 index 7dcccd99..00000000 --- a/Resources/NetHook/NetHook.vcproj +++ /dev/null @@ -1,863 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/NetHook/NetHook.vcxproj b/Resources/NetHook/NetHook.vcxproj deleted file mode 100644 index af6d9c06..00000000 --- a/Resources/NetHook/NetHook.vcxproj +++ /dev/null @@ -1,268 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {04A24EE0-87D6-4CFB-BE63-7A9BC777B1A8} - NetHook - Win32Proj - - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - tier0;tier1;public;.;G:\dev\C++\Open Steamworks\Open Steamworks;C:\Users\ryan\Documents\development\Open Steamworks\Open Steamworks;%(AdditionalIncludeDirectories) - WIN32;_WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - Ws2_32.lib;steam.lib;%(AdditionalDependencies) - G:\dev\C++\Open Steamworks;C:\Users\ryan\Documents\development\Open Steamworks;%(AdditionalLibraryDirectories) - %(IgnoreSpecificDefaultLibraries) - true - Console - MachineX86 - - - - - MaxSpeed - true - tier0;tier1;public;.;C:\opensteamworks\Open Steamworks;%(AdditionalIncludeDirectories) - WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - Ws2_32.lib;%(AdditionalDependencies) - true - Windows - true - true - MachineX86 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Resources/NetHook/NetHook.vcxproj.filters b/Resources/NetHook/NetHook.vcxproj.filters deleted file mode 100644 index 9336e021..00000000 --- a/Resources/NetHook/NetHook.vcxproj.filters +++ /dev/null @@ -1,526 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93ff0feb-41ba-4a2c-9515-743871565253} - - - {ed4f167c-f6fc-4a3f-b5c7-5c0d4571646f} - - - {fa004520-6c3d-4c8b-9247-46be82bbb9f6} - - - {7674315e-74a1-451d-a9f1-1a33fb9f8a3a} - - - {cefb79e7-d12e-4d17-ab50-23b2365add3d} - - - {b948904a-73d7-445e-bfa7-146fcdf8dffa} - - - {f03368a7-6e2f-45f0-aabc-6aa1fcdee7f9} - - - {9b6b88a4-c98c-4a87-b335-1fc72128660a} - - - {ce62386e-1161-49e4-9f21-f912acbb45e2} - - - {f9881518-2823-4cab-ae08-0a00f32a3207} - - - {66a163d1-a739-4f18-8b60-d2b5790462c3} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - tier1\Source - - - tier1\Source - - - tier1\Source - - - tier1\Source - - - tier1\Source - - - Helpers - - - Helpers - - - Helpers - - - Source Files - - - - - Headers - - - Headers - - - Headers - - - Headers - - - Headers - - - Headers - - - Steam Headers - - - Steam Headers - - - Steam Headers - - - Steam Headers - - - Steam Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier1\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - tier0\Headers - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - mathlib - - - Helpers - - - Helpers - - - Helpers - - - Helpers - - - public - - - public - - - public - - - zlib - - - zlib - - - Headers - - - - - - - - - \ No newline at end of file diff --git a/Resources/NetHook/clientapp.cpp b/Resources/NetHook/clientapp.cpp deleted file mode 100644 index ca7ad35f..00000000 --- a/Resources/NetHook/clientapp.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -#include "clientapp.h" - -#include "utils.h" -#include "logger.h" -#include "crypto.h" -#include "DataDumper.h" - -#include "interface.h" - -#define STEAMTYPES_H -#include "usercommon.h" -#include "ESteamError.h" -#include "isteamclient009.h" -#include "isteamgameserver010.h" -#include "steammessages_base.pb.h" - -CDataDumper* g_Dumper; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - if ( fdwReason == DLL_PROCESS_ATTACH ) - { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - AllocConsole(); - LoadLibrary("steamclient.dll"); - - g_Logger = new CLogger(".\\"); - g_Dumper = new CDataDumper(); - g_Crypto = new CCrypto(g_Dumper); - } - else if ( fdwReason == DLL_PROCESS_DETACH ) - { - delete g_Crypto; - delete g_Dumper; - delete g_Logger; - } - - return TRUE; -} diff --git a/Resources/NetHook/clientapp.h b/Resources/NetHook/clientapp.h deleted file mode 100644 index ef929a52..00000000 --- a/Resources/NetHook/clientapp.h +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef CLIENTAPP_H_ -#define CLIENTAPP_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#define STEAM_API_EXPORTS - -#include "steam/steamtypes.h" - -typedef int ( STEAM_CALL *SteamExeFrameFn )( int, int ); -typedef int ( STEAM_CALL *SteamDllMainFn )( int , char ** ); - - -#define CLIENTAPP( entry ) \ - SteamExeFrameFn g_SteamExeFrame = NULL; \ - int entry( int argc, char **argv ); \ - S_API int STEAM_CALL SteamDllMain( int argc, char **argv ) \ - { \ - return entry( argc, argv ); \ - } \ - S_API int STEAM_CALL SteamDllMainEx( int argc, char **argv, SteamExeFrameFn frameFn ) \ - { \ - g_SteamExeFrame = frameFn; \ - return entry( argc, argv ); \ - } - - -#endif // !CLIENTAPP_H_ diff --git a/Resources/NetHook/crypto.cpp b/Resources/NetHook/crypto.cpp deleted file mode 100644 index c6cf40e3..00000000 --- a/Resources/NetHook/crypto.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "crypto.h" - -#include "DataDumper.h" -#include "logger.h" -#include "utils.h" - -#include "csimplescan.h" -#include "csimpledetour.h" - -#include "steam/steamtypes.h" - -#include "tier0/dbg.h" -#undef GetMessage - -CCrypto* g_Crypto = NULL; - -bool (__cdecl *Encrypt_Orig)(const uint8*, uint32, uint8*, uint32*, uint32); -bool (__cdecl *Decrypt_Orig)(const uint8*, uint32, uint8*, uint32*, const uint8*, uint32); -bool (__cdecl *GetMessageFn)( int * ); - -CCrypto::CCrypto(ICryptoCallback* callback) : - m_Callback(callback) -{ - CSimpleScan steamClientScan( "steamclient.dll" ); - - bool bRet = steamClientScan.FindFunction( - "\x55\x8B\xEC\x6A\xFF\x68\x01\x47\x32\x38\x64\xA1\x00\x00\x00\x00\x50\x64\x89\x25\x00\x00\x00\x00\x81\xEC\x04\x09\x00\x00", - "xxxxxx????xxxxxxxxxxxxxxxxxxxx", - (void **)& Encrypt_Orig - ); - - g_Logger->LogConsole( "CCrypto::SymmetricEncrypt = 0x%x \n", Encrypt_Orig ); - - - bRet = steamClientScan.FindFunction( - "\x55\x8B\xEC\x6A\xFF\x68\x21\x74\x28\x38\x64\xA1\x00\x00\x00\x00\x50\x64\x89\x25\x00\x00\x00\x00\x81\xEC\xE8\x04\x00\x00", - "xxxxxx????xxxxxxxxxxxxxxxxxxx", - (void **)& Decrypt_Orig - ); - - g_Logger->LogConsole( "CCrypto::SymmetricDecrypt = 0x%x\n", Decrypt_Orig ); - - /* - "51 A1 FC 24 33 38 | 8B 08 85 C9 75 05 89 0C 24 EB 28 E8 DA 09 E7 FF 8D 14 24 52 6A 04 6A 00 68 BC" - "\x51\xA1\xFF\xFF\xFF\xFF\x8B\x08\x85\xC9\x75\x05\x89\x0C\x24\xEB\x28\xE8" - "xx????" - - "\x51\xA1\x00\x95\x32\x38\x8B\x08\x85\xC9\x75\x05\x89\x0C\x24\xEB\x28\xE8\xA1\xBF\xE5\xFF\x8D\x14\x24\x52" - "\x6A\x04\x6A\x00\x68\x9C\x35\x36\x38\x6A\x00\x68\xF8\xEF\x38\x38\x8B\xC8\x89\x44\x24\x18", - "xx????xxxxx?xxxx?x????xxxx" - "xxxxxxxxxxxxxxxxxxxxxx", - */ - - bRet = steamClientScan.FindFunction( - "\x51\xA1\x00\x95\x32\x38\x8B\x08\x85\xC9\x75\x05\x89\x0C\x24\xEB\x28\xE8", - "xx????xxxxxxxxxxxx", - (void **) &GetMessageFn - ); - - g_Logger->LogConsole( "CMessageList::GetMessage = 0x%x\n", GetMessageFn ); - - for ( int x = 0; x < 7003; ++x ) - { - //g_Logger->AppendFile( g_Dumper->GetFileName( "emsg_list.txt" ), "\t%s = %d,\r\n", this->GetMessage( (EMsg)x ), x ); - } - - - static bool (__cdecl *encrypt)(const uint8*, uint32, uint8*, uint32*, uint32) = &CCrypto::SymmetricEncrypt; - static bool (__cdecl *decrypt)(const uint8*, uint32, uint8*, uint32*, const uint8*, uint32) = &CCrypto::SymmetricDecrypt; - - Encrypt_Detour = new CSimpleDetour((void **) &Encrypt_Orig, *(void**) &encrypt); - Decrypt_Detour = new CSimpleDetour((void **) &Decrypt_Orig, *(void**) &decrypt); - - Encrypt_Detour->Attach(); - Decrypt_Detour->Attach(); -} - -CCrypto::~CCrypto() -{ - Encrypt_Detour->Detach(); - Decrypt_Detour->Detach(); - - delete Encrypt_Detour; - delete Decrypt_Detour; -} - -// This call got strangely optimized. Don't clobber ECX. -__declspec(naked) bool __cdecl CCrypto::SymmetricEncrypt( const uint8 *pubPlaintextData, uint32 cubPlaintextData, uint8 *pubEncryptedData, uint32 *pcubEncryptedData, uint32 cubKey ) -{ - __asm { - // prologue - push ebp; - mov ebp, esp; - sub esp, __LOCAL_SIZE; - - // this needs to be saved (aes key) - push ecx; - } - - if ( g_Crypto ) - g_Crypto->m_Callback->DataEncrypted(pubPlaintextData, cubPlaintextData); - - __asm { - // call it manually here, prevent - // it from 'helpfully' using ECX - - // prep aes key in register - pop ecx; - - // push args - push cubKey; - push pcubEncryptedData; - push pubEncryptedData; - push cubPlaintextData; - push pubPlaintextData; - - // call! - call Encrypt_Orig; - - // cleanup - add esp, 0x14; - - // epilogue - mov esp, ebp; - pop ebp; - ret; - } -} - -// This function is considerably less retarded -bool __cdecl CCrypto::SymmetricDecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubKey, uint32 cubKey ) -{ - bool ret = (*Decrypt_Orig)(pubEncryptedData, cubEncryptedData, pubPlaintextData, pcubPlaintextData, pubKey, cubKey); - - if ( g_Crypto ) - g_Crypto->m_Callback->DataDecrypted(pubPlaintextData, *pcubPlaintextData); - - return ret; -} - -const char* CCrypto::GetMessage( EMsg eMsg ) -{ - static char *szMsg = new char[ 200 ]; - - int ieMsg = (int)eMsg; - - bool bRet = false; - - __asm - { - pushad - - lea esi, [ szMsg ] - mov ecx, 200 - mov edi, ieMsg - - push 0xFF - - call GetMessageFn - mov bRet, al - - popad - } - - if ( bRet ) - { - return szMsg; - } - else - { - return "INVALID"; - } -} \ No newline at end of file diff --git a/Resources/NetHook/crypto.h b/Resources/NetHook/crypto.h deleted file mode 100644 index 4e879c16..00000000 --- a/Resources/NetHook/crypto.h +++ /dev/null @@ -1,43 +0,0 @@ - -#ifndef CRYPTO_H_ -#define CRYPTO_H_ -#ifdef _WIN32 -#pragma once -#endif - -#define _WINSOCKAPI_ // god damn winsock headers - -#include "logger.h" -#include "csimpledetour.h" -#include "steam/steamtypes.h" -#include "steam/emsg.h" -#undef GetMessage - -class ICryptoCallback -{ -public: - virtual void DataEncrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData) = 0; - virtual void DataDecrypted(const uint8* pubPlaintextData, uint32 cubPlaintextData) = 0; -}; - -class CCrypto -{ -public: - CCrypto(ICryptoCallback* callback); - ~CCrypto(); - - const char* GetMessage( EMsg eMsg ); - -private: - ICryptoCallback* m_Callback; - - CSimpleDetour* Encrypt_Detour; - CSimpleDetour* Decrypt_Detour; - - static bool __cdecl SymmetricEncrypt( const uint8 *pubPlaintextData, uint32 cubPlaintextData, uint8 *pubEncryptedData, uint32 *pcubEncryptedData, uint32 cubKey ); - static bool __cdecl SymmetricDecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubKey, uint32 cubKey ); -}; - -extern CCrypto* g_Crypto; - -#endif // !CRYPTO_H_ diff --git a/Resources/NetHook/csimpledetour.cpp b/Resources/NetHook/csimpledetour.cpp deleted file mode 100644 index f3024065..00000000 --- a/Resources/NetHook/csimpledetour.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include "csimpledetour.h" - - -CSimpleDetour::CSimpleDetour(void **old, void *replacement) -{ - m_fnOld = old; - m_fnReplacement = replacement; -} - -void CSimpleDetour::Attach() -{ - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - DetourAttach(m_fnOld, m_fnReplacement); - - DetourTransactionCommit(); - - m_bAttached = true; -} - -void CSimpleDetour::Detach() -{ - if (!m_bAttached) - return; - - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - DetourDetach(m_fnOld, m_fnReplacement); - - DetourTransactionCommit(); -} \ No newline at end of file diff --git a/Resources/NetHook/csimpledetour.h b/Resources/NetHook/csimpledetour.h deleted file mode 100644 index b1f9470f..00000000 --- a/Resources/NetHook/csimpledetour.h +++ /dev/null @@ -1,56 +0,0 @@ - -#ifndef CSIMPLEDETOUR_H_ -#define CSIMPLEDETOUR_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#include "detours.h" - - -class CSimpleDetour -{ - -public: - CSimpleDetour( void **old, void *replacement ); - - void Attach(); - void Detach(); - -private: - void **m_fnOld; - void *m_fnReplacement; - - bool m_bAttached; - -}; - - -#define SETUP_SIMPLE_DETOUR(name, old, replacement) \ - CSimpleDetour name(&(void * &)old, (void *)(&(void * &)replacement)) - - -#define SETUP_DETOUR_FUNCTION( ret, conv, name, params ) \ - ret conv name##_H params; \ - ret ( conv *name##_T ) params = name; \ - CSimpleDetour *Detour_##name = new CSimpleDetour( &(void * &)name##_T, (void *)(&(void * &)name##_H) ); \ - ret conv name##_H params - -#define SETUP_DETOUR_FUNCTION_LATE( ret, conv, name, params ) \ - ret conv name##_H params; \ - ret ( conv *name##_T ) params = NULL; \ - CSimpleDetour *Detour_##name = NULL; \ - ret conv name##_H params - -#define SETUP_DETOUR_LATE( name ) \ - Detour_##name = new CSimpleDetour( &(void * &)name##_T, (void *)(&(void * &)name##_H) ) - -#define SETUP_DETOUR_EXTERN( ret, conv, name, params ) \ - extern ret ( conv *name##_T ) params; \ - extern CSimpleDetour *Detour_##name - -#define SETUP_DETOUR_TRAMP( ret, conv, name, params ) \ - ret ( conv *name##_T ) params = NULL; \ - -#endif // !CSIMPLEDETOUR_H_ diff --git a/Resources/NetHook/csimplescan.cpp b/Resources/NetHook/csimplescan.cpp deleted file mode 100644 index 3f6b0d93..00000000 --- a/Resources/NetHook/csimplescan.cpp +++ /dev/null @@ -1,44 +0,0 @@ - - -#include "csimplescan.h" - - -CSimpleScan::CSimpleScan() -{ - m_bInterfaceSet = false; -} - -CSimpleScan::CSimpleScan( const char *filename ) -{ - SetDLL( filename ); -} - -bool CSimpleScan::SetDLL( const char *filename ) -{ - m_Interface = Sys_GetFactory( filename ); - - CSigScan::sigscan_dllfunc = m_Interface; - - if ( !CSigScan::GetDllMemInfo() ) - return m_bInterfaceSet = false; - - m_bInterfaceSet = ( m_Interface != NULL ); - - return m_bInterfaceSet; -} - -bool CSimpleScan::FindFunction( const char *sig, const char *mask, void **func ) -{ - if ( !m_bInterfaceSet ) - return false; - - - m_Signature.Init( ( unsigned char * )sig, ( char * )mask, strlen( mask ) ); - - if ( !m_Signature.is_set ) - return false; - - *func = m_Signature.sig_addr; - - return true; -} \ No newline at end of file diff --git a/Resources/NetHook/csimplescan.h b/Resources/NetHook/csimplescan.h deleted file mode 100644 index e6f1b662..00000000 --- a/Resources/NetHook/csimplescan.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CSIMPLESCAN_H -#define CSIMPLESCAN_H - -#include "sigscan.h" - -class CSimpleScan -{ - -public: - CSimpleScan(); - CSimpleScan( const char *filename ); - - bool SetDLL( const char *filename ); - bool FindFunction( const char *sig, const char *mask, void **func ); - -private: - bool m_bInterfaceSet; - bool m_bDllInfo; - - CreateInterfaceFn m_Interface; - CSigScan m_Signature; - -}; - -#endif //CSIMPLESCAN_H \ No newline at end of file diff --git a/Resources/NetHook/detours.h b/Resources/NetHook/detours.h deleted file mode 100644 index 33b3a328..00000000 --- a/Resources/NetHook/detours.h +++ /dev/null @@ -1,532 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Core Detours Functionality (detours.h of detours.lib) -// -// Microsoft Research Detours Package, Version 2.1. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - -#pragma once -#ifndef _DETOURS_H_ -#define _DETOURS_H_ - -#include - -#define DETOURS_VERSION 20100 // 2.1.0 - -////////////////////////////////////////////////////////////////////////////// -// - -#if (_MSC_VER < 1299) -typedef LONG LONG_PTR; -typedef ULONG ULONG_PTR; -#endif - -#ifndef __in_z -#define __in_z -#endif - -////////////////////////////////////////////////////////////////////////////// -// -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID -{ - DWORD Data1; - WORD Data2; - WORD Data3; - BYTE Data4[ 8 ]; -} GUID; - -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name -#endif // INITGUID -#endif // !GUID_DEFINED - -#if defined(__cplusplus) -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID & -#endif // !_REFGUID_DEFINED -#else // !__cplusplus -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID * const -#endif // !_REFGUID_DEFINED -#endif // !__cplusplus - -// -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - - /////////////////////////////////////////////////// Instruction Target Macros. - // -#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) -#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) -#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" - - extern const GUID DETOUR_EXE_RESTORE_GUID; - -#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! - typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; - - /////////////////////////////////////////////////////////// Binary Structures. - // -#pragma pack(push, 8) - typedef struct _DETOUR_SECTION_HEADER - { - DWORD cbHeaderSize; - DWORD nSignature; - DWORD nDataOffset; - DWORD cbDataSize; - - DWORD nOriginalImportVirtualAddress; - DWORD nOriginalImportSize; - DWORD nOriginalBoundImportVirtualAddress; - DWORD nOriginalBoundImportSize; - - DWORD nOriginalIatVirtualAddress; - DWORD nOriginalIatSize; - DWORD nOriginalSizeOfImage; - DWORD cbPrePE; - - DWORD nOriginalClrFlags; - DWORD reserved1; - DWORD reserved2; - DWORD reserved3; - - // Followed by cbPrePE bytes of data. - } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; - - typedef struct _DETOUR_SECTION_RECORD - { - DWORD cbBytes; - DWORD nReserved; - GUID guid; - } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; - - typedef struct _DETOUR_CLR_HEADER - { - // Header versioning - ULONG cb; - USHORT MajorRuntimeVersion; - USHORT MinorRuntimeVersion; - - // Symbol table and startup information - IMAGE_DATA_DIRECTORY MetaData; - ULONG Flags; - - // Followed by the rest of the header. - } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; - - typedef struct _DETOUR_EXE_RESTORE - { - ULONG cb; - - PIMAGE_DOS_HEADER pidh; - PIMAGE_NT_HEADERS pinh; - PULONG pclrFlags; - DWORD impDirProt; - - IMAGE_DOS_HEADER idh; - IMAGE_NT_HEADERS inh; - ULONG clrFlags; - } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; - -#pragma pack(pop) - -#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ - { \ - sizeof(DETOUR_SECTION_HEADER),\ - DETOUR_SECTION_HEADER_SIGNATURE,\ - sizeof(DETOUR_SECTION_HEADER),\ - (cbSectionSize),\ - \ - 0,\ - 0,\ - 0,\ - 0,\ - \ - 0,\ - 0,\ - 0,\ - 0,\ - } - - ///////////////////////////////////////////////////////////// Binary Typedefs. - // - typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(PVOID pContext, - PCHAR pszFile, - PCHAR *ppszOutFile); - - typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(PVOID pContext, - PCHAR pszOrigFile, - PCHAR pszFile, - PCHAR *ppszOutFile); - - typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(PVOID pContext, - ULONG nOrigOrdinal, - ULONG nOrdinal, - ULONG *pnOutOrdinal, - PCHAR pszOrigSymbol, - PCHAR pszSymbol, - PCHAR *ppszOutSymbol); - - typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)(PVOID pContext); - - typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(PVOID pContext, - ULONG nOrdinal, - PCHAR pszName, - PVOID pCode); - - typedef VOID * PDETOUR_BINARY; - typedef VOID * PDETOUR_LOADED_BINARY; - - //////////////////////////////////////////////////////////// Detours 2.1 APIs. - // - - LONG WINAPI DetourTransactionBegin(); - LONG WINAPI DetourTransactionAbort(); - LONG WINAPI DetourTransactionCommit(); - LONG WINAPI DetourTransactionCommitEx(PVOID **pppFailedPointer); - - LONG WINAPI DetourUpdateThread(HANDLE hThread); - - LONG WINAPI DetourAttach(PVOID *ppPointer, - PVOID pDetour); - - LONG WINAPI DetourAttachEx(PVOID *ppPointer, - PVOID pDetour, - PDETOUR_TRAMPOLINE *ppRealTrampoline, - PVOID *ppRealTarget, - PVOID *ppRealDetour); - - LONG WINAPI DetourDetach(PVOID *ppPointer, - PVOID pDetour); - - VOID WINAPI DetourSetIgnoreTooSmall(BOOL fIgnore); - - ////////////////////////////////////////////////////////////// Code Functions. - // - PVOID WINAPI DetourFindFunction(PCSTR pszModule, PCSTR pszFunction); - PVOID WINAPI DetourCodeFromPointer(PVOID pPointer, PVOID *ppGlobals); - - PVOID WINAPI DetourCopyInstruction(PVOID pDst, PVOID pSrc, PVOID *ppTarget); - PVOID WINAPI DetourCopyInstructionEx(PVOID pDst, - PVOID pSrc, - PVOID *ppTarget, - LONG *plExtra); - - ///////////////////////////////////////////////////// Loaded Binary Functions. - // - HMODULE WINAPI DetourEnumerateModules(HMODULE hModuleLast); - PVOID WINAPI DetourGetEntryPoint(HMODULE hModule); - ULONG WINAPI DetourGetModuleSize(HMODULE hModule); - BOOL WINAPI DetourEnumerateExports(HMODULE hModule, - PVOID pContext, - PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); - - PVOID WINAPI DetourFindPayload(HMODULE hModule, REFGUID rguid, DWORD *pcbData); - DWORD WINAPI DetourGetSizeOfPayloads(HMODULE hModule); - - ///////////////////////////////////////////////// Persistent Binary Functions. - // - - PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile); - PVOID WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pBinary, - GUID *pGuid, - DWORD *pcbData, - DWORD *pnIterator); - PVOID WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pBinary, - REFGUID rguid, - DWORD *pcbData); - PVOID WINAPI DetourBinarySetPayload(PDETOUR_BINARY pBinary, - REFGUID rguid, - PVOID pData, - DWORD cbData); - BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pBinary, REFGUID rguid); - BOOL WINAPI DetourBinaryPurgePayloads(PDETOUR_BINARY pBinary); - BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pBinary); - BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pBinary, - PVOID pContext, - PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, - PF_DETOUR_BINARY_FILE_CALLBACK pfFile, - PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, - PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); - BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pBinary, HANDLE hFile); - BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pBinary); - - /////////////////////////////////////////////////// Create Process & Load Dll. - // - typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA) - (LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation); - - typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW) - (LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation); - - BOOL WINAPI DetourCreateProcessWithDllA(LPCSTR lpApplicationName, - __in_z LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - LPCSTR lpDetouredDllFullName, - LPCSTR lpDllName, - PDETOUR_CREATE_PROCESS_ROUTINEA - pfCreateProcessA); - - BOOL WINAPI DetourCreateProcessWithDllW(LPCWSTR lpApplicationName, - __in_z LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - LPCSTR lpDetouredDllFullName, - LPCSTR lpDllName, - PDETOUR_CREATE_PROCESS_ROUTINEW - pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDll DetourCreateProcessWithDllW -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW -#else -#define DetourCreateProcessWithDll DetourCreateProcessWithDllA -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA -#endif // !UNICODE - - BOOL WINAPI DetourCopyPayloadToProcess(HANDLE hProcess, - REFGUID rguid, - PVOID pvData, - DWORD cbData); - BOOL WINAPI DetourRestoreAfterWith(); - BOOL WINAPI DetourRestoreAfterWithEx(PVOID pvData, DWORD cbData); - - HMODULE WINAPI DetourGetDetouredMarker(); - - // - ////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -} -#endif // __cplusplus - -//////////////////////////////////////////////// Detours Internal Definitions. -// -#ifdef __cplusplus -#ifdef DETOURS_INTERNAL - -#ifndef __deref_out -#define __deref_out -#endif - -#ifndef __deref -#define __deref -#endif - -////////////////////////////////////////////////////////////////////////////// -// -#if (_MSC_VER < 1299) -#include -typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; -typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; -typedef IMAGEHLP_SYMBOL SYMBOL_INFO; -typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; - -static inline -LONG InterlockedCompareExchange(LONG *ptr, LONG nval, LONG oval) -{ - return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); -} -#else -#include -#endif - -#ifdef IMAGEAPI // defined by DBGHELP.H -typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion); - -typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess, - IN LPCSTR UserSearchPath, - IN BOOL fInvadeProcess); -typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions); -typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); -typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess, - IN HANDLE hFile, - IN PSTR ImageName, - IN PSTR ModuleName, - IN DWORD64 BaseOfDll, - IN DWORD SizeOfDll); -typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess, - IN DWORD64 qwAddr, - OUT PIMAGEHLP_MODULE64 ModuleInfo); -typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess, - IN LPSTR Name, - OUT PSYMBOL_INFO Symbol); - -typedef struct _DETOUR_SYM_INFO -{ - HANDLE hProcess; - HMODULE hDbgHelp; - PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; - PF_SymInitialize pfSymInitialize; - PF_SymSetOptions pfSymSetOptions; - PF_SymGetOptions pfSymGetOptions; - PF_SymLoadModule64 pfSymLoadModule64; - PF_SymGetModuleInfo64 pfSymGetModuleInfo64; - PF_SymFromName pfSymFromName; -} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; - -PDETOUR_SYM_INFO DetourLoadDbgHelp(VOID); - -#endif // IMAGEAPI - -#ifndef DETOUR_TRACE -#if DETOUR_DEBUG -#define DETOUR_TRACE(x) printf x -#define DETOUR_BREAK() DebugBreak() -#include -#include -#else -#define DETOUR_TRACE(x) -#define DETOUR_BREAK() -#endif -#endif - -#ifdef DETOURS_IA64 -__declspec(align(16)) struct DETOUR_IA64_BUNDLE -{ -public: - union - { - BYTE data[16]; - UINT64 wide[2]; - }; - -public: - struct DETOUR_IA64_METADATA; - - typedef BOOL (DETOUR_IA64_BUNDLE::* DETOUR_IA64_METACOPY) - (const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - - enum { - A_UNIT = 1u, - I_UNIT = 2u, - M_UNIT = 3u, - B_UNIT = 4u, - F_UNIT = 5u, - L_UNIT = 6u, - X_UNIT = 7u, - UNIT_MASK = 7u, - STOP = 8u - }; - struct DETOUR_IA64_METADATA - { - ULONG nTemplate : 8; // Instruction template. - ULONG nUnit0 : 4; // Unit for slot 0 - ULONG nUnit1 : 4; // Unit for slot 1 - ULONG nUnit2 : 4; // Unit for slot 2 - DETOUR_IA64_METACOPY pfCopy; // Function pointer. - }; - -protected: - BOOL CopyBytes(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - BOOL CopyBytesMMB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - BOOL CopyBytesMBB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - BOOL CopyBytesBBB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - BOOL CopyBytesMLX(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; - - static const DETOUR_IA64_METADATA s_rceCopyTable[33]; - -public: - // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 - // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. - - // 00 - // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. - // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] - // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] - // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] - // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] - // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] - // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] - // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] - BYTE GetTemplate() const; - BYTE GetInst0() const; - BYTE GetInst1() const; - BYTE GetInst2() const; - BYTE GetUnit0() const; - BYTE GetUnit1() const; - BYTE GetUnit2() const; - UINT64 GetData0() const; - UINT64 GetData1() const; - UINT64 GetData2() const; - -public: - BOOL IsBrl() const; - VOID SetBrl(); - VOID SetBrl(UINT64 target); - UINT64 GetBrlTarget() const; - VOID SetBrlTarget(UINT64 target); - VOID SetBrlImm(UINT64 imm); - UINT64 GetBrlImm() const; - - BOOL IsMovlGp() const; - UINT64 GetMovlGp() const; - VOID SetMovlGp(UINT64 gp); - - VOID SetInst0(BYTE nInst); - VOID SetInst1(BYTE nInst); - VOID SetInst2(BYTE nInst); - VOID SetData0(UINT64 nData); - VOID SetData1(UINT64 nData); - VOID SetData2(UINT64 nData); - BOOL SetNop0(); - BOOL SetNop1(); - BOOL SetNop2(); - BOOL SetStop(); - - BOOL Copy(DETOUR_IA64_BUNDLE *pDst) const; -}; -#endif // DETOURS_IA64 - -////////////////////////////////////////////////////////////////////////////// - -#endif // DETOURS_INTERNAL -#endif // __cplusplus - -#endif // _DETOURS_H_ -// -//////////////////////////////////////////////////////////////// End of File. diff --git a/Resources/NetHook/detours.lib b/Resources/NetHook/detours.lib deleted file mode 100644 index 3bdca0756bb8eead2125ee82561880a397374081..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202552 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 P9%ZjwHpmtP=|%qq>>i-U diff --git a/Resources/NetHook/google/protobuf/descriptor.cc b/Resources/NetHook/google/protobuf/descriptor.cc deleted file mode 100644 index 81c4ac0f..00000000 --- a/Resources/NetHook/google/protobuf/descriptor.cc +++ /dev/null @@ -1,4401 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef PACKAGE // autoheader #defines this. :( - -namespace google { -namespace protobuf { - -const FieldDescriptor::CppType -FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { - static_cast(0), // 0 is reserved for errors - - CPPTYPE_DOUBLE, // TYPE_DOUBLE - CPPTYPE_FLOAT, // TYPE_FLOAT - CPPTYPE_INT64, // TYPE_INT64 - CPPTYPE_UINT64, // TYPE_UINT64 - CPPTYPE_INT32, // TYPE_INT32 - CPPTYPE_UINT64, // TYPE_FIXED64 - CPPTYPE_UINT32, // TYPE_FIXED32 - CPPTYPE_BOOL, // TYPE_BOOL - CPPTYPE_STRING, // TYPE_STRING - CPPTYPE_MESSAGE, // TYPE_GROUP - CPPTYPE_MESSAGE, // TYPE_MESSAGE - CPPTYPE_STRING, // TYPE_BYTES - CPPTYPE_UINT32, // TYPE_UINT32 - CPPTYPE_ENUM, // TYPE_ENUM - CPPTYPE_INT32, // TYPE_SFIXED32 - CPPTYPE_INT64, // TYPE_SFIXED64 - CPPTYPE_INT32, // TYPE_SINT32 - CPPTYPE_INT64, // TYPE_SINT64 -}; - -const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { - "ERROR", // 0 is reserved for errors - - "double", // TYPE_DOUBLE - "float", // TYPE_FLOAT - "int64", // TYPE_INT64 - "uint64", // TYPE_UINT64 - "int32", // TYPE_INT32 - "fixed64", // TYPE_FIXED64 - "fixed32", // TYPE_FIXED32 - "bool", // TYPE_BOOL - "string", // TYPE_STRING - "group", // TYPE_GROUP - "message", // TYPE_MESSAGE - "bytes", // TYPE_BYTES - "uint32", // TYPE_UINT32 - "enum", // TYPE_ENUM - "sfixed32", // TYPE_SFIXED32 - "sfixed64", // TYPE_SFIXED64 - "sint32", // TYPE_SINT32 - "sint64", // TYPE_SINT64 -}; - -const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { - "ERROR", // 0 is reserved for errors - - "optional", // LABEL_OPTIONAL - "required", // LABEL_REQUIRED - "repeated", // LABEL_REPEATED -}; - -#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them. -const int FieldDescriptor::kMaxNumber; -const int FieldDescriptor::kFirstReservedNumber; -const int FieldDescriptor::kLastReservedNumber; -#endif - -namespace { - -const string kEmptyString; - -string ToCamelCase(const string& input) { - bool capitalize_next = false; - string result; - result.reserve(input.size()); - - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { - capitalize_next = true; - } else if (capitalize_next) { - // Note: I distrust ctype.h due to locales. - if ('a' <= input[i] && input[i] <= 'z') { - result.push_back(input[i] - 'a' + 'A'); - } else { - result.push_back(input[i]); - } - capitalize_next = false; - } else { - result.push_back(input[i]); - } - } - - // Lower-case the first letter. - if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') { - result[0] = result[0] - 'A' + 'a'; - } - - return result; -} - -// A DescriptorPool contains a bunch of hash_maps to implement the -// various Find*By*() methods. Since hashtable lookups are O(1), it's -// most efficient to construct a fixed set of large hash_maps used by -// all objects in the pool rather than construct one or more small -// hash_maps for each object. -// -// The keys to these hash_maps are (parent, name) or (parent, number) -// pairs. Unfortunately STL doesn't provide hash functions for pair<>, -// so we must invent our own. -// -// TODO(kenton): Use StringPiece rather than const char* in keys? It would -// be a lot cleaner but we'd just have to convert it back to const char* -// for the open source release. - -typedef pair PointerStringPair; - -struct PointerStringPairEqual { - inline bool operator()(const PointerStringPair& a, - const PointerStringPair& b) const { - return a.first == b.first && strcmp(a.second, b.second) == 0; - } -}; - -template -struct PointerIntegerPairHash { - size_t operator()(const PairType& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - return reinterpret_cast(p.first) * ((1 << 16) - 1) + p.second; - } - - // Used only by MSVC and platforms where hash_map is not available. - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline bool operator()(const PairType& a, const PairType& b) const { - return a.first < b.first || - (a.first == b.first && a.second < b.second); - } -}; - -typedef pair DescriptorIntPair; -typedef pair EnumIntPair; - -struct PointerStringPairHash { - size_t operator()(const PointerStringPair& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - hash cstring_hash; - return reinterpret_cast(p.first) * ((1 << 16) - 1) + - cstring_hash(p.second); - } - - // Used only by MSVC and platforms where hash_map is not available. - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline bool operator()(const PointerStringPair& a, - const PointerStringPair& b) const { - if (a.first < b.first) return true; - if (a.first > b.first) return false; - return strcmp(a.second, b.second) < 0; - } -}; - - -struct Symbol { - enum Type { - NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE - }; - Type type; - union { - const Descriptor* descriptor; - const FieldDescriptor* field_descriptor; - const EnumDescriptor* enum_descriptor; - const EnumValueDescriptor* enum_value_descriptor; - const ServiceDescriptor* service_descriptor; - const MethodDescriptor* method_descriptor; - const FileDescriptor* package_file_descriptor; - }; - - inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } - inline bool IsNull() const { return type == NULL_SYMBOL; } - inline bool IsType() const { - return type == MESSAGE || type == ENUM; - } - inline bool IsAggregate() const { - return type == MESSAGE || type == PACKAGE - || type == ENUM || type == SERVICE; - } - -#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ - inline explicit Symbol(const TYPE* value) { \ - type = TYPE_CONSTANT; \ - this->FIELD = value; \ - } - - CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) - CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) - CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) - CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) - CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) - CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) - CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) -#undef CONSTRUCTOR - - const FileDescriptor* GetFile() const { - switch (type) { - case NULL_SYMBOL: return NULL; - case MESSAGE : return descriptor ->file(); - case FIELD : return field_descriptor ->file(); - case ENUM : return enum_descriptor ->file(); - case ENUM_VALUE : return enum_value_descriptor->type()->file(); - case SERVICE : return service_descriptor ->file(); - case METHOD : return method_descriptor ->service()->file(); - case PACKAGE : return package_file_descriptor; - } - return NULL; - } -}; - -const Symbol kNullSymbol; - -typedef hash_map, streq> - SymbolsByNameMap; -typedef hash_map - SymbolsByParentMap; -typedef hash_map, streq> - FilesByNameMap; -typedef hash_map - FieldsByNameMap; -typedef hash_map > - FieldsByNumberMap; -typedef hash_map > - EnumValuesByNumberMap; -// This is a map rather than a hash_map, since we use it to iterate -// through all the extensions that extend a given Descriptor, and an -// ordered data structure that implements lower_bound is convenient -// for that. -typedef map - ExtensionsGroupedByDescriptorMap; - -} // anonymous namespace - -// =================================================================== -// DescriptorPool::Tables - -class DescriptorPool::Tables { - public: - Tables(); - ~Tables(); - - // Checkpoint the state of the tables. Future calls to Rollback() will - // return the Tables to this state. This is used when building files, since - // some kinds of validation errors cannot be detected until the file's - // descriptors have already been added to the tables. BuildFile() calls - // Checkpoint() before it starts building and Rollback() if it encounters - // an error. - void Checkpoint(); - - // Roll back the Tables to the state of the last Checkpoint(), removing - // everything that was added after that point. - void Rollback(); - - // The stack of files which are currently being built. Used to detect - // cyclic dependencies when loading files from a DescriptorDatabase. Not - // used when fallback_database_ == NULL. - vector pending_files_; - - // A set of files which we have tried to load from the fallback database - // and encountered errors. We will not attempt to load them again. - // Not used when fallback_database_ == NULL. - hash_set known_bad_files_; - - // The set of descriptors for which we've already loaded the full - // set of extensions numbers from fallback_database_. - hash_set extensions_loaded_from_db_; - - // ----------------------------------------------------------------- - // Finding items. - - // Find symbols. This returns a null Symbol (symbol.IsNull() is true) - // if not found. - inline Symbol FindSymbol(const string& key) const; - - // This implements the body of DescriptorPool::Find*ByName(). It should - // really be a private method of DescriptorPool, but that would require - // declaring Symbol in descriptor.h, which would drag all kinds of other - // stuff into the header. Yay C++. - Symbol FindByNameHelper( - const DescriptorPool* pool, const string& name) const; - - // These return NULL if not found. - inline const FileDescriptor* FindFile(const string& key) const; - inline const FieldDescriptor* FindExtension(const Descriptor* extendee, - int number); - inline void FindAllExtensions(const Descriptor* extendee, - vector* out) const; - - // ----------------------------------------------------------------- - // Adding items. - - // These add items to the corresponding tables. They return false if - // the key already exists in the table. For AddSymbol(), the string passed - // in must be one that was constructed using AllocateString(), as it will - // be used as a key in the symbols_by_name_ map without copying. - bool AddSymbol(const string& full_name, Symbol symbol); - bool AddFile(const FileDescriptor* file); - bool AddExtension(const FieldDescriptor* field); - - // ----------------------------------------------------------------- - // Allocating memory. - - // Allocate an object which will be reclaimed when the pool is - // destroyed. Note that the object's destructor will never be called, - // so its fields must be plain old data (primitive data types and - // pointers). All of the descriptor types are such objects. - template Type* Allocate(); - - // Allocate an array of objects which will be reclaimed when the - // pool in destroyed. Again, destructors are never called. - template Type* AllocateArray(int count); - - // Allocate a string which will be destroyed when the pool is destroyed. - // The string is initialized to the given value for convenience. - string* AllocateString(const string& value); - - // Allocate a protocol message object. Some older versions of GCC have - // trouble understanding explicit template instantiations in some cases, so - // in those cases we have to pass a dummy pointer of the right type as the - // parameter instead of specifying the type explicitly. - template Type* AllocateMessage(Type* dummy = NULL); - - // Allocate a FileDescriptorTables object. - FileDescriptorTables* AllocateFileTables(); - - private: - vector strings_; // All strings in the pool. - vector messages_; // All messages in the pool. - vector file_tables_; // All file tables in the pool. - vector allocations_; // All other memory allocated in the pool. - - SymbolsByNameMap symbols_by_name_; - FilesByNameMap files_by_name_; - ExtensionsGroupedByDescriptorMap extensions_; - - int strings_before_checkpoint_; - int messages_before_checkpoint_; - int file_tables_before_checkpoint_; - int allocations_before_checkpoint_; - vector symbols_after_checkpoint_; - vector files_after_checkpoint_; - vector extensions_after_checkpoint_; - - // Allocate some bytes which will be reclaimed when the pool is - // destroyed. - void* AllocateBytes(int size); -}; - -// Contains tables specific to a particular file. These tables are not -// modified once the file has been constructed, so they need not be -// protected by a mutex. This makes operations that depend only on the -// contents of a single file -- e.g. Descriptor::FindFieldByName() -- -// lock-free. -// -// For historical reasons, the definitions of the methods of -// FileDescriptorTables and DescriptorPool::Tables are interleaved below. -// These used to be a single class. -class FileDescriptorTables { - public: - FileDescriptorTables(); - ~FileDescriptorTables(); - - // Empty table, used with placeholder files. - static const FileDescriptorTables kEmpty; - - // ----------------------------------------------------------------- - // Finding items. - - // Find symbols. These return a null Symbol (symbol.IsNull() is true) - // if not found. - inline Symbol FindNestedSymbol(const void* parent, - const string& name) const; - inline Symbol FindNestedSymbolOfType(const void* parent, - const string& name, - const Symbol::Type type) const; - - // These return NULL if not found. - inline const FieldDescriptor* FindFieldByNumber( - const Descriptor* parent, int number) const; - inline const FieldDescriptor* FindFieldByLowercaseName( - const void* parent, const string& lowercase_name) const; - inline const FieldDescriptor* FindFieldByCamelcaseName( - const void* parent, const string& camelcase_name) const; - inline const EnumValueDescriptor* FindEnumValueByNumber( - const EnumDescriptor* parent, int number) const; - - // ----------------------------------------------------------------- - // Adding items. - - // These add items to the corresponding tables. They return false if - // the key already exists in the table. For AddAliasUnderParent(), the - // string passed in must be one that was constructed using AllocateString(), - // as it will be used as a key in the symbols_by_parent_ map without copying. - bool AddAliasUnderParent(const void* parent, const string& name, - Symbol symbol); - bool AddFieldByNumber(const FieldDescriptor* field); - bool AddEnumValueByNumber(const EnumValueDescriptor* value); - - // Adds the field to the lowercase_name and camelcase_name maps. Never - // fails because we allow duplicates; the first field by the name wins. - void AddFieldByStylizedNames(const FieldDescriptor* field); - - private: - SymbolsByParentMap symbols_by_parent_; - FieldsByNameMap fields_by_lowercase_name_; - FieldsByNameMap fields_by_camelcase_name_; - FieldsByNumberMap fields_by_number_; // Not including extensions. - EnumValuesByNumberMap enum_values_by_number_; -}; - -DescriptorPool::Tables::Tables() - : strings_before_checkpoint_(0), - messages_before_checkpoint_(0), - allocations_before_checkpoint_(0) {} - -DescriptorPool::Tables::~Tables() { - // Note that the deletion order is important, since the destructors of some - // messages may refer to objects in allocations_. - STLDeleteElements(&messages_); - for (int i = 0; i < allocations_.size(); i++) { - operator delete(allocations_[i]); - } - STLDeleteElements(&strings_); - STLDeleteElements(&file_tables_); -} - -FileDescriptorTables::FileDescriptorTables() {} -FileDescriptorTables::~FileDescriptorTables() {} - -const FileDescriptorTables FileDescriptorTables::kEmpty; - -void DescriptorPool::Tables::Checkpoint() { - strings_before_checkpoint_ = strings_.size(); - messages_before_checkpoint_ = messages_.size(); - file_tables_before_checkpoint_ = file_tables_.size(); - allocations_before_checkpoint_ = allocations_.size(); - - symbols_after_checkpoint_.clear(); - files_after_checkpoint_.clear(); - extensions_after_checkpoint_.clear(); -} - -void DescriptorPool::Tables::Rollback() { - for (int i = 0; i < symbols_after_checkpoint_.size(); i++) { - symbols_by_name_.erase(symbols_after_checkpoint_[i]); - } - for (int i = 0; i < files_after_checkpoint_.size(); i++) { - files_by_name_.erase(files_after_checkpoint_[i]); - } - for (int i = 0; i < extensions_after_checkpoint_.size(); i++) { - extensions_.erase(extensions_after_checkpoint_[i]); - } - - symbols_after_checkpoint_.clear(); - files_after_checkpoint_.clear(); - extensions_after_checkpoint_.clear(); - - STLDeleteContainerPointers( - strings_.begin() + strings_before_checkpoint_, strings_.end()); - STLDeleteContainerPointers( - messages_.begin() + messages_before_checkpoint_, messages_.end()); - STLDeleteContainerPointers( - file_tables_.begin() + file_tables_before_checkpoint_, file_tables_.end()); - for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) { - operator delete(allocations_[i]); - } - - strings_.resize(strings_before_checkpoint_); - messages_.resize(messages_before_checkpoint_); - file_tables_.resize(file_tables_before_checkpoint_); - allocations_.resize(allocations_before_checkpoint_); -} - -// ------------------------------------------------------------------- - -inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { - const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); - if (result == NULL) { - return kNullSymbol; - } else { - return *result; - } -} - -inline Symbol FileDescriptorTables::FindNestedSymbol( - const void* parent, const string& name) const { - const Symbol* result = - FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); - if (result == NULL) { - return kNullSymbol; - } else { - return *result; - } -} - -inline Symbol FileDescriptorTables::FindNestedSymbolOfType( - const void* parent, const string& name, const Symbol::Type type) const { - Symbol result = FindNestedSymbol(parent, name); - if (result.type != type) return kNullSymbol; - return result; -} - -Symbol DescriptorPool::Tables::FindByNameHelper( - const DescriptorPool* pool, const string& name) const { - MutexLockMaybe lock(pool->mutex_); - Symbol result = FindSymbol(name); - - if (result.IsNull() && pool->underlay_ != NULL) { - // Symbol not found; check the underlay. - result = - pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); - } - - if (result.IsNull()) { - // Symbol still not found, so check fallback database. - if (pool->TryFindSymbolInFallbackDatabase(name)) { - result = FindSymbol(name); - } - } - - return result; -} - -inline const FileDescriptor* DescriptorPool::Tables::FindFile( - const string& key) const { - return FindPtrOrNull(files_by_name_, key.c_str()); -} - -inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( - const Descriptor* parent, int number) const { - return FindPtrOrNull(fields_by_number_, make_pair(parent, number)); -} - -inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( - const void* parent, const string& lowercase_name) const { - return FindPtrOrNull(fields_by_lowercase_name_, - PointerStringPair(parent, lowercase_name.c_str())); -} - -inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( - const void* parent, const string& camelcase_name) const { - return FindPtrOrNull(fields_by_camelcase_name_, - PointerStringPair(parent, camelcase_name.c_str())); -} - -inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( - const EnumDescriptor* parent, int number) const { - return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number)); -} - -inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( - const Descriptor* extendee, int number) { - return FindPtrOrNull(extensions_, make_pair(extendee, number)); -} - -inline void DescriptorPool::Tables::FindAllExtensions( - const Descriptor* extendee, vector* out) const { - ExtensionsGroupedByDescriptorMap::const_iterator it = - extensions_.lower_bound(make_pair(extendee, 0)); - for (; it != extensions_.end() && it->first.first == extendee; ++it) { - out->push_back(it->second); - } -} - -// ------------------------------------------------------------------- - -bool DescriptorPool::Tables::AddSymbol( - const string& full_name, Symbol symbol) { - if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { - symbols_after_checkpoint_.push_back(full_name.c_str()); - return true; - } else { - return false; - } -} - -bool FileDescriptorTables::AddAliasUnderParent( - const void* parent, const string& name, Symbol symbol) { - PointerStringPair by_parent_key(parent, name.c_str()); - return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); -} - -bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { - if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { - files_after_checkpoint_.push_back(file->name().c_str()); - return true; - } else { - return false; - } -} - -void FileDescriptorTables::AddFieldByStylizedNames( - const FieldDescriptor* field) { - const void* parent; - if (field->is_extension()) { - if (field->extension_scope() == NULL) { - parent = field->file(); - } else { - parent = field->extension_scope(); - } - } else { - parent = field->containing_type(); - } - - PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); - InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); - - PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); - InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); -} - -bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) { - DescriptorIntPair key(field->containing_type(), field->number()); - return InsertIfNotPresent(&fields_by_number_, key, field); -} - -bool FileDescriptorTables::AddEnumValueByNumber( - const EnumValueDescriptor* value) { - EnumIntPair key(value->type(), value->number()); - return InsertIfNotPresent(&enum_values_by_number_, key, value); -} - -bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { - DescriptorIntPair key(field->containing_type(), field->number()); - if (InsertIfNotPresent(&extensions_, key, field)) { - extensions_after_checkpoint_.push_back(key); - return true; - } else { - return false; - } -} - -// ------------------------------------------------------------------- - -template -Type* DescriptorPool::Tables::Allocate() { - return reinterpret_cast(AllocateBytes(sizeof(Type))); -} - -template -Type* DescriptorPool::Tables::AllocateArray(int count) { - return reinterpret_cast(AllocateBytes(sizeof(Type) * count)); -} - -string* DescriptorPool::Tables::AllocateString(const string& value) { - string* result = new string(value); - strings_.push_back(result); - return result; -} - -template -Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) { - Type* result = new Type; - messages_.push_back(result); - return result; -} - -FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { - FileDescriptorTables* result = new FileDescriptorTables; - file_tables_.push_back(result); - return result; -} - -void* DescriptorPool::Tables::AllocateBytes(int size) { - // TODO(kenton): Would it be worthwhile to implement this in some more - // sophisticated way? Probably not for the open source release, but for - // internal use we could easily plug in one of our existing memory pool - // allocators... - if (size == 0) return NULL; - - void* result = operator new(size); - allocations_.push_back(result); - return result; -} - -// =================================================================== -// DescriptorPool - -DescriptorPool::ErrorCollector::~ErrorCollector() {} - -DescriptorPool::DescriptorPool() - : mutex_(NULL), - fallback_database_(NULL), - default_error_collector_(NULL), - underlay_(NULL), - tables_(new Tables), - enforce_dependencies_(true), - allow_unknown_(false) {} - -DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, - ErrorCollector* error_collector) - : mutex_(new Mutex), - fallback_database_(fallback_database), - default_error_collector_(error_collector), - underlay_(NULL), - tables_(new Tables), - enforce_dependencies_(true), - allow_unknown_(false) { -} - -DescriptorPool::DescriptorPool(const DescriptorPool* underlay) - : mutex_(NULL), - fallback_database_(NULL), - default_error_collector_(NULL), - underlay_(underlay), - tables_(new Tables), - enforce_dependencies_(true), - allow_unknown_(false) {} - -DescriptorPool::~DescriptorPool() { - if (mutex_ != NULL) delete mutex_; -} - -// DescriptorPool::BuildFile() defined later. -// DescriptorPool::BuildFileCollectingErrors() defined later. - -void DescriptorPool::InternalDontEnforceDependencies() { - enforce_dependencies_ = false; -} - -bool DescriptorPool::InternalIsFileLoaded(const string& filename) const { - MutexLockMaybe lock(mutex_); - return tables_->FindFile(filename) != NULL; -} - -// generated_pool ==================================================== - -namespace { - - -EncodedDescriptorDatabase* generated_database_ = NULL; -DescriptorPool* generated_pool_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); - -void DeleteGeneratedPool() { - delete generated_database_; - generated_database_ = NULL; - delete generated_pool_; - generated_pool_ = NULL; -} - -void InitGeneratedPool() { - generated_database_ = new EncodedDescriptorDatabase; - generated_pool_ = new DescriptorPool(generated_database_); - - internal::OnShutdown(&DeleteGeneratedPool); -} - -inline void InitGeneratedPoolOnce() { - ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); -} - -} // anonymous namespace - -const DescriptorPool* DescriptorPool::generated_pool() { - InitGeneratedPoolOnce(); - return generated_pool_; -} - -DescriptorPool* DescriptorPool::internal_generated_pool() { - InitGeneratedPoolOnce(); - return generated_pool_; -} - -void DescriptorPool::InternalAddGeneratedFile( - const void* encoded_file_descriptor, int size) { - // So, this function is called in the process of initializing the - // descriptors for generated proto classes. Each generated .pb.cc file - // has an internal procedure called AddDescriptors() which is called at - // process startup, and that function calls this one in order to register - // the raw bytes of the FileDescriptorProto representing the file. - // - // We do not actually construct the descriptor objects right away. We just - // hang on to the bytes until they are actually needed. We actually construct - // the descriptor the first time one of the following things happens: - // * Someone calls a method like descriptor(), GetDescriptor(), or - // GetReflection() on the generated types, which requires returning the - // descriptor or an object based on it. - // * Someone looks up the descriptor in DescriptorPool::generated_pool(). - // - // Once one of these happens, the DescriptorPool actually parses the - // FileDescriptorProto and generates a FileDescriptor (and all its children) - // based on it. - // - // Note that FileDescriptorProto is itself a generated protocol message. - // Therefore, when we parse one, we have to be very careful to avoid using - // any descriptor-based operations, since this might cause infinite recursion - // or deadlock. - InitGeneratedPoolOnce(); - GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size)); -} - - -// Find*By* methods ================================================== - -// TODO(kenton): There's a lot of repeated code here, but I'm not sure if -// there's any good way to factor it out. Think about this some time when -// there's nothing more important to do (read: never). - -const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { - MutexLockMaybe lock(mutex_); - const FileDescriptor* result = tables_->FindFile(name); - if (result != NULL) return result; - if (underlay_ != NULL) { - const FileDescriptor* result = underlay_->FindFileByName(name); - if (result != NULL) return result; - } - if (TryFindFileInFallbackDatabase(name)) { - const FileDescriptor* result = tables_->FindFile(name); - if (result != NULL) return result; - } - return NULL; -} - -const FileDescriptor* DescriptorPool::FindFileContainingSymbol( - const string& symbol_name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbol(symbol_name); - if (!result.IsNull()) return result.GetFile(); - if (underlay_ != NULL) { - const FileDescriptor* result = - underlay_->FindFileContainingSymbol(symbol_name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(symbol_name)) { - Symbol result = tables_->FindSymbol(symbol_name); - if (!result.IsNull()) return result.GetFile(); - } - return NULL; -} - -const Descriptor* DescriptorPool::FindMessageTypeByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL; -} - -const FieldDescriptor* DescriptorPool::FindFieldByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - if (result.type == Symbol::FIELD && - !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* DescriptorPool::FindExtensionByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - if (result.type == Symbol::FIELD && - result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const EnumDescriptor* DescriptorPool::FindEnumTypeByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL; -} - -const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::ENUM_VALUE) ? - result.enum_value_descriptor : NULL; -} - -const ServiceDescriptor* DescriptorPool::FindServiceByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL; -} - -const MethodDescriptor* DescriptorPool::FindMethodByName( - const string& name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL; -} - -const FieldDescriptor* DescriptorPool::FindExtensionByNumber( - const Descriptor* extendee, int number) const { - MutexLockMaybe lock(mutex_); - const FieldDescriptor* result = tables_->FindExtension(extendee, number); - if (result != NULL) { - return result; - } - if (underlay_ != NULL) { - const FieldDescriptor* result = - underlay_->FindExtensionByNumber(extendee, number); - if (result != NULL) return result; - } - if (TryFindExtensionInFallbackDatabase(extendee, number)) { - const FieldDescriptor* result = tables_->FindExtension(extendee, number); - if (result != NULL) { - return result; - } - } - return NULL; -} - -void DescriptorPool::FindAllExtensions( - const Descriptor* extendee, vector* out) const { - MutexLockMaybe lock(mutex_); - - // Initialize tables_->extensions_ from the fallback database first - // (but do this only once per descriptor). - if (fallback_database_ != NULL && - tables_->extensions_loaded_from_db_.count(extendee) == 0) { - vector numbers; - if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), - &numbers)) { - for (int i = 0; i < numbers.size(); ++i) { - int number = numbers[i]; - if (tables_->FindExtension(extendee, number) == NULL) { - TryFindExtensionInFallbackDatabase(extendee, number); - } - } - tables_->extensions_loaded_from_db_.insert(extendee); - } - } - - tables_->FindAllExtensions(extendee, out); - if (underlay_ != NULL) { - underlay_->FindAllExtensions(extendee, out); - } -} - -// ------------------------------------------------------------------- - -const FieldDescriptor* -Descriptor::FindFieldByNumber(int key) const { - const FieldDescriptor* result = - file()->tables_->FindFieldByNumber(this, key); - if (result == NULL || result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -Descriptor::FindFieldByLowercaseName(const string& key) const { - const FieldDescriptor* result = - file()->tables_->FindFieldByLowercaseName(this, key); - if (result == NULL || result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -Descriptor::FindFieldByCamelcaseName(const string& key) const { - const FieldDescriptor* result = - file()->tables_->FindFieldByCamelcaseName(this, key); - if (result == NULL || result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -Descriptor::FindFieldByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -Descriptor::FindExtensionByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -Descriptor::FindExtensionByLowercaseName(const string& key) const { - const FieldDescriptor* result = - file()->tables_->FindFieldByLowercaseName(this, key); - if (result == NULL || !result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -Descriptor::FindExtensionByCamelcaseName(const string& key) const { - const FieldDescriptor* result = - file()->tables_->FindFieldByCamelcaseName(this, key); - if (result == NULL || !result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const Descriptor* -Descriptor::FindNestedTypeByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return NULL; - } -} - -const EnumDescriptor* -Descriptor::FindEnumTypeByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -Descriptor::FindEnumValueByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -EnumDescriptor::FindValueByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -EnumDescriptor::FindValueByNumber(int key) const { - return file()->tables_->FindEnumValueByNumber(this, key); -} - -const MethodDescriptor* -ServiceDescriptor::FindMethodByName(const string& key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); - if (!result.IsNull()) { - return result.method_descriptor; - } else { - return NULL; - } -} - -const Descriptor* -FileDescriptor::FindMessageTypeByName(const string& key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return NULL; - } -} - -const EnumDescriptor* -FileDescriptor::FindEnumTypeByName(const string& key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -FileDescriptor::FindEnumValueByName(const string& key) const { - Symbol result = - tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const ServiceDescriptor* -FileDescriptor::FindServiceByName(const string& key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); - if (!result.IsNull()) { - return result.service_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -FileDescriptor::FindExtensionByName(const string& key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -FileDescriptor::FindExtensionByLowercaseName(const string& key) const { - const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); - if (result == NULL || !result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -FileDescriptor::FindExtensionByCamelcaseName(const string& key) const { - const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); - if (result == NULL || !result->is_extension()) { - return NULL; - } else { - return result; - } -} - -bool Descriptor::IsExtensionNumber(int number) const { - // Linear search should be fine because we don't expect a message to have - // more than a couple extension ranges. - for (int i = 0; i < extension_range_count(); i++) { - if (number >= extension_range(i)->start && - number < extension_range(i)->end) { - return true; - } - } - return false; -} - -// ------------------------------------------------------------------- - -bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { - if (fallback_database_ == NULL) return false; - - if (tables_->known_bad_files_.count(name) > 0) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileByName(name, &file_proto) || - BuildFileFromDatabase(file_proto) == NULL) { - tables_->known_bad_files_.insert(name); - return false; - } - - return true; -} - -bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { - if (fallback_database_ == NULL) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) { - return false; - } - - if (tables_->FindFile(file_proto.name()) != NULL) { - // We've already loaded this file, and it apparently doesn't contain the - // symbol we're looking for. Some DescriptorDatabases return false - // positives. - return false; - } - - if (BuildFileFromDatabase(file_proto) == NULL) { - return false; - } - - return true; -} - -bool DescriptorPool::TryFindExtensionInFallbackDatabase( - const Descriptor* containing_type, int field_number) const { - if (fallback_database_ == NULL) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileContainingExtension( - containing_type->full_name(), field_number, &file_proto)) { - return false; - } - - if (tables_->FindFile(file_proto.name()) != NULL) { - // We've already loaded this file, and it apparently doesn't contain the - // extension we're looking for. Some DescriptorDatabases return false - // positives. - return false; - } - - if (BuildFileFromDatabase(file_proto) == NULL) { - return false; - } - - return true; -} - -// =================================================================== - -string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { - GOOGLE_CHECK(has_default_value()) << "No default value"; - switch (cpp_type()) { - case CPPTYPE_INT32: - return SimpleItoa(default_value_int32()); - break; - case CPPTYPE_INT64: - return SimpleItoa(default_value_int64()); - break; - case CPPTYPE_UINT32: - return SimpleItoa(default_value_uint32()); - break; - case CPPTYPE_UINT64: - return SimpleItoa(default_value_uint64()); - break; - case CPPTYPE_FLOAT: - return SimpleFtoa(default_value_float()); - break; - case CPPTYPE_DOUBLE: - return SimpleDtoa(default_value_double()); - break; - case CPPTYPE_BOOL: - return default_value_bool() ? "true" : "false"; - break; - case CPPTYPE_STRING: - if (quote_string_type) { - return "\"" + CEscape(default_value_string()) + "\""; - } else { - if (type() == TYPE_BYTES) { - return CEscape(default_value_string()); - } else { - return default_value_string(); - } - } - break; - case CPPTYPE_ENUM: - return default_value_enum()->name(); - break; - case CPPTYPE_MESSAGE: - GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; - break; - } - GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; - return ""; -} - -// CopyTo methods ==================================================== - -void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { - proto->set_name(name()); - if (!package().empty()) proto->set_package(package()); - - for (int i = 0; i < dependency_count(); i++) { - proto->add_dependency(dependency(i)->name()); - } - - for (int i = 0; i < message_type_count(); i++) { - message_type(i)->CopyTo(proto->add_message_type()); - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->CopyTo(proto->add_enum_type()); - } - for (int i = 0; i < service_count(); i++) { - service(i)->CopyTo(proto->add_service()); - } - for (int i = 0; i < extension_count(); i++) { - extension(i)->CopyTo(proto->add_extension()); - } - - if (&options() != &FileOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void Descriptor::CopyTo(DescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < field_count(); i++) { - field(i)->CopyTo(proto->add_field()); - } - for (int i = 0; i < nested_type_count(); i++) { - nested_type(i)->CopyTo(proto->add_nested_type()); - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->CopyTo(proto->add_enum_type()); - } - for (int i = 0; i < extension_range_count(); i++) { - DescriptorProto::ExtensionRange* range = proto->add_extension_range(); - range->set_start(extension_range(i)->start); - range->set_end(extension_range(i)->end); - } - for (int i = 0; i < extension_count(); i++) { - extension(i)->CopyTo(proto->add_extension()); - } - - if (&options() != &MessageOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { - proto->set_name(name()); - proto->set_number(number()); - - // Some compilers do not allow static_cast directly between two enum types, - // so we must cast to int first. - proto->set_label(static_cast( - implicit_cast(label()))); - proto->set_type(static_cast( - implicit_cast(type()))); - - if (is_extension()) { - if (!containing_type()->is_unqualified_placeholder_) { - proto->set_extendee("."); - } - proto->mutable_extendee()->append(containing_type()->full_name()); - } - - if (cpp_type() == CPPTYPE_MESSAGE) { - if (message_type()->is_placeholder_) { - // We don't actually know if the type is a message type. It could be - // an enum. - proto->clear_type(); - } - - if (!message_type()->is_unqualified_placeholder_) { - proto->set_type_name("."); - } - proto->mutable_type_name()->append(message_type()->full_name()); - } else if (cpp_type() == CPPTYPE_ENUM) { - if (!enum_type()->is_unqualified_placeholder_) { - proto->set_type_name("."); - } - proto->mutable_type_name()->append(enum_type()->full_name()); - } - - if (has_default_value()) { - proto->set_default_value(DefaultValueAsString(false)); - } - - if (&options() != &FieldOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < value_count(); i++) { - value(i)->CopyTo(proto->add_value()); - } - - if (&options() != &EnumOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { - proto->set_name(name()); - proto->set_number(number()); - - if (&options() != &EnumValueOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < method_count(); i++) { - method(i)->CopyTo(proto->add_method()); - } - - if (&options() != &ServiceOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { - proto->set_name(name()); - - if (!input_type()->is_unqualified_placeholder_) { - proto->set_input_type("."); - } - proto->mutable_input_type()->append(input_type()->full_name()); - - if (!output_type()->is_unqualified_placeholder_) { - proto->set_output_type("."); - } - proto->mutable_output_type()->append(output_type()->full_name()); - - if (&options() != &MethodOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -// DebugString methods =============================================== - -namespace { - -// Used by each of the option formatters. -bool RetrieveOptions(const Message &options, vector *option_entries) { - option_entries->clear(); - const Reflection* reflection = options.GetReflection(); - vector fields; - reflection->ListFields(options, &fields); - for (int i = 0; i < fields.size(); i++) { - // Doesn't make sense to have message type fields here - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - continue; - } - int count = 1; - bool repeated = false; - if (fields[i]->is_repeated()) { - count = reflection->FieldSize(options, fields[i]); - repeated = true; - } - for (int j = 0; j < count; j++) { - string fieldval; - TextFormat::PrintFieldValueToString(options, fields[i], - repeated ? count : -1, &fieldval); - option_entries->push_back(fields[i]->name() + " = " + fieldval); - } - } - return !option_entries->empty(); -} - -// Formats options that all appear together in brackets. Does not include -// brackets. -bool FormatBracketedOptions(const Message &options, string *output) { - vector all_options; - if (RetrieveOptions(options, &all_options)) { - output->append(JoinStrings(all_options, ", ")); - } - return !all_options.empty(); -} - -// Formats options one per line -bool FormatLineOptions(int depth, const Message &options, string *output) { - string prefix(depth * 2, ' '); - vector all_options; - if (RetrieveOptions(options, &all_options)) { - for (int i = 0; i < all_options.size(); i++) { - strings::SubstituteAndAppend(output, "$0option $1;\n", - prefix, all_options[i]); - } - } - return !all_options.empty(); -} - -} // anonymous namespace - -string FileDescriptor::DebugString() const { - string contents = "syntax = \"proto2\";\n\n"; - - for (int i = 0; i < dependency_count(); i++) { - strings::SubstituteAndAppend(&contents, "import \"$0\";\n", - dependency(i)->name()); - } - - if (!package().empty()) { - strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); - } - - if (FormatLineOptions(0, options(), &contents)) { - contents.append("\n"); // add some space if we had options - } - - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->DebugString(0, &contents); - contents.append("\n"); - } - - // Find all the 'group' type extensions; we will not output their nested - // definitions (those will be done with their group field descriptor). - set groups; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(extension(i)->message_type()); - } - } - - for (int i = 0; i < message_type_count(); i++) { - if (groups.count(message_type(i)) == 0) { - strings::SubstituteAndAppend(&contents, "message $0", - message_type(i)->name()); - message_type(i)->DebugString(0, &contents); - contents.append("\n"); - } - } - - for (int i = 0; i < service_count(); i++) { - service(i)->DebugString(&contents); - contents.append("\n"); - } - - const Descriptor* containing_type = NULL; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->containing_type() != containing_type) { - if (i > 0) contents.append("}\n\n"); - containing_type = extension(i)->containing_type(); - strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type->full_name()); - } - extension(i)->DebugString(1, &contents); - } - if (extension_count() > 0) contents.append("}\n\n"); - - return contents; -} - -string Descriptor::DebugString() const { - string contents; - strings::SubstituteAndAppend(&contents, "message $0", name()); - DebugString(0, &contents); - return contents; -} - -void Descriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - contents->append(" {\n"); - - FormatLineOptions(depth, options(), contents); - - // Find all the 'group' types for fields and extensions; we will not output - // their nested definitions (those will be done with their group field - // descriptor). - set groups; - for (int i = 0; i < field_count(); i++) { - if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(field(i)->message_type()); - } - } - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(extension(i)->message_type()); - } - } - - for (int i = 0; i < nested_type_count(); i++) { - if (groups.count(nested_type(i)) == 0) { - strings::SubstituteAndAppend(contents, "$0 message $1", - prefix, nested_type(i)->name()); - nested_type(i)->DebugString(depth, contents); - } - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->DebugString(depth, contents); - } - for (int i = 0; i < field_count(); i++) { - field(i)->DebugString(depth, contents); - } - - for (int i = 0; i < extension_range_count(); i++) { - strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", - prefix, - extension_range(i)->start, - extension_range(i)->end - 1); - } - - // Group extensions by what they extend, so they can be printed out together. - const Descriptor* containing_type = NULL; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->containing_type() != containing_type) { - if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); - containing_type = extension(i)->containing_type(); - strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", - prefix, containing_type->full_name()); - } - extension(i)->DebugString(depth + 1, contents); - } - if (extension_count() > 0) - strings::SubstituteAndAppend(contents, "$0 }\n", prefix); - - strings::SubstituteAndAppend(contents, "$0}\n", prefix); -} - -string FieldDescriptor::DebugString() const { - string contents; - int depth = 0; - if (is_extension()) { - strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type()->full_name()); - depth = 1; - } - DebugString(depth, &contents); - if (is_extension()) { - contents.append("}\n"); - } - return contents; -} - -void FieldDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - string field_type; - switch (type()) { - case TYPE_MESSAGE: - field_type = "." + message_type()->full_name(); - break; - case TYPE_ENUM: - field_type = "." + enum_type()->full_name(); - break; - default: - field_type = kTypeToName[type()]; - } - - strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4", - prefix, - kLabelToName[label()], - field_type, - type() == TYPE_GROUP ? message_type()->name() : - name(), - number()); - - bool bracketed = false; - if (has_default_value()) { - bracketed = true; - strings::SubstituteAndAppend(contents, " [default = $0", - DefaultValueAsString(true)); - } - - string formatted_options; - if (FormatBracketedOptions(options(), &formatted_options)) { - contents->append(bracketed ? ", " : " ["); - bracketed = true; - contents->append(formatted_options); - } - - if (bracketed) { - contents->append("]"); - } - - if (type() == TYPE_GROUP) { - message_type()->DebugString(depth, contents); - } else { - contents->append(";\n"); - } -} - -string EnumDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void EnumDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - strings::SubstituteAndAppend(contents, "$0enum $1 {\n", - prefix, name()); - - FormatLineOptions(depth, options(), contents); - - for (int i = 0; i < value_count(); i++) { - value(i)->DebugString(depth, contents); - } - strings::SubstituteAndAppend(contents, "$0}\n", prefix); -} - -string EnumValueDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void EnumValueDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - strings::SubstituteAndAppend(contents, "$0$1 = $2", - prefix, name(), number()); - - string formatted_options; - if (FormatBracketedOptions(options(), &formatted_options)) { - strings::SubstituteAndAppend(contents, " [$0]", formatted_options); - } - contents->append(";\n"); -} - -string ServiceDescriptor::DebugString() const { - string contents; - DebugString(&contents); - return contents; -} - -void ServiceDescriptor::DebugString(string *contents) const { - strings::SubstituteAndAppend(contents, "service $0 {\n", name()); - - FormatLineOptions(1, options(), contents); - - for (int i = 0; i < method_count(); i++) { - method(i)->DebugString(1, contents); - } - - contents->append("}\n"); -} - -string MethodDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void MethodDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)", - prefix, name(), - input_type()->full_name(), - output_type()->full_name()); - - string formatted_options; - if (FormatLineOptions(depth, options(), &formatted_options)) { - strings::SubstituteAndAppend(contents, " {\n$0$1}\n", - formatted_options, prefix); - } else { - contents->append(";\n"); - } -} -// =================================================================== - -namespace { - -// Represents an options message to interpret. Extension names in the option -// name are respolved relative to name_scope. element_name and orig_opt are -// used only for error reporting (since the parser records locations against -// pointers in the original options, not the mutable copy). The Message must be -// one of the Options messages in descriptor.proto. -struct OptionsToInterpret { - OptionsToInterpret(const string& ns, - const string& el, - const Message* orig_opt, - Message* opt) - : name_scope(ns), - element_name(el), - original_options(orig_opt), - options(opt) { - } - string name_scope; - string element_name; - const Message* original_options; - Message* options; -}; - -} // namespace - -class DescriptorBuilder { - public: - DescriptorBuilder(const DescriptorPool* pool, - DescriptorPool::Tables* tables, - DescriptorPool::ErrorCollector* error_collector); - ~DescriptorBuilder(); - - const FileDescriptor* BuildFile(const FileDescriptorProto& proto); - - private: - friend class OptionInterpreter; - - const DescriptorPool* pool_; - DescriptorPool::Tables* tables_; // for convenience - DescriptorPool::ErrorCollector* error_collector_; - - // As we build descriptors we store copies of the options messages in - // them. We put pointers to those copies in this vector, as we build, so we - // can later (after cross-linking) interpret those options. - vector options_to_interpret_; - - bool had_errors_; - string filename_; - FileDescriptor* file_; - FileDescriptorTables* file_tables_; - - // If LookupSymbol() finds a symbol that is in a file which is not a declared - // dependency of this file, it will fail, but will set - // possible_undeclared_dependency_ to point at that file. This is only used - // by AddNotDefinedError() to report a more useful error message. - // possible_undeclared_dependency_name_ is the name of the symbol that was - // actually found in possible_undeclared_dependency_, which may be a parent - // of the symbol actually looked for. - const FileDescriptor* possible_undeclared_dependency_; - string possible_undeclared_dependency_name_; - - void AddError(const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& error); - - // Adds an error indicating that undefined_symbol was not defined. Must - // only be called after LookupSymbol() fails. - void AddNotDefinedError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& undefined_symbol); - - // Silly helper which determines if the given file is in the given package. - // I.e., either file->package() == package_name or file->package() is a - // nested package within package_name. - bool IsInPackage(const FileDescriptor* file, const string& package_name); - - // Like tables_->FindSymbol(), but additionally: - // - Search the pool's underlay if not found in tables_. - // - Insure that the resulting Symbol is from one of the file's declared - // dependencies. - Symbol FindSymbol(const string& name); - - // Like FindSymbol() but does not require that the symbol is in one of the - // file's declared dependencies. - Symbol FindSymbolNotEnforcingDeps(const string& name); - - // Like FindSymbol(), but looks up the name relative to some other symbol - // name. This first searches siblings of relative_to, then siblings of its - // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes - // the following calls, returning the first non-null result: - // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), - // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called - // on the DescriptorPool, this will generate a placeholder type if - // the name is not found (unless the name itself is malformed). The - // placeholder_type parameter indicates what kind of placeholder should be - // constructed in this case. The resolve_mode parameter determines whether - // any symbol is returned, or only symbols that are types. Note, however, - // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, - // if it believes that's all it could refer to. The caller should always - // check that it receives the type of symbol it was expecting. - enum PlaceholderType { - PLACEHOLDER_MESSAGE, - PLACEHOLDER_ENUM, - PLACEHOLDER_EXTENDABLE_MESSAGE - }; - enum ResolveMode { - LOOKUP_ALL, LOOKUP_TYPES - }; - Symbol LookupSymbol(const string& name, const string& relative_to, - PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, - ResolveMode resolve_mode = LOOKUP_ALL); - - // Like LookupSymbol() but will not return a placeholder even if - // AllowUnknownDependencies() has been used. - Symbol LookupSymbolNoPlaceholder(const string& name, - const string& relative_to, - ResolveMode resolve_mode = LOOKUP_ALL); - - // Creates a placeholder type suitable for return from LookupSymbol(). May - // return kNullSymbol if the name is not a valid type name. - Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); - - // Creates a placeholder file. Never returns NULL. This is used when an - // import is not found and AllowUnknownDependencies() is enabled. - const FileDescriptor* NewPlaceholderFile(const string& name); - - // Calls tables_->AddSymbol() and records an error if it fails. Returns - // true if successful or false if failed, though most callers can ignore - // the return value since an error has already been recorded. - bool AddSymbol(const string& full_name, - const void* parent, const string& name, - const Message& proto, Symbol symbol); - - // Like AddSymbol(), but succeeds if the symbol is already defined as long - // as the existing definition is also a package (because it's OK to define - // the same package in two different files). Also adds all parents of the - // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add - // "foo.bar" and "foo" to the table). - void AddPackage(const string& name, const Message& proto, - const FileDescriptor* file); - - // Checks that the symbol name contains only alphanumeric characters and - // underscores. Records an error otherwise. - void ValidateSymbolName(const string& name, const string& full_name, - const Message& proto); - - // Like ValidateSymbolName(), but the name is allowed to contain periods and - // an error is indicated by returning false (not recording the error). - bool ValidateQualifiedName(const string& name); - - // Used by BUILD_ARRAY macro (below) to avoid having to have the type - // specified as a macro parameter. - template - inline void AllocateArray(int size, Type** output) { - *output = tables_->AllocateArray(size); - } - - // Allocates a copy of orig_options in tables_ and stores it in the - // descriptor. Remembers its uninterpreted options, to be interpreted - // later. DescriptorT must be one of the Descriptor messages from - // descriptor.proto. - template void AllocateOptions( - const typename DescriptorT::OptionsType& orig_options, - DescriptorT* descriptor); - // Specialization for FileOptions. - void AllocateOptions(const FileOptions& orig_options, - FileDescriptor* descriptor); - - // Implementation for AllocateOptions(). Don't call this directly. - template void AllocateOptionsImpl( - const string& name_scope, - const string& element_name, - const typename DescriptorT::OptionsType& orig_options, - DescriptorT* descriptor); - - // These methods all have the same signature for the sake of the BUILD_ARRAY - // macro, below. - void BuildMessage(const DescriptorProto& proto, - const Descriptor* parent, - Descriptor* result); - void BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result, - bool is_extension); - void BuildField(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result) { - BuildFieldOrExtension(proto, parent, result, false); - } - void BuildExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result) { - BuildFieldOrExtension(proto, parent, result, true); - } - void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, - const Descriptor* parent, - Descriptor::ExtensionRange* result); - void BuildEnum(const EnumDescriptorProto& proto, - const Descriptor* parent, - EnumDescriptor* result); - void BuildEnumValue(const EnumValueDescriptorProto& proto, - const EnumDescriptor* parent, - EnumValueDescriptor* result); - void BuildService(const ServiceDescriptorProto& proto, - const void* dummy, - ServiceDescriptor* result); - void BuildMethod(const MethodDescriptorProto& proto, - const ServiceDescriptor* parent, - MethodDescriptor* result); - - // Must be run only after building. - // - // NOTE: Options will not be available during cross-linking, as they - // have not yet been interpreted. Defer any handling of options to the - // Validate*Options methods. - void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); - void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); - void CrossLinkField(FieldDescriptor* field, - const FieldDescriptorProto& proto); - void CrossLinkEnum(EnumDescriptor* enum_type, - const EnumDescriptorProto& proto); - void CrossLinkEnumValue(EnumValueDescriptor* enum_value, - const EnumValueDescriptorProto& proto); - void CrossLinkService(ServiceDescriptor* service, - const ServiceDescriptorProto& proto); - void CrossLinkMethod(MethodDescriptor* method, - const MethodDescriptorProto& proto); - - // Must be run only after cross-linking. - void InterpretOptions(); - - // A helper class for interpreting options. - class OptionInterpreter { - public: - // Creates an interpreter that operates in the context of the pool of the - // specified builder, which must not be NULL. We don't take ownership of the - // builder. - explicit OptionInterpreter(DescriptorBuilder* builder); - - ~OptionInterpreter(); - - // Interprets the uninterpreted options in the specified Options message. - // On error, calls AddError() on the underlying builder and returns false. - // Otherwise returns true. - bool InterpretOptions(OptionsToInterpret* options_to_interpret); - - private: - // Interprets uninterpreted_option_ on the specified message, which - // must be the mutable copy of the original options message to which - // uninterpreted_option_ belongs. - bool InterpretSingleOption(Message* options); - - // Adds the uninterpreted_option to the given options message verbatim. - // Used when AllowUnknownDependencies() is in effect and we can't find - // the option's definition. - void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, - Message* options); - - // A recursive helper function that drills into the intermediate fields - // in unknown_fields to check if field innermost_field is set on the - // innermost message. Returns false and sets an error if so. - bool ExamineIfOptionIsSet( - vector::const_iterator intermediate_fields_iter, - vector::const_iterator intermediate_fields_end, - const FieldDescriptor* innermost_field, const string& debug_msg_name, - const UnknownFieldSet& unknown_fields); - - // Validates the value for the option field of the currently interpreted - // option and then sets it on the unknown_field. - bool SetOptionValue(const FieldDescriptor* option_field, - UnknownFieldSet* unknown_fields); - - // Convenience functions to set an int field the right way, depending on - // its wire type (a single int CppType can represent multiple wire types). - void SetInt32(int number, int32 value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetInt64(int number, int64 value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - - // A helper function that adds an error at the specified location of the - // option we're currently interpreting, and returns false. - bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, - const string& msg) { - builder_->AddError(options_to_interpret_->element_name, - *uninterpreted_option_, location, msg); - return false; - } - - // A helper function that adds an error at the location of the option name - // and returns false. - bool AddNameError(const string& msg) { - return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); - } - - // A helper function that adds an error at the location of the option name - // and returns false. - bool AddValueError(const string& msg) { - return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); - } - - // We interpret against this builder's pool. Is never NULL. We don't own - // this pointer. - DescriptorBuilder* builder_; - - // The options we're currently interpreting, or NULL if we're not in a call - // to InterpretOptions. - const OptionsToInterpret* options_to_interpret_; - - // The option we're currently interpreting within options_to_interpret_, or - // NULL if we're not in a call to InterpretOptions(). This points to a - // submessage of the original option, not the mutable copy. Therefore we - // can use it to find locations recorded by the parser. - const UninterpretedOption* uninterpreted_option_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); - }; - - // Work-around for broken compilers: According to the C++ standard, - // OptionInterpreter should have access to the private members of any class - // which has declared DescriptorBuilder as a friend. Unfortunately some old - // versions of GCC and other compilers do not implement this correctly. So, - // we have to have these intermediate methods to provide access. We also - // redundantly declare OptionInterpreter a friend just to make things extra - // clear for these bad compilers. - friend class OptionInterpreter; - static inline bool get_allow_unknown(const DescriptorPool* pool) { - return pool->allow_unknown_; - } - static inline bool get_is_placeholder(const Descriptor* descriptor) { - return descriptor->is_placeholder_; - } - - // Must be run only after options have been interpreted. - // - // NOTE: Validation code must only reference the options in the mutable - // descriptors, which are the ones that have been interpreted. The const - // proto references are passed in only so they can be provided to calls to - // AddError(). Do not look at their options, which have not been interpreted. - void ValidateFileOptions(FileDescriptor* file, - const FileDescriptorProto& proto); - void ValidateMessageOptions(Descriptor* message, - const DescriptorProto& proto); - void ValidateFieldOptions(FieldDescriptor* field, - const FieldDescriptorProto& proto); - void ValidateEnumOptions(EnumDescriptor* enm, - const EnumDescriptorProto& proto); - void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, - const EnumValueDescriptorProto& proto); - void ValidateServiceOptions(ServiceDescriptor* service, - const ServiceDescriptorProto& proto); - void ValidateMethodOptions(MethodDescriptor* method, - const MethodDescriptorProto& proto); - - void ValidateMapKey(FieldDescriptor* field, - const FieldDescriptorProto& proto); -}; - -const FileDescriptor* DescriptorPool::BuildFile( - const FileDescriptorProto& proto) { - GOOGLE_CHECK(fallback_database_ == NULL) - << "Cannot call BuildFile on a DescriptorPool that uses a " - "DescriptorDatabase. You must instead find a way to get your file " - "into the underlying database."; - GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. - return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); -} - -const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( - const FileDescriptorProto& proto, - ErrorCollector* error_collector) { - GOOGLE_CHECK(fallback_database_ == NULL) - << "Cannot call BuildFile on a DescriptorPool that uses a " - "DescriptorDatabase. You must instead find a way to get your file " - "into the underlying database."; - GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. - return DescriptorBuilder(this, tables_.get(), - error_collector).BuildFile(proto); -} - -const FileDescriptor* DescriptorPool::BuildFileFromDatabase( - const FileDescriptorProto& proto) const { - mutex_->AssertHeld(); - return DescriptorBuilder(this, tables_.get(), - default_error_collector_).BuildFile(proto); -} - -DescriptorBuilder::DescriptorBuilder( - const DescriptorPool* pool, - DescriptorPool::Tables* tables, - DescriptorPool::ErrorCollector* error_collector) - : pool_(pool), - tables_(tables), - error_collector_(error_collector), - had_errors_(false), - possible_undeclared_dependency_(NULL) {} - -DescriptorBuilder::~DescriptorBuilder() {} - -void DescriptorBuilder::AddError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& error) { - if (error_collector_ == NULL) { - if (!had_errors_) { - GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ - << "\":"; - } - GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; - } else { - error_collector_->AddError(filename_, element_name, - &descriptor, location, error); - } - had_errors_ = true; -} - -void DescriptorBuilder::AddNotDefinedError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& undefined_symbol) { - if (possible_undeclared_dependency_ == NULL) { - AddError(element_name, descriptor, location, - "\"" + undefined_symbol + "\" is not defined."); - } else { - AddError(element_name, descriptor, location, - "\"" + possible_undeclared_dependency_name_ + - "\" seems to be defined in \"" + - possible_undeclared_dependency_->name() + "\", which is not " - "imported by \"" + filename_ + "\". To use it here, please " - "add the necessary import."); - } -} - -bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, - const string& package_name) { - return HasPrefixString(file->package(), package_name) && - (file->package().size() == package_name.size() || - file->package()[package_name.size()] == '.'); -} - -Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { - Symbol result; - - // We need to search our pool and all its underlays. - const DescriptorPool* pool = pool_; - while (true) { - // If we are looking at an underlay, we must lock its mutex_, since we are - // accessing the underlay's tables_ dircetly. - MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); - - // Note that we don't have to check fallback_database_ here because the - // symbol has to be in one of its file's direct dependencies, and we have - // already loaded those by the time we get here. - result = pool->tables_->FindSymbol(name); - if (!result.IsNull()) break; - if (pool->underlay_ == NULL) return kNullSymbol; - pool = pool->underlay_; - } - - return result; -} - -Symbol DescriptorBuilder::FindSymbol(const string& name) { - Symbol result = FindSymbolNotEnforcingDeps(name); - - if (!pool_->enforce_dependencies_) { - // Hack for CompilerUpgrader. - return result; - } - - // Only find symbols which were defined in this file or one of its - // dependencies. - const FileDescriptor* file = result.GetFile(); - if (file == file_) return result; - for (int i = 0; i < file_->dependency_count(); i++) { - if (file == file_->dependency(i)) return result; - } - - if (result.type == Symbol::PACKAGE) { - // Arg, this is overcomplicated. The symbol is a package name. It could - // be that the package was defined in multiple files. result.GetFile() - // returns the first file we saw that used this package. We've determined - // that that file is not a direct dependency of the file we are currently - // building, but it could be that some other file which *is* a direct - // dependency also defines the same package. We can't really rule out this - // symbol unless none of the dependencies define it. - if (IsInPackage(file_, name)) return result; - for (int i = 0; i < file_->dependency_count(); i++) { - // Note: A dependency may be NULL if it was not found or had errors. - if (file_->dependency(i) != NULL && - IsInPackage(file_->dependency(i), name)) { - return result; - } - } - } - - possible_undeclared_dependency_ = file; - possible_undeclared_dependency_name_ = name; - return kNullSymbol; -} - -Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( - const string& name, const string& relative_to, ResolveMode resolve_mode) { - possible_undeclared_dependency_ = NULL; - - if (name.size() > 0 && name[0] == '.') { - // Fully-qualified name. - return FindSymbol(name.substr(1)); - } - - // If name is something like "Foo.Bar.baz", and symbols named "Foo" are - // defined in multiple parent scopes, we only want to find "Bar.baz" in the - // innermost one. E.g., the following should produce an error: - // message Bar { message Baz {} } - // message Foo { - // message Bar { - // } - // optional Bar.Baz baz = 1; - // } - // So, we look for just "Foo" first, then look for "Bar.baz" within it if - // found. - int name_dot_pos = name.find_first_of('.'); - string first_part_of_name; - if (name_dot_pos == string::npos) { - first_part_of_name = name; - } else { - first_part_of_name = name.substr(0, name_dot_pos); - } - - string scope_to_try(relative_to); - - while (true) { - // Chop off the last component of the scope. - string::size_type dot_pos = scope_to_try.find_last_of('.'); - if (dot_pos == string::npos) { - return FindSymbol(name); - } else { - scope_to_try.erase(dot_pos); - } - - // Append ".first_part_of_name" and try to find. - string::size_type old_size = scope_to_try.size(); - scope_to_try.append(1, '.'); - scope_to_try.append(first_part_of_name); - Symbol result = FindSymbol(scope_to_try); - if (!result.IsNull()) { - if (first_part_of_name.size() < name.size()) { - // name is a compound symbol, of which we only found the first part. - // Now try to look up the rest of it. - if (result.IsAggregate()) { - scope_to_try.append(name, first_part_of_name.size(), - name.size() - first_part_of_name.size()); - return FindSymbol(scope_to_try); - } else { - // We found a symbol but it's not an aggregate. Continue the loop. - } - } else { - if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { - // We found a symbol but it's not a type. Continue the loop. - } else { - return result; - } - } - } - - // Not found. Remove the name so we can try again. - scope_to_try.erase(old_size); - } -} - -Symbol DescriptorBuilder::LookupSymbol( - const string& name, const string& relative_to, - PlaceholderType placeholder_type, ResolveMode resolve_mode) { - Symbol result = LookupSymbolNoPlaceholder( - name, relative_to, resolve_mode); - if (result.IsNull() && pool_->allow_unknown_) { - // Not found, but AllowUnknownDependencies() is enabled. Return a - // placeholder instead. - result = NewPlaceholder(name, placeholder_type); - } - return result; -} - -Symbol DescriptorBuilder::NewPlaceholder(const string& name, - PlaceholderType placeholder_type) { - // Compute names. - const string* placeholder_full_name; - const string* placeholder_name; - const string* placeholder_package; - - if (!ValidateQualifiedName(name)) return kNullSymbol; - if (name[0] == '.') { - // Fully-qualified. - placeholder_full_name = tables_->AllocateString(name.substr(1)); - } else { - placeholder_full_name = tables_->AllocateString(name); - } - - string::size_type dotpos = placeholder_full_name->find_last_of('.'); - if (dotpos != string::npos) { - placeholder_package = tables_->AllocateString( - placeholder_full_name->substr(0, dotpos)); - placeholder_name = tables_->AllocateString( - placeholder_full_name->substr(dotpos + 1)); - } else { - placeholder_package = &kEmptyString; - placeholder_name = placeholder_full_name; - } - - // Create the placeholders. - FileDescriptor* placeholder_file = tables_->Allocate(); - memset(placeholder_file, 0, sizeof(*placeholder_file)); - - placeholder_file->name_ = - tables_->AllocateString(*placeholder_full_name + ".placeholder.proto"); - placeholder_file->package_ = placeholder_package; - placeholder_file->pool_ = pool_; - placeholder_file->options_ = &FileOptions::default_instance(); - placeholder_file->tables_ = &FileDescriptorTables::kEmpty; - // All other fields are zero or NULL. - - if (placeholder_type == PLACEHOLDER_ENUM) { - placeholder_file->enum_type_count_ = 1; - placeholder_file->enum_types_ = - tables_->AllocateArray(1); - - EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; - memset(placeholder_enum, 0, sizeof(*placeholder_enum)); - - placeholder_enum->full_name_ = placeholder_full_name; - placeholder_enum->name_ = placeholder_name; - placeholder_enum->file_ = placeholder_file; - placeholder_enum->options_ = &EnumOptions::default_instance(); - placeholder_enum->is_placeholder_ = true; - placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); - - // Enums must have at least one value. - placeholder_enum->value_count_ = 1; - placeholder_enum->values_ = tables_->AllocateArray(1); - - EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; - memset(placeholder_value, 0, sizeof(*placeholder_value)); - - placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); - // Note that enum value names are siblings of their type, not children. - placeholder_value->full_name_ = - placeholder_package->empty() ? placeholder_value->name_ : - tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE"); - - placeholder_value->number_ = 0; - placeholder_value->type_ = placeholder_enum; - placeholder_value->options_ = &EnumValueOptions::default_instance(); - - return Symbol(placeholder_enum); - } else { - placeholder_file->message_type_count_ = 1; - placeholder_file->message_types_ = - tables_->AllocateArray(1); - - Descriptor* placeholder_message = &placeholder_file->message_types_[0]; - memset(placeholder_message, 0, sizeof(*placeholder_message)); - - placeholder_message->full_name_ = placeholder_full_name; - placeholder_message->name_ = placeholder_name; - placeholder_message->file_ = placeholder_file; - placeholder_message->options_ = &MessageOptions::default_instance(); - placeholder_message->is_placeholder_ = true; - placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); - - if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { - placeholder_message->extension_range_count_ = 1; - placeholder_message->extension_ranges_ = - tables_->AllocateArray(1); - placeholder_message->extension_ranges_->start = 1; - // kMaxNumber + 1 because ExtensionRange::end is exclusive. - placeholder_message->extension_ranges_->end = - FieldDescriptor::kMaxNumber + 1; - } - - return Symbol(placeholder_message); - } -} - -const FileDescriptor* DescriptorBuilder::NewPlaceholderFile( - const string& name) { - FileDescriptor* placeholder = tables_->Allocate(); - memset(placeholder, 0, sizeof(*placeholder)); - - placeholder->name_ = tables_->AllocateString(name); - placeholder->package_ = &kEmptyString; - placeholder->pool_ = pool_; - placeholder->options_ = &FileOptions::default_instance(); - placeholder->tables_ = &FileDescriptorTables::kEmpty; - // All other fields are zero or NULL. - - return placeholder; -} - -bool DescriptorBuilder::AddSymbol( - const string& full_name, const void* parent, const string& name, - const Message& proto, Symbol symbol) { - // If the caller passed NULL for the parent, the symbol is at file scope. - // Use its file as the parent instead. - if (parent == NULL) parent = file_; - - if (tables_->AddSymbol(full_name, symbol)) { - if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { - GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " - "symbols_by_name_, but was defined in symbols_by_parent_; " - "this shouldn't be possible."; - return false; - } - return true; - } else { - const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); - if (other_file == file_) { - string::size_type dot_pos = full_name.find_last_of('.'); - if (dot_pos == string::npos) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name + "\" is already defined."); - } else { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name.substr(dot_pos + 1) + - "\" is already defined in \"" + - full_name.substr(0, dot_pos) + "\"."); - } - } else { - // Symbol seems to have been defined in a different file. - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name + "\" is already defined in file \"" + - other_file->name() + "\"."); - } - return false; - } -} - -void DescriptorBuilder::AddPackage( - const string& name, const Message& proto, const FileDescriptor* file) { - if (tables_->AddSymbol(name, Symbol(file))) { - // Success. Also add parent package, if any. - string::size_type dot_pos = name.find_last_of('.'); - if (dot_pos == string::npos) { - // No parents. - ValidateSymbolName(name, name, proto); - } else { - // Has parent. - string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); - AddPackage(*parent_name, proto, file); - ValidateSymbolName(name.substr(dot_pos + 1), name, proto); - } - } else { - Symbol existing_symbol = tables_->FindSymbol(name); - // It's OK to redefine a package. - if (existing_symbol.type != Symbol::PACKAGE) { - // Symbol seems to have been defined in a different file. - AddError(name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + name + "\" is already defined (as something other than " - "a package) in file \"" + existing_symbol.GetFile()->name() + - "\"."); - } - } -} - -void DescriptorBuilder::ValidateSymbolName( - const string& name, const string& full_name, const Message& proto) { - if (name.empty()) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "Missing name."); - } else { - for (int i = 0; i < name.size(); i++) { - // I don't trust isalnum() due to locales. :( - if ((name[i] < 'a' || 'z' < name[i]) && - (name[i] < 'A' || 'Z' < name[i]) && - (name[i] < '0' || '9' < name[i]) && - (name[i] != '_')) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + name + "\" is not a valid identifier."); - } - } - } -} - -bool DescriptorBuilder::ValidateQualifiedName(const string& name) { - bool last_was_period = false; - - for (int i = 0; i < name.size(); i++) { - // I don't trust isalnum() due to locales. :( - if (('a' <= name[i] && name[i] <= 'z') || - ('A' <= name[i] && name[i] <= 'Z') || - ('0' <= name[i] && name[i] <= '9') || - (name[i] == '_')) { - last_was_period = false; - } else if (name[i] == '.') { - if (last_was_period) return false; - last_was_period = true; - } else { - return false; - } - } - - return !name.empty() && !last_was_period; -} - -// ------------------------------------------------------------------- - -// This generic implementation is good for all descriptors except -// FileDescriptor. -template void DescriptorBuilder::AllocateOptions( - const typename DescriptorT::OptionsType& orig_options, - DescriptorT* descriptor) { - AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), - orig_options, descriptor); -} - -// We specialize for FileDescriptor. -void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, - FileDescriptor* descriptor) { - // We add the dummy token so that LookupSymbol does the right thing. - AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), - orig_options, descriptor); -} - -template void DescriptorBuilder::AllocateOptionsImpl( - const string& name_scope, - const string& element_name, - const typename DescriptorT::OptionsType& orig_options, - DescriptorT* descriptor) { - // We need to use a dummy pointer to work around a bug in older versions of - // GCC. Otherwise, the following two lines could be replaced with: - // typename DescriptorT::OptionsType* options = - // tables_->AllocateMessage(); - typename DescriptorT::OptionsType* const dummy = NULL; - typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); - options->CopyFrom(orig_options); - descriptor->options_ = options; - - // Don't add to options_to_interpret_ unless there were uninterpreted - // options. This not only avoids unnecessary work, but prevents a - // bootstrapping problem when building descriptors for descriptor.proto. - // descriptor.proto does not contain any uninterpreted options, but - // attempting to interpret options anyway will cause - // OptionsType::GetDescriptor() to be called which may then deadlock since - // we're still trying to build it. - if (options->uninterpreted_option_size() > 0) { - options_to_interpret_.push_back( - OptionsToInterpret(name_scope, element_name, &orig_options, options)); - } -} - - -// A common pattern: We want to convert a repeated field in the descriptor -// to an array of values, calling some method to build each value. -#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ - OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ - AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ - for (int i = 0; i < INPUT.NAME##_size(); i++) { \ - METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ - } - -const FileDescriptor* DescriptorBuilder::BuildFile( - const FileDescriptorProto& proto) { - filename_ = proto.name(); - - // Check if the file already exists and is identical to the one being built. - // Note: This only works if the input is canonical -- that is, it - // fully-qualifies all type names, has no UninterpretedOptions, etc. - // This is fine, because this idempotency "feature" really only exists to - // accomodate one hack in the proto1->proto2 migration layer. - const FileDescriptor* existing_file = tables_->FindFile(filename_); - if (existing_file != NULL) { - // File already in pool. Compare the existing one to the input. - FileDescriptorProto existing_proto; - existing_file->CopyTo(&existing_proto); - if (existing_proto.SerializeAsString() == proto.SerializeAsString()) { - // They're identical. Return the existing descriptor. - return existing_file; - } - - // Not a match. The error will be detected and handled later. - } - - // Check to see if this file is already on the pending files list. - // TODO(kenton): Allow recursive imports? It may not work with some - // (most?) programming languages. E.g., in C++, a forward declaration - // of a type is not sufficient to allow it to be used even in a - // generated header file due to inlining. This could perhaps be - // worked around using tricks involving inserting #include statements - // mid-file, but that's pretty ugly, and I'm pretty sure there are - // some languages out there that do not allow recursive dependencies - // at all. - for (int i = 0; i < tables_->pending_files_.size(); i++) { - if (tables_->pending_files_[i] == proto.name()) { - string error_message("File recursively imports itself: "); - for (; i < tables_->pending_files_.size(); i++) { - error_message.append(tables_->pending_files_[i]); - error_message.append(" -> "); - } - error_message.append(proto.name()); - - AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, - error_message); - return NULL; - } - } - - // If we have a fallback_database_, attempt to load all dependencies now, - // before checkpointing tables_. This avoids confusion with recursive - // checkpoints. - if (pool_->fallback_database_ != NULL) { - tables_->pending_files_.push_back(proto.name()); - for (int i = 0; i < proto.dependency_size(); i++) { - if (tables_->FindFile(proto.dependency(i)) == NULL && - (pool_->underlay_ == NULL || - pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { - // We don't care what this returns since we'll find out below anyway. - pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); - } - } - tables_->pending_files_.pop_back(); - } - - // Checkpoint the tables so that we can roll back if something goes wrong. - tables_->Checkpoint(); - - FileDescriptor* result = tables_->Allocate(); - file_ = result; - - file_tables_ = tables_->AllocateFileTables(); - file_->tables_ = file_tables_; - - if (!proto.has_name()) { - AddError("", proto, DescriptorPool::ErrorCollector::OTHER, - "Missing field: FileDescriptorProto.name."); - } - - result->name_ = tables_->AllocateString(proto.name()); - if (proto.has_package()) { - result->package_ = tables_->AllocateString(proto.package()); - } else { - // We cannot rely on proto.package() returning a valid string if - // proto.has_package() is false, because we might be running at static - // initialization time, in which case default values have not yet been - // initialized. - result->package_ = tables_->AllocateString(""); - } - result->pool_ = pool_; - - // Add to tables. - if (!tables_->AddFile(result)) { - AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, - "A file with this name is already in the pool."); - // Bail out early so that if this is actually the exact same file, we - // don't end up reporting that every single symbol is already defined. - tables_->Rollback(); - return NULL; - } - if (!result->package().empty()) { - AddPackage(result->package(), proto, result); - } - - // Make sure all dependencies are loaded. - set seen_dependencies; - result->dependency_count_ = proto.dependency_size(); - result->dependencies_ = - tables_->AllocateArray(proto.dependency_size()); - for (int i = 0; i < proto.dependency_size(); i++) { - if (!seen_dependencies.insert(proto.dependency(i)).second) { - AddError(proto.name(), proto, - DescriptorPool::ErrorCollector::OTHER, - "Import \"" + proto.dependency(i) + "\" was listed twice."); - } - - const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); - if (dependency == NULL && pool_->underlay_ != NULL) { - dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); - } - - if (dependency == NULL) { - if (pool_->allow_unknown_) { - dependency = NewPlaceholderFile(proto.dependency(i)); - } else { - string message; - if (pool_->fallback_database_ == NULL) { - message = "Import \"" + proto.dependency(i) + - "\" has not been loaded."; - } else { - message = "Import \"" + proto.dependency(i) + - "\" was not found or had errors."; - } - AddError(proto.name(), proto, - DescriptorPool::ErrorCollector::OTHER, - message); - } - } - - result->dependencies_[i] = dependency; - } - - // Convert children. - BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); - BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); - BUILD_ARRAY(proto, result, service , BuildService , NULL); - BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - // Note that the following steps must occur in exactly the specified order. - - // Cross-link. - CrossLinkFile(result, proto); - - // Interpret any remaining uninterpreted options gathered into - // options_to_interpret_ during descriptor building. Cross-linking has made - // extension options known, so all interpretations should now succeed. - if (!had_errors_) { - OptionInterpreter option_interpreter(this); - for (vector::iterator iter = - options_to_interpret_.begin(); - iter != options_to_interpret_.end(); ++iter) { - option_interpreter.InterpretOptions(&(*iter)); - } - options_to_interpret_.clear(); - } - - // Validate options. - if (!had_errors_) { - ValidateFileOptions(result, proto); - } - - if (had_errors_) { - tables_->Rollback(); - return NULL; - } else { - tables_->Checkpoint(); - return result; - } -} - -void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, - const Descriptor* parent, - Descriptor* result) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->containing_type_ = parent; - result->is_placeholder_ = false; - result->is_unqualified_placeholder_ = false; - - BUILD_ARRAY(proto, result, field , BuildField , result); - BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); - BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); - BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); - BUILD_ARRAY(proto, result, extension , BuildExtension , result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); - - // Check that no fields have numbers in extension ranges. - for (int i = 0; i < result->field_count(); i++) { - const FieldDescriptor* field = result->field(i); - for (int j = 0; j < result->extension_range_count(); j++) { - const Descriptor::ExtensionRange* range = result->extension_range(j); - if (range->start <= field->number() && field->number() < range->end) { - AddError(field->full_name(), proto.extension_range(j), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute( - "Extension range $0 to $1 includes field \"$2\" ($3).", - range->start, range->end - 1, - field->name(), field->number())); - } - } - } - - // Check that extension ranges don't overlap. - for (int i = 0; i < result->extension_range_count(); i++) { - const Descriptor::ExtensionRange* range1 = result->extension_range(i); - for (int j = i + 1; j < result->extension_range_count(); j++) { - const Descriptor::ExtensionRange* range2 = result->extension_range(j); - if (range1->end > range2->start && range2->end > range1->start) { - AddError(result->full_name(), proto.extension_range(j), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension range $0 to $1 overlaps with " - "already-defined range $2 to $3.", - range2->start, range2->end - 1, - range1->start, range1->end - 1)); - } - } - } -} - -void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result, - bool is_extension) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->number_ = proto.number(); - result->is_extension_ = is_extension; - - // If .proto files follow the style guide then the name should already be - // lower-cased. If that's the case we can just reuse the string we already - // allocated rather than allocate a new one. - string lowercase_name(proto.name()); - LowerString(&lowercase_name); - if (lowercase_name == proto.name()) { - result->lowercase_name_ = result->name_; - } else { - result->lowercase_name_ = tables_->AllocateString(lowercase_name); - } - - // Don't bother with the above optimization for camel-case names since - // .proto files that follow the guide shouldn't be using names in this - // format, so the optimization wouldn't help much. - result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name())); - - // Some compilers do not allow static_cast directly between two enum types, - // so we must cast to int first. - result->type_ = static_cast( - implicit_cast(proto.type())); - result->label_ = static_cast( - implicit_cast(proto.label())); - - // Some of these may be filled in when cross-linking. - result->containing_type_ = NULL; - result->extension_scope_ = NULL; - result->experimental_map_key_ = NULL; - result->message_type_ = NULL; - result->enum_type_ = NULL; - - result->has_default_value_ = proto.has_default_value(); - if (proto.has_default_value() && result->is_repeated()) { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Repeated fields can't have default values."); - } - - if (proto.has_type()) { - if (proto.has_default_value()) { - char* end_pos = NULL; - switch (result->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = - strtol(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = - strto64(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = - strtoul(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = - strtou64(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_FLOAT: - if (proto.default_value() == "inf") { - result->default_value_float_ = numeric_limits::infinity(); - } else if (proto.default_value() == "-inf") { - result->default_value_float_ = -numeric_limits::infinity(); - } else if (proto.default_value() == "nan") { - result->default_value_float_ = numeric_limits::quiet_NaN(); - } else { - result->default_value_float_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); - } - break; - case FieldDescriptor::CPPTYPE_DOUBLE: - if (proto.default_value() == "inf") { - result->default_value_double_ = numeric_limits::infinity(); - } else if (proto.default_value() == "-inf") { - result->default_value_double_ = -numeric_limits::infinity(); - } else if (proto.default_value() == "nan") { - result->default_value_double_ = numeric_limits::quiet_NaN(); - } else { - result->default_value_double_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); - } - break; - case FieldDescriptor::CPPTYPE_BOOL: - if (proto.default_value() == "true") { - result->default_value_bool_ = true; - } else if (proto.default_value() == "false") { - result->default_value_bool_ = false; - } else { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Boolean default must be true or false."); - } - break; - case FieldDescriptor::CPPTYPE_ENUM: - // This will be filled in when cross-linking. - result->default_value_enum_ = NULL; - break; - case FieldDescriptor::CPPTYPE_STRING: - if (result->type() == FieldDescriptor::TYPE_BYTES) { - result->default_value_string_ = tables_->AllocateString( - UnescapeCEscapeString(proto.default_value())); - } else { - result->default_value_string_ = - tables_->AllocateString(proto.default_value()); - } - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Messages can't have default values."); - result->has_default_value_ = false; - break; - } - - if (end_pos != NULL) { - // end_pos is only set non-NULL by the parsers for numeric types, above. - // This checks that the default was non-empty and had no extra junk - // after the end of the number. - if (proto.default_value().empty() || *end_pos != '\0') { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Couldn't parse default value."); - } - } - } else { - // No explicit default value - switch (result->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = 0; - break; - case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = 0; - break; - case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = 0; - break; - case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = 0; - break; - case FieldDescriptor::CPPTYPE_FLOAT: - result->default_value_float_ = 0.0f; - break; - case FieldDescriptor::CPPTYPE_DOUBLE: - result->default_value_double_ = 0.0; - break; - case FieldDescriptor::CPPTYPE_BOOL: - result->default_value_bool_ = false; - break; - case FieldDescriptor::CPPTYPE_ENUM: - // This will be filled in when cross-linking. - result->default_value_enum_ = NULL; - break; - case FieldDescriptor::CPPTYPE_STRING: - result->default_value_string_ = &kEmptyString; - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - break; - } - } - } - - if (result->number() <= 0) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - "Field numbers must be positive integers."); - } else if (result->number() > FieldDescriptor::kMaxNumber) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Field numbers cannot be greater than $0.", - FieldDescriptor::kMaxNumber)); - } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && - result->number() <= FieldDescriptor::kLastReservedNumber) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute( - "Field numbers $0 through $1 are reserved for the protocol " - "buffer library implementation.", - FieldDescriptor::kFirstReservedNumber, - FieldDescriptor::kLastReservedNumber)); - } - - if (is_extension) { - if (!proto.has_extendee()) { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "FieldDescriptorProto.extendee not set for extension field."); - } - - result->extension_scope_ = parent; - } else { - if (proto.has_extendee()) { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "FieldDescriptorProto.extendee set for non-extension field."); - } - - result->containing_type_ = parent; - } - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildExtensionRange( - const DescriptorProto::ExtensionRange& proto, - const Descriptor* parent, - Descriptor::ExtensionRange* result) { - result->start = proto.start(); - result->end = proto.end(); - if (result->start <= 0) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - "Extension numbers must be positive integers."); - } - - if (result->end > FieldDescriptor::kMaxNumber + 1) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension numbers cannot be greater than $0.", - FieldDescriptor::kMaxNumber)); - } - - if (result->start >= result->end) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - "Extension range end number must be greater than start number."); - } -} - -void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, - const Descriptor* parent, - EnumDescriptor* result) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->containing_type_ = parent; - result->is_placeholder_ = false; - result->is_unqualified_placeholder_ = false; - - if (proto.value_size() == 0) { - // We cannot allow enums with no values because this would mean there - // would be no valid default value for fields of this type. - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "Enums must contain at least one value."); - } - - BUILD_ARRAY(proto, result, value, BuildEnumValue, result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, - const EnumDescriptor* parent, - EnumValueDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); - result->number_ = proto.number(); - result->type_ = parent; - - // Note: full_name for enum values is a sibling to the parent's name, not a - // child of it. - string* full_name = tables_->AllocateString(*parent->full_name_); - full_name->resize(full_name->size() - parent->name_->size()); - full_name->append(*result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - // Again, enum values are weird because we makes them appear as siblings - // of the enum type instead of children of it. So, we use - // parent->containing_type() as the value's parent. - bool added_to_outer_scope = - AddSymbol(result->full_name(), parent->containing_type(), result->name(), - proto, Symbol(result)); - - // However, we also want to be able to search for values within a single - // enum type, so we add it as a child of the enum type itself, too. - // Note: This could fail, but if it does, the error has already been - // reported by the above AddSymbol() call, so we ignore the return code. - bool added_to_inner_scope = - file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); - - if (added_to_inner_scope && !added_to_outer_scope) { - // This value did not conflict with any values defined in the same enum, - // but it did conflict with some other symbol defined in the enum type's - // scope. Let's print an additional error to explain this. - string outer_scope; - if (parent->containing_type() == NULL) { - outer_scope = file_->package(); - } else { - outer_scope = parent->containing_type()->full_name(); - } - - if (outer_scope.empty()) { - outer_scope = "the global scope"; - } else { - outer_scope = "\"" + outer_scope + "\""; - } - - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "Note that enum values use C++ scoping rules, meaning that " - "enum values are siblings of their type, not children of it. " - "Therefore, \"" + result->name() + "\" must be unique within " - + outer_scope + ", not just within \"" + parent->name() + "\"."); - } - - // An enum is allowed to define two numbers that refer to the same value. - // FindValueByNumber() should return the first such value, so we simply - // ignore AddEnumValueByNumber()'s return code. - file_tables_->AddEnumValueByNumber(result); -} - -void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, - const void* dummy, - ServiceDescriptor* result) { - string* full_name = tables_->AllocateString(file_->package()); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - - BUILD_ARRAY(proto, result, method, BuildMethod, result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - AddSymbol(result->full_name(), NULL, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, - const ServiceDescriptor* parent, - MethodDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); - result->service_ = parent; - - string* full_name = tables_->AllocateString(parent->full_name()); - full_name->append(1, '.'); - full_name->append(*result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); - - // These will be filled in when cross-linking. - result->input_type_ = NULL; - result->output_type_ = NULL; - - // Copy options. - if (!proto.has_options()) { - result->options_ = NULL; // Will set to default_instance later. - } else { - AllocateOptions(proto.options(), result); - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -#undef BUILD_ARRAY - -// ------------------------------------------------------------------- - -void DescriptorBuilder::CrossLinkFile( - FileDescriptor* file, const FileDescriptorProto& proto) { - if (file->options_ == NULL) { - file->options_ = &FileOptions::default_instance(); - } - - for (int i = 0; i < file->message_type_count(); i++) { - CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); - } - - for (int i = 0; i < file->extension_count(); i++) { - CrossLinkField(&file->extensions_[i], proto.extension(i)); - } - - for (int i = 0; i < file->enum_type_count(); i++) { - CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); - } - - for (int i = 0; i < file->service_count(); i++) { - CrossLinkService(&file->services_[i], proto.service(i)); - } -} - -void DescriptorBuilder::CrossLinkMessage( - Descriptor* message, const DescriptorProto& proto) { - if (message->options_ == NULL) { - message->options_ = &MessageOptions::default_instance(); - } - - for (int i = 0; i < message->nested_type_count(); i++) { - CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); - } - - for (int i = 0; i < message->enum_type_count(); i++) { - CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); - } - - for (int i = 0; i < message->field_count(); i++) { - CrossLinkField(&message->fields_[i], proto.field(i)); - } - - for (int i = 0; i < message->extension_count(); i++) { - CrossLinkField(&message->extensions_[i], proto.extension(i)); - } -} - -void DescriptorBuilder::CrossLinkField( - FieldDescriptor* field, const FieldDescriptorProto& proto) { - if (field->options_ == NULL) { - field->options_ = &FieldOptions::default_instance(); - } - - if (proto.has_extendee()) { - Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), - PLACEHOLDER_EXTENDABLE_MESSAGE); - if (extendee.IsNull()) { - AddNotDefinedError(field->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - proto.extendee()); - return; - } else if (extendee.type != Symbol::MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "\"" + proto.extendee() + "\" is not a message type."); - return; - } - field->containing_type_ = extendee.descriptor; - - if (!field->containing_type()->IsExtensionNumber(field->number())) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("\"$0\" does not declare $1 as an " - "extension number.", - field->containing_type()->full_name(), - field->number())); - } - } - - if (proto.has_type_name()) { - // Assume we are expecting a message type unless the proto contains some - // evidence that it expects an enum type. This only makes a difference if - // we end up creating a placeholder. - bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || - proto.has_default_value(); - - Symbol type = - LookupSymbol(proto.type_name(), field->full_name(), - expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, - LOOKUP_TYPES); - - if (type.IsNull()) { - AddNotDefinedError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - proto.type_name()); - return; - } - - if (!proto.has_type()) { - // Choose field type based on symbol. - if (type.type == Symbol::MESSAGE) { - field->type_ = FieldDescriptor::TYPE_MESSAGE; - } else if (type.type == Symbol::ENUM) { - field->type_ = FieldDescriptor::TYPE_ENUM; - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not a type."); - return; - } - } - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (type.type != Symbol::MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not a message type."); - return; - } - field->message_type_ = type.descriptor; - - if (field->has_default_value()) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Messages can't have default values."); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - if (type.type != Symbol::ENUM) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not an enum type."); - return; - } - field->enum_type_ = type.enum_descriptor; - - if (field->enum_type()->is_placeholder_) { - // We can't look up default values for placeholder types. We'll have - // to just drop them. - field->has_default_value_ = false; - } - - if (field->has_default_value()) { - // We can't just use field->enum_type()->FindValueByName() here - // because that locks the pool's mutex, which we have already locked - // at this point. - Symbol default_value = - LookupSymbolNoPlaceholder(proto.default_value(), - field->enum_type()->full_name()); - - if (default_value.type == Symbol::ENUM_VALUE && - default_value.enum_value_descriptor->type() == field->enum_type()) { - field->default_value_enum_ = default_value.enum_value_descriptor; - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Enum type \"" + field->enum_type()->full_name() + - "\" has no value named \"" + proto.default_value() + "\"."); - } - } else if (field->enum_type()->value_count() > 0) { - // All enums must have at least one value, or we would have reported - // an error elsewhere. We use the first defined value as the default - // if a default is not explicitly defined. - field->default_value_enum_ = field->enum_type()->value(0); - } - } else { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Field with primitive type has type_name."); - } - } else { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Field with message or enum type missing type_name."); - } - } - - // Add the field to the fields-by-number table. - // Note: We have to do this *after* cross-linking because extensions do not - // know their containing type until now. - if (!file_tables_->AddFieldByNumber(field)) { - const FieldDescriptor* conflicting_field = - file_tables_->FindFieldByNumber(field->containing_type(), - field->number()); - if (field->is_extension()) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension number $0 has already been used " - "in \"$1\" by extension \"$2\".", - field->number(), - field->containing_type()->full_name(), - conflicting_field->full_name())); - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Field number $0 has already been used in " - "\"$1\" by field \"$2\".", - field->number(), - field->containing_type()->full_name(), - conflicting_field->name())); - } - } - - if (field->is_extension()) { - // No need for error checking: if the extension number collided, - // we've already been informed of it by the if() above. - tables_->AddExtension(field); - } - - // Add the field to the lowercase-name and camelcase-name tables. - file_tables_->AddFieldByStylizedNames(field); -} - -void DescriptorBuilder::CrossLinkEnum( - EnumDescriptor* enum_type, const EnumDescriptorProto& proto) { - if (enum_type->options_ == NULL) { - enum_type->options_ = &EnumOptions::default_instance(); - } - - for (int i = 0; i < enum_type->value_count(); i++) { - CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); - } -} - -void DescriptorBuilder::CrossLinkEnumValue( - EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { - if (enum_value->options_ == NULL) { - enum_value->options_ = &EnumValueOptions::default_instance(); - } -} - -void DescriptorBuilder::CrossLinkService( - ServiceDescriptor* service, const ServiceDescriptorProto& proto) { - if (service->options_ == NULL) { - service->options_ = &ServiceOptions::default_instance(); - } - - for (int i = 0; i < service->method_count(); i++) { - CrossLinkMethod(&service->methods_[i], proto.method(i)); - } -} - -void DescriptorBuilder::CrossLinkMethod( - MethodDescriptor* method, const MethodDescriptorProto& proto) { - if (method->options_ == NULL) { - method->options_ = &MethodOptions::default_instance(); - } - - Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); - if (input_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::INPUT_TYPE, - proto.input_type()); - } else if (input_type.type != Symbol::MESSAGE) { - AddError(method->full_name(), proto, - DescriptorPool::ErrorCollector::INPUT_TYPE, - "\"" + proto.input_type() + "\" is not a message type."); - } else { - method->input_type_ = input_type.descriptor; - } - - Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); - if (output_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::OUTPUT_TYPE, - proto.output_type()); - } else if (output_type.type != Symbol::MESSAGE) { - AddError(method->full_name(), proto, - DescriptorPool::ErrorCollector::OUTPUT_TYPE, - "\"" + proto.output_type() + "\" is not a message type."); - } else { - method->output_type_ = output_type.descriptor; - } -} - -// ------------------------------------------------------------------- - -#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ - for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ - Validate##type##Options(descriptor->array_name##s_ + i, \ - proto.array_name(i)); \ - } - -// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to -// avoid problems that exist at init time. -static bool IsLite(const FileDescriptor* file) { - // TODO(kenton): I don't even remember how many of these conditions are - // actually possible. I'm just being super-safe. - return file != NULL && - &file->options() != NULL && - &file->options() != &FileOptions::default_instance() && - file->options().optimize_for() == FileOptions::LITE_RUNTIME; -} - -void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, - const FileDescriptorProto& proto) { - VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); - VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); - VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); - VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); - - // Lite files can only be imported by other Lite files. - if (!IsLite(file)) { - for (int i = 0; i < file->dependency_count(); i++) { - if (IsLite(file->dependency(i))) { - AddError( - file->name(), proto, - DescriptorPool::ErrorCollector::OTHER, - "Files that do not use optimize_for = LITE_RUNTIME cannot import " - "files which do use this option. This file is not lite, but it " - "imports \"" + file->dependency(i)->name() + "\" which is."); - break; - } - } - } -} - -void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, - const DescriptorProto& proto) { - VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); - VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); - VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); - VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); -} - -void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, - const FieldDescriptorProto& proto) { - if (field->options().has_experimental_map_key()) { - ValidateMapKey(field, proto); - } - - // Only repeated primitive fields may be packed. - if (field->options().packed() && !field->is_packable()) { - AddError( - field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "[packed = true] can only be specified for repeated primitive fields."); - } - - // Note: Default instance may not yet be initialized here, so we have to - // avoid reading from it. - if (field->containing_type_ != NULL && - &field->containing_type()->options() != - &MessageOptions::default_instance() && - field->containing_type()->options().message_set_wire_format()) { - if (field->is_extension()) { - if (!field->is_optional() || - field->type() != FieldDescriptor::TYPE_MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "Extensions of MessageSets must be optional messages."); - } - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "MessageSets cannot have fields, only extensions."); - } - } - - // Lite extensions can only be of Lite types. - if (IsLite(field->file()) && - field->containing_type_ != NULL && - !IsLite(field->containing_type()->file())) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "Extensions to non-lite types can only be declared in non-lite " - "files. Note that you cannot extend a non-lite type to contain " - "a lite type, but the reverse is allowed."); - } -} - -void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, - const EnumDescriptorProto& proto) { - VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); -} - -void DescriptorBuilder::ValidateEnumValueOptions( - EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { - // Nothing to do so far. -} -void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, - const ServiceDescriptorProto& proto) { - if (IsLite(service->file())) { - AddError(service->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "Files with optimize_for = LITE_RUNTIME cannot define services."); - } - - VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); -} - -void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method, - const MethodDescriptorProto& proto) { - // Nothing to do so far. -} - -void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field, - const FieldDescriptorProto& proto) { - if (!field->is_repeated()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map type is only allowed for repeated fields."); - return; - } - - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map type is only allowed for fields with a message type."); - return; - } - - const Descriptor* item_type = field->message_type(); - if (item_type == NULL) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Could not find field type."); - return; - } - - // Find the field in item_type named by "experimental_map_key" - const string& key_name = field->options().experimental_map_key(); - const Symbol key_symbol = LookupSymbol( - key_name, - // We append ".key_name" to the containing type's name since - // LookupSymbol() searches for peers of the supplied name, not - // children of the supplied name. - item_type->full_name() + "." + key_name); - - if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Could not find field named \"" + key_name + "\" in type \"" + - item_type->full_name() + "\"."); - return; - } - const FieldDescriptor* key_field = key_symbol.field_descriptor; - - if (key_field->is_repeated()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map_key must not name a repeated field."); - return; - } - - if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map key must name a scalar or string field."); - return; - } - - field->experimental_map_key_ = key_field; -} - -#undef VALIDATE_OPTIONS_FROM_ARRAY - -// ------------------------------------------------------------------- - -DescriptorBuilder::OptionInterpreter::OptionInterpreter( - DescriptorBuilder* builder) : builder_(builder) { - GOOGLE_CHECK(builder_); -} - -DescriptorBuilder::OptionInterpreter::~OptionInterpreter() { -} - -bool DescriptorBuilder::OptionInterpreter::InterpretOptions( - OptionsToInterpret* options_to_interpret) { - // Note that these may be in different pools, so we can't use the same - // descriptor and reflection objects on both. - Message* options = options_to_interpret->options; - const Message* original_options = options_to_interpret->original_options; - - bool failed = false; - options_to_interpret_ = options_to_interpret; - - // Find the uninterpreted_option field in the mutable copy of the options - // and clear them, since we're about to interpret them. - const FieldDescriptor* uninterpreted_options_field = - options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(uninterpreted_options_field != NULL) - << "No field named \"uninterpreted_option\" in the Options proto."; - options->GetReflection()->ClearField(options, uninterpreted_options_field); - - // Find the uninterpreted_option field in the original options. - const FieldDescriptor* original_uninterpreted_options_field = - original_options->GetDescriptor()-> - FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(original_uninterpreted_options_field != NULL) - << "No field named \"uninterpreted_option\" in the Options proto."; - - const int num_uninterpreted_options = original_options->GetReflection()-> - FieldSize(*original_options, original_uninterpreted_options_field); - for (int i = 0; i < num_uninterpreted_options; ++i) { - uninterpreted_option_ = down_cast( - &original_options->GetReflection()->GetRepeatedMessage( - *original_options, original_uninterpreted_options_field, i)); - if (!InterpretSingleOption(options)) { - // Error already added by InterpretSingleOption(). - failed = true; - break; - } - } - // Reset these, so we don't have any dangling pointers. - uninterpreted_option_ = NULL; - options_to_interpret_ = NULL; - - if (!failed) { - // InterpretSingleOption() added the interpreted options in the - // UnknownFieldSet, in case the option isn't yet known to us. Now we - // serialize the options message and deserialize it back. That way, any - // option fields that we do happen to know about will get moved from the - // UnknownFieldSet into the real fields, and thus be available right away. - // If they are not known, that's OK too. They will get reparsed into the - // UnknownFieldSet and wait there until the message is parsed by something - // that does know about the options. - string buf; - options->AppendToString(&buf); - GOOGLE_CHECK(options->ParseFromString(buf)) - << "Protocol message serialized itself in invalid fashion."; - } - - return !failed; -} - -bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( - Message* options) { - // First do some basic validation. - if (uninterpreted_option_->name_size() == 0) { - // This should never happen unless the parser has gone seriously awry or - // someone has manually created the uninterpreted option badly. - return AddNameError("Option must have a name."); - } - if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { - return AddNameError("Option must not use reserved name " - "\"uninterpreted_option\"."); - } - - const Descriptor* options_descriptor = NULL; - // Get the options message's descriptor from the builder's pool, so that we - // get the version that knows about any extension options declared in the - // file we're currently building. The descriptor should be there as long as - // the file we're building imported "google/protobuf/descriptors.proto". - - // Note that we use DescriptorBuilder::FindSymbol(), not - // DescriptorPool::FindMessageTypeByName() because we're already holding the - // pool's mutex, and the latter method locks it again. - Symbol symbol = builder_->FindSymbolNotEnforcingDeps( - options->GetDescriptor()->full_name()); - if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { - options_descriptor = symbol.descriptor; - } else { - // The options message's descriptor was not in the builder's pool, so use - // the standard version from the generated pool. We're not holding the - // generated pool's mutex, so we can search it the straightforward way. - options_descriptor = options->GetDescriptor(); - } - GOOGLE_CHECK(options_descriptor); - - // We iterate over the name parts to drill into the submessages until we find - // the leaf field for the option. As we drill down we remember the current - // submessage's descriptor in |descriptor| and the next field in that - // submessage in |field|. We also track the fields we're drilling down - // through in |intermediate_fields|. As we go, we reconstruct the full option - // name in |debug_msg_name|, for use in error messages. - const Descriptor* descriptor = options_descriptor; - const FieldDescriptor* field = NULL; - vector intermediate_fields; - string debug_msg_name = ""; - - for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { - const string& name_part = uninterpreted_option_->name(i).name_part(); - if (debug_msg_name.size() > 0) { - debug_msg_name += "."; - } - if (uninterpreted_option_->name(i).is_extension()) { - debug_msg_name += "(" + name_part + ")"; - // Search for the extension's descriptor as an extension in the builder's - // pool. Note that we use DescriptorBuilder::LookupSymbol(), not - // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows - // relative lookups, and 2) because we're already holding the pool's - // mutex, and the latter method locks it again. - Symbol symbol = builder_->LookupSymbol(name_part, - options_to_interpret_->name_scope); - if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { - field = symbol.field_descriptor; - } - // If we don't find the field then the field's descriptor was not in the - // builder's pool, but there's no point in looking in the generated - // pool. We require that you import the file that defines any extensions - // you use, so they must be present in the builder's pool. - } else { - debug_msg_name += name_part; - // Search for the field's descriptor as a regular field. - field = descriptor->FindFieldByName(name_part); - } - - if (field == NULL) { - if (get_allow_unknown(builder_->pool_)) { - // We can't find the option, but AllowUnknownDependencies() is enabled, - // so we will just leave it as uninterpreted. - AddWithoutInterpreting(*uninterpreted_option_, options); - return true; - } else { - return AddNameError("Option \"" + debug_msg_name + "\" unknown."); - } - } else if (field->containing_type() != descriptor) { - if (get_is_placeholder(field->containing_type())) { - // The field is an extension of a placeholder type, so we can't - // reliably verify whether it is a valid extension to use here (e.g. - // we don't know if it is an extension of the correct *Options message, - // or if it has a valid field number, etc.). Just leave it as - // uninterpreted instead. - AddWithoutInterpreting(*uninterpreted_option_, options); - return true; - } else { - // This can only happen if, due to some insane misconfiguration of the - // pools, we find the options message in one pool but the field in - // another. This would probably imply a hefty bug somewhere. - return AddNameError("Option field \"" + debug_msg_name + - "\" is not a field or extension of message \"" + - descriptor->name() + "\"."); - } - } else if (field->is_repeated()) { - return AddNameError("Option field \"" + debug_msg_name + - "\" is repeated. Repeated options are not " - "supported."); - } else if (i < uninterpreted_option_->name_size() - 1) { - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - return AddNameError("Option \"" + debug_msg_name + - "\" is an atomic type, not a message."); - } else { - // Drill down into the submessage. - intermediate_fields.push_back(field); - descriptor = field->message_type(); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - return AddNameError("Option field \"" + debug_msg_name + - "\" cannot be of message type."); - } - } - - // We've found the leaf field. Now we use UnknownFieldSets to set its value - // on the options message. We do so because the message may not yet know - // about its extension fields, so we may not be able to set the fields - // directly. But the UnknownFieldSets will serialize to the same wire-format - // message, so reading that message back in once the extension fields are - // known will populate them correctly. - - // First see if the option is already set. - if (!ExamineIfOptionIsSet( - intermediate_fields.begin(), - intermediate_fields.end(), - field, debug_msg_name, - options->GetReflection()->GetUnknownFields(*options))) { - return false; // ExamineIfOptionIsSet() already added the error. - } - - - // First set the value on the UnknownFieldSet corresponding to the - // innermost message. - scoped_ptr unknown_fields(new UnknownFieldSet()); - if (!SetOptionValue(field, unknown_fields.get())) { - return false; // SetOptionValue() already added the error. - } - - // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all - // the intermediate messages. - for (vector::reverse_iterator iter = - intermediate_fields.rbegin(); - iter != intermediate_fields.rend(); ++iter) { - scoped_ptr parent_unknown_fields(new UnknownFieldSet()); - switch ((*iter)->type()) { - case FieldDescriptor::TYPE_MESSAGE: { - io::StringOutputStream outstr( - parent_unknown_fields->AddLengthDelimited((*iter)->number())); - io::CodedOutputStream out(&outstr); - internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); - GOOGLE_CHECK(!out.HadError()) - << "Unexpected failure while serializing option submessage " - << debug_msg_name << "\"."; - break; - } - - case FieldDescriptor::TYPE_GROUP: { - parent_unknown_fields->AddGroup((*iter)->number()) - ->MergeFrom(*unknown_fields); - break; - } - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " - << (*iter)->type(); - return false; - } - unknown_fields.reset(parent_unknown_fields.release()); - } - - // Now merge the UnknownFieldSet corresponding to the top-level message into - // the options message. - options->GetReflection()->MutableUnknownFields(options)->MergeFrom( - *unknown_fields); - - return true; -} - -void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( - const UninterpretedOption& uninterpreted_option, Message* options) { - const FieldDescriptor* field = - options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(field != NULL); - - options->GetReflection()->AddMessage(options, field) - ->CopyFrom(uninterpreted_option); -} - -bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( - vector::const_iterator intermediate_fields_iter, - vector::const_iterator intermediate_fields_end, - const FieldDescriptor* innermost_field, const string& debug_msg_name, - const UnknownFieldSet& unknown_fields) { - // We do linear searches of the UnknownFieldSet and its sub-groups. This - // should be fine since it's unlikely that any one options structure will - // contain more than a handful of options. - - if (intermediate_fields_iter == intermediate_fields_end) { - // We're at the innermost submessage. - for (int i = 0; i < unknown_fields.field_count(); i++) { - if (unknown_fields.field(i).number() == innermost_field->number()) { - return AddNameError("Option \"" + debug_msg_name + - "\" was already set."); - } - } - return true; - } - - for (int i = 0; i < unknown_fields.field_count(); i++) { - if (unknown_fields.field(i).number() == - (*intermediate_fields_iter)->number()) { - const UnknownField* unknown_field = &unknown_fields.field(i); - FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); - // Recurse into the next submessage. - switch (type) { - case FieldDescriptor::TYPE_MESSAGE: - if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { - UnknownFieldSet intermediate_unknown_fields; - if (intermediate_unknown_fields.ParseFromString( - unknown_field->length_delimited()) && - !ExamineIfOptionIsSet(intermediate_fields_iter + 1, - intermediate_fields_end, - innermost_field, debug_msg_name, - intermediate_unknown_fields)) { - return false; // Error already added. - } - } - break; - - case FieldDescriptor::TYPE_GROUP: - if (unknown_field->type() == UnknownField::TYPE_GROUP) { - if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, - intermediate_fields_end, - innermost_field, debug_msg_name, - unknown_field->group())) { - return false; // Error already added. - } - } - break; - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; - return false; - } - } - } - return true; -} - -bool DescriptorBuilder::OptionInterpreter::SetOptionValue( - const FieldDescriptor* option_field, - UnknownFieldSet* unknown_fields) { - // We switch on the CppType to validate. - switch (option_field->cpp_type()) { - - case FieldDescriptor::CPPTYPE_INT32: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > - static_cast(kint32max)) { - return AddValueError("Value out of range for int32 option \"" + - option_field->full_name() + "\"."); - } else { - SetInt32(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else if (uninterpreted_option_->has_negative_int_value()) { - if (uninterpreted_option_->negative_int_value() < - static_cast(kint32min)) { - return AddValueError("Value out of range for int32 option \"" + - option_field->full_name() + "\"."); - } else { - SetInt32(option_field->number(), - uninterpreted_option_->negative_int_value(), - option_field->type(), unknown_fields); - } - } else { - return AddValueError("Value must be integer for int32 option \"" + - option_field->full_name() + "\"."); - } - break; - - case FieldDescriptor::CPPTYPE_INT64: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > - static_cast(kint64max)) { - return AddValueError("Value out of range for int64 option \"" + - option_field->full_name() + "\"."); - } else { - SetInt64(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else if (uninterpreted_option_->has_negative_int_value()) { - SetInt64(option_field->number(), - uninterpreted_option_->negative_int_value(), - option_field->type(), unknown_fields); - } else { - return AddValueError("Value must be integer for int64 option \"" + - option_field->full_name() + "\"."); - } - break; - - case FieldDescriptor::CPPTYPE_UINT32: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > kuint32max) { - return AddValueError("Value out of range for uint32 option \"" + - option_field->name() + "\"."); - } else { - SetUInt32(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else { - return AddValueError("Value must be non-negative integer for uint32 " - "option \"" + option_field->full_name() + "\"."); - } - break; - - case FieldDescriptor::CPPTYPE_UINT64: - if (uninterpreted_option_->has_positive_int_value()) { - SetUInt64(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } else { - return AddValueError("Value must be non-negative integer for uint64 " - "option \"" + option_field->full_name() + "\"."); - } - break; - - case FieldDescriptor::CPPTYPE_FLOAT: { - float value; - if (uninterpreted_option_->has_double_value()) { - value = uninterpreted_option_->double_value(); - } else if (uninterpreted_option_->has_positive_int_value()) { - value = uninterpreted_option_->positive_int_value(); - } else if (uninterpreted_option_->has_negative_int_value()) { - value = uninterpreted_option_->negative_int_value(); - } else { - return AddValueError("Value must be number for float option \"" + - option_field->full_name() + "\"."); - } - unknown_fields->AddFixed32(option_field->number(), - google::protobuf::internal::WireFormatLite::EncodeFloat(value)); - break; - } - - case FieldDescriptor::CPPTYPE_DOUBLE: { - double value; - if (uninterpreted_option_->has_double_value()) { - value = uninterpreted_option_->double_value(); - } else if (uninterpreted_option_->has_positive_int_value()) { - value = uninterpreted_option_->positive_int_value(); - } else if (uninterpreted_option_->has_negative_int_value()) { - value = uninterpreted_option_->negative_int_value(); - } else { - return AddValueError("Value must be number for double option \"" + - option_field->full_name() + "\"."); - } - unknown_fields->AddFixed64(option_field->number(), - google::protobuf::internal::WireFormatLite::EncodeDouble(value)); - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: - uint64 value; - if (!uninterpreted_option_->has_identifier_value()) { - return AddValueError("Value must be identifier for boolean option " - "\"" + option_field->full_name() + "\"."); - } - if (uninterpreted_option_->identifier_value() == "true") { - value = 1; - } else if (uninterpreted_option_->identifier_value() == "false") { - value = 0; - } else { - return AddValueError("Value must be \"true\" or \"false\" for boolean " - "option \"" + option_field->full_name() + "\"."); - } - unknown_fields->AddVarint(option_field->number(), value); - break; - - case FieldDescriptor::CPPTYPE_ENUM: { - if (!uninterpreted_option_->has_identifier_value()) { - return AddValueError("Value must be identifier for enum-valued option " - "\"" + option_field->full_name() + "\"."); - } - const EnumDescriptor* enum_type = option_field->enum_type(); - const string& value_name = uninterpreted_option_->identifier_value(); - const EnumValueDescriptor* enum_value = NULL; - - if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { - // Note that the enum value's fully-qualified name is a sibling of the - // enum's name, not a child of it. - string fully_qualified_name = enum_type->full_name(); - fully_qualified_name.resize(fully_qualified_name.size() - - enum_type->name().size()); - fully_qualified_name += value_name; - - // Search for the enum value's descriptor in the builder's pool. Note - // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not - // DescriptorPool::FindEnumValueByName() because we're already holding - // the pool's mutex, and the latter method locks it again. - Symbol symbol = - builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); - if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { - if (symbol.enum_value_descriptor->type() != enum_type) { - return AddValueError("Enum type \"" + enum_type->full_name() + - "\" has no value named \"" + value_name + "\" for option \"" + - option_field->full_name() + - "\". This appears to be a value from a sibling type."); - } else { - enum_value = symbol.enum_value_descriptor; - } - } - } else { - // The enum type is in the generated pool, so we can search for the - // value there. - enum_value = enum_type->FindValueByName(value_name); - } - - if (enum_value == NULL) { - return AddValueError("Enum type \"" + - option_field->enum_type()->full_name() + - "\" has no value named \"" + value_name + "\" for " - "option \"" + option_field->full_name() + "\"."); - } else { - // Sign-extension is not a problem, since we cast directly from int32 to - // uint64, without first going through uint32. - unknown_fields->AddVarint(option_field->number(), - static_cast(static_cast(enum_value->number()))); - } - break; - } - - case FieldDescriptor::CPPTYPE_STRING: - if (!uninterpreted_option_->has_string_value()) { - return AddValueError("Value must be quoted string for string option " - "\"" + option_field->full_name() + "\"."); - } - // The string has already been unquoted and unescaped by the parser. - unknown_fields->AddLengthDelimited(option_field->number(), - uninterpreted_option_->string_value()); - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - // We don't currently support defining a message-typed option, so we - // should never actually get here. - return AddValueError("Option \"" + option_field->full_name() + - "\" is a message. To set fields within it, use " - "syntax like \"" + option_field->name() + - ".foo = value\"."); - break; - } - - return true; -} - -void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, - FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_INT32: - unknown_fields->AddVarint(number, - static_cast(static_cast(value))); - break; - - case FieldDescriptor::TYPE_SFIXED32: - unknown_fields->AddFixed32(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SINT32: - unknown_fields->AddVarint(number, - google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); - break; - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; - break; - } -} - -void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, - FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_INT64: - unknown_fields->AddVarint(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SFIXED64: - unknown_fields->AddFixed64(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SINT64: - unknown_fields->AddVarint(number, - google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); - break; - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; - break; - } -} - -void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value, - FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_UINT32: - unknown_fields->AddVarint(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_FIXED32: - unknown_fields->AddFixed32(number, static_cast(value)); - break; - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; - break; - } -} - -void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value, - FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_UINT64: - unknown_fields->AddVarint(number, value); - break; - - case FieldDescriptor::TYPE_FIXED64: - unknown_fields->AddFixed64(number, value); - break; - - default: - GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; - break; - } -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/descriptor.h b/Resources/NetHook/google/protobuf/descriptor.h deleted file mode 100644 index 7f87dd80..00000000 --- a/Resources/NetHook/google/protobuf/descriptor.h +++ /dev/null @@ -1,1367 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains classes which describe a type of protocol message. -// You can use a message's descriptor to learn at runtime what fields -// it contains and what the types of those fields are. The Message -// interface also allows you to dynamically access and modify individual -// fields by passing the FieldDescriptor of the field you are interested -// in. -// -// Most users will not care about descriptors, because they will write -// code specific to certain protocol types and will simply use the classes -// generated by the protocol compiler directly. Advanced users who want -// to operate on arbitrary types (not known at compile time) may want to -// read descriptors in order to learn about the contents of a message. -// A very small number of users will want to construct their own -// Descriptors, either because they are implementing Message manually or -// because they are writing something like the protocol compiler. -// -// For an example of how you might use descriptors, see the code example -// at the top of message.h. - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ -#define GOOGLE_PROTOBUF_DESCRIPTOR_H__ - -#include -#include -#include - - -namespace google { -namespace protobuf { - -// Defined in this file. -class Descriptor; -class FieldDescriptor; -class EnumDescriptor; -class EnumValueDescriptor; -class ServiceDescriptor; -class MethodDescriptor; -class FileDescriptor; -class DescriptorDatabase; -class DescriptorPool; - -// Defined in descriptor.proto -class DescriptorProto; -class FieldDescriptorProto; -class EnumDescriptorProto; -class EnumValueDescriptorProto; -class ServiceDescriptorProto; -class MethodDescriptorProto; -class FileDescriptorProto; -class MessageOptions; -class FieldOptions; -class EnumOptions; -class EnumValueOptions; -class ServiceOptions; -class MethodOptions; -class FileOptions; -class UninterpretedOption; - -// Defined in message.h -class Message; - -// Defined in descriptor.cc -class DescriptorBuilder; -class FileDescriptorTables; - -// Defined in unknown_field_set.h. -class UnknownField; - -// Describes a type of protocol message, or a particular group within a -// message. To obtain the Descriptor for a given message object, call -// Message::GetDescriptor(). Generated message classes also have a -// static method called descriptor() which returns the type's descriptor. -// Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT Descriptor { - public: - // The name of the message type, not including its scope. - const string& name() const; - - // The fully-qualified name of the message type, scope delimited by - // periods. For example, message type "Foo" which is declared in package - // "bar" has full name "bar.Foo". If a type "Baz" is nested within - // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that - // comes after the last '.', use name(). - const string& full_name() const; - - // Index of this descriptor within the file or containing type's message - // type array. - int index() const; - - // The .proto file in which this message type was defined. Never NULL. - const FileDescriptor* file() const; - - // If this Descriptor describes a nested type, this returns the type - // in which it is nested. Otherwise, returns NULL. - const Descriptor* containing_type() const; - - // Get options for this message type. These are specified in the .proto file - // by placing lines like "option foo = 1234;" in the message definition. - // Allowed options are defined by MessageOptions in - // google/protobuf/descriptor.proto, and any available extensions of that - // message. - const MessageOptions& options() const; - - // Write the contents of this Descriptor into the given DescriptorProto. - // The target DescriptorProto must be clear before calling this; if it - // isn't, the result may be garbage. - void CopyTo(DescriptorProto* proto) const; - - // Write the contents of this decriptor in a human-readable form. Output - // will be suitable for re-parsing. - string DebugString() const; - - // Field stuff ----------------------------------------------------- - - // The number of fields in this message type. - int field_count() const; - // Gets a field by index, where 0 <= index < field_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* field(int index) const; - - // Looks up a field by declared tag number. Returns NULL if no such field - // exists. - const FieldDescriptor* FindFieldByNumber(int number) const; - // Looks up a field by name. Returns NULL if no such field exists. - const FieldDescriptor* FindFieldByName(const string& name) const; - - // Looks up a field by lowercased name (as returned by lowercase_name()). - // This lookup may be ambiguous if multiple field names differ only by case, - // in which case the field returned is chosen arbitrarily from the matches. - const FieldDescriptor* FindFieldByLowercaseName( - const string& lowercase_name) const; - - // Looks up a field by camel-case name (as returned by camelcase_name()). - // This lookup may be ambiguous if multiple field names differ in a way that - // leads them to have identical camel-case names, in which case the field - // returned is chosen arbitrarily from the matches. - const FieldDescriptor* FindFieldByCamelcaseName( - const string& camelcase_name) const; - - // Nested type stuff ----------------------------------------------- - - // The number of nested types in this message type. - int nested_type_count() const; - // Gets a nested type by index, where 0 <= index < nested_type_count(). - // These are returned in the order they were defined in the .proto file. - const Descriptor* nested_type(int index) const; - - // Looks up a nested type by name. Returns NULL if no such nested type - // exists. - const Descriptor* FindNestedTypeByName(const string& name) const; - - // Enum stuff ------------------------------------------------------ - - // The number of enum types in this message type. - int enum_type_count() const; - // Gets an enum type by index, where 0 <= index < enum_type_count(). - // These are returned in the order they were defined in the .proto file. - const EnumDescriptor* enum_type(int index) const; - - // Looks up an enum type by name. Returns NULL if no such enum type exists. - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - - // Looks up an enum value by name, among all enum types in this message. - // Returns NULL if no such value exists. - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - - // Extensions ------------------------------------------------------ - - // A range of field numbers which are designated for third-party - // extensions. - struct ExtensionRange { - int start; // inclusive - int end; // exclusive - }; - - // The number of extension ranges in this message type. - int extension_range_count() const; - // Gets an extension range by index, where 0 <= index < - // extension_range_count(). These are returned in the order they were defined - // in the .proto file. - const ExtensionRange* extension_range(int index) const; - - // Returns true if the number is in one of the extension ranges. - bool IsExtensionNumber(int number) const; - - // The number of extensions -- extending *other* messages -- that were - // defined nested within this message type's scope. - int extension_count() const; - // Get an extension by index, where 0 <= index < extension_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* extension(int index) const; - - // Looks up a named extension (which extends some *other* message type) - // defined within this message type's scope. - const FieldDescriptor* FindExtensionByName(const string& name) const; - - // Similar to FindFieldByLowercaseName(), but finds extensions defined within - // this message type's scope. - const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; - - // Similar to FindFieldByCamelcaseName(), but finds extensions defined within - // this message type's scope. - const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; - - private: - typedef MessageOptions OptionsType; - - // Internal version of DebugString; controls the level of indenting for - // correct depth - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const MessageOptions* options_; - - // True if this is a placeholder for an unknown type. - bool is_placeholder_; - // True if this is a placeholder and the type name wasn't fully-qualified. - bool is_unqualified_placeholder_; - - int field_count_; - FieldDescriptor* fields_; - int nested_type_count_; - Descriptor* nested_types_; - int enum_type_count_; - EnumDescriptor* enum_types_; - int extension_range_count_; - ExtensionRange* extension_ranges_; - int extension_count_; - FieldDescriptor* extensions_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in descriptor.cc - // and update them to initialize the field. - - // Must be constructed using DescriptorPool. - Descriptor() {} - friend class DescriptorBuilder; - friend class EnumDescriptor; - friend class FieldDescriptor; - friend class MethodDescriptor; - friend class FileDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); -}; - -// Describes a single field of a message. To get the descriptor for a given -// field, first get the Descriptor for the message in which it is defined, -// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for -// an extension, do one of the following: -// - Get the Descriptor or FileDescriptor for its containing scope, then -// call Descriptor::FindExtensionByName() or -// FileDescriptor::FindExtensionByName(). -// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber(). -// - Given a Reflection for a message object, call -// Reflection::FindKnownExtensionByName() or -// Reflection::FindKnownExtensionByNumber(). -// Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT FieldDescriptor { - public: - // Identifies a field type. 0 is reserved for errors. The order is weird - // for historical reasons. Types 12 and up are new in proto2. - enum Type { - TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. - TYPE_FLOAT = 2, // float, exactly four bytes on the wire. - TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4, // uint64, varint on the wire. - TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. - TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. - TYPE_BOOL = 8, // bool, varint on the wire. - TYPE_STRING = 9, // UTF-8 text. - TYPE_GROUP = 10, // Tag-delimited message. Deprecated. - TYPE_MESSAGE = 11, // Length-delimited message. - - TYPE_BYTES = 12, // Arbitrary byte array. - TYPE_UINT32 = 13, // uint32, varint on the wire - TYPE_ENUM = 14, // Enum, varint on the wire - TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire - TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire - TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire - TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire - - MAX_TYPE = 18, // Constant useful for defining lookup tables - // indexed by Type. - }; - - // Specifies the C++ data type used to represent the field. There is a - // fixed mapping from Type to CppType where each Type maps to exactly one - // CppType. 0 is reserved for errors. - enum CppType { - CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 - CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 - CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 - CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 - CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE - CPPTYPE_FLOAT = 6, // TYPE_FLOAT - CPPTYPE_BOOL = 7, // TYPE_BOOL - CPPTYPE_ENUM = 8, // TYPE_ENUM - CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES - CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP - - MAX_CPPTYPE = 10, // Constant useful for defining lookup tables - // indexed by CppType. - }; - - // Identifies whether the field is optional, required, or repeated. 0 is - // reserved for errors. - enum Label { - LABEL_OPTIONAL = 1, // optional - LABEL_REQUIRED = 2, // required - LABEL_REPEATED = 3, // repeated - - MAX_LABEL = 3, // Constant useful for defining lookup tables - // indexed by Label. - }; - - // Valid field numbers are positive integers up to kMaxNumber. - static const int kMaxNumber = (1 << 29) - 1; - - // First field number reserved for the protocol buffer library implementation. - // Users may not declare fields that use reserved numbers. - static const int kFirstReservedNumber = 19000; - // Last field number reserved for the protocol buffer library implementation. - // Users may not declare fields that use reserved numbers. - static const int kLastReservedNumber = 19999; - - const string& name() const; // Name of this field within the message. - const string& full_name() const; // Fully-qualified name of the field. - const FileDescriptor* file() const;// File in which this field was defined. - bool is_extension() const; // Is this an extension field? - int number() const; // Declared tag number. - - // Same as name() except converted to lower-case. This (and especially the - // FindFieldByLowercaseName() method) can be useful when parsing formats - // which prefer to use lowercase naming style. (Although, technically - // field names should be lowercased anyway according to the protobuf style - // guide, so this only makes a difference when dealing with old .proto files - // which do not follow the guide.) - const string& lowercase_name() const; - - // Same as name() except converted to camel-case. In this conversion, any - // time an underscore appears in the name, it is removed and the next - // letter is capitalized. Furthermore, the first letter of the name is - // lower-cased. Examples: - // FooBar -> fooBar - // foo_bar -> fooBar - // fooBar -> fooBar - // This (and especially the FindFieldByCamelcaseName() method) can be useful - // when parsing formats which prefer to use camel-case naming style. - const string& camelcase_name() const; - - Type type() const; // Declared type of this field. - CppType cpp_type() const; // C++ type of this field. - Label label() const; // optional/required/repeated - - bool is_required() const; // shorthand for label() == LABEL_REQUIRED - bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL - bool is_repeated() const; // shorthand for label() == LABEL_REPEATED - bool is_packable() const; // shorthand for is_repeated() && - // IsTypePackable(type()) - - // Index of this field within the message's field array, or the file or - // extension scope's extensions array. - int index() const; - - // Does this field have an explicitly-declared default value? - bool has_default_value() const; - - // Get the field default value if cpp_type() == CPPTYPE_INT32. If no - // explicit default was defined, the default is 0. - int32 default_value_int32() const; - // Get the field default value if cpp_type() == CPPTYPE_INT64. If no - // explicit default was defined, the default is 0. - int64 default_value_int64() const; - // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no - // explicit default was defined, the default is 0. - uint32 default_value_uint32() const; - // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no - // explicit default was defined, the default is 0. - uint64 default_value_uint64() const; - // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no - // explicit default was defined, the default is 0.0. - float default_value_float() const; - // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no - // explicit default was defined, the default is 0.0. - double default_value_double() const; - // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no - // explicit default was defined, the default is false. - bool default_value_bool() const; - // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no - // explicit default was defined, the default is the first value defined - // in the enum type (all enum types are required to have at least one value). - // This never returns NULL. - const EnumValueDescriptor* default_value_enum() const; - // Get the field default value if cpp_type() == CPPTYPE_STRING. If no - // explicit default was defined, the default is the empty string. - const string& default_value_string() const; - - // The Descriptor for the message of which this is a field. For extensions, - // this is the extended type. Never NULL. - const Descriptor* containing_type() const; - - // An extension may be declared within the scope of another message. If this - // field is an extension (is_extension() is true), then extension_scope() - // returns that message, or NULL if the extension was declared at global - // scope. If this is not an extension, extension_scope() is undefined (may - // assert-fail). - const Descriptor* extension_scope() const; - - // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the - // message or the group type. Otherwise, undefined. - const Descriptor* message_type() const; - // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise, - // undefined. - const EnumDescriptor* enum_type() const; - - // EXPERIMENTAL; DO NOT USE. - // If this field is a map field, experimental_map_key() is the field - // that is the key for this map. - // experimental_map_key()->containing_type() is the same as message_type(). - const FieldDescriptor* experimental_map_key() const; - - // Get the FieldOptions for this field. This includes things listed in - // square brackets after the field definition. E.g., the field: - // optional string text = 1 [ctype=CORD]; - // has the "ctype" option set. Allowed options are defined by FieldOptions - // in google/protobuf/descriptor.proto, and any available extensions of that - // message. - const FieldOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(FieldDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - // Helper method to get the CppType for a particular Type. - static CppType TypeToCppType(Type type); - - // Return true iff [packed = true] is valid for fields of this type. - static inline bool IsTypePackable(Type field_type); - - private: - typedef FieldOptions OptionsType; - - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - // formats the default value appropriately and returns it as a string. - // Must have a default value to call this. If quote_string_type is true, then - // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped. - string DefaultValueAsString(bool quote_string_type) const; - - const string* name_; - const string* full_name_; - const string* lowercase_name_; - const string* camelcase_name_; - const FileDescriptor* file_; - int number_; - Type type_; - Label label_; - bool is_extension_; - const Descriptor* containing_type_; - const Descriptor* extension_scope_; - const Descriptor* message_type_; - const EnumDescriptor* enum_type_; - const FieldDescriptor* experimental_map_key_; - const FieldOptions* options_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in - // descriptor.cc and update them to initialize the field. - - bool has_default_value_; - union { - int32 default_value_int32_; - int64 default_value_int64_; - uint32 default_value_uint32_; - uint64 default_value_uint64_; - float default_value_float_; - double default_value_double_; - bool default_value_bool_; - - const EnumValueDescriptor* default_value_enum_; - const string* default_value_string_; - }; - - static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; - - static const char * const kTypeToName[MAX_TYPE + 1]; - - static const char * const kLabelToName[MAX_LABEL + 1]; - - // Must be constructed using DescriptorPool. - FieldDescriptor() {} - friend class DescriptorBuilder; - friend class FileDescriptor; - friend class Descriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); -}; - -// Describes an enum type defined in a .proto file. To get the EnumDescriptor -// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool -// to construct your own descriptors. -class LIBPROTOBUF_EXPORT EnumDescriptor { - public: - // The name of this enum type in the containing scope. - const string& name() const; - - // The fully-qualified name of the enum type, scope delimited by periods. - const string& full_name() const; - - // Index of this enum within the file or containing message's enum array. - int index() const; - - // The .proto file in which this enum type was defined. Never NULL. - const FileDescriptor* file() const; - - // The number of values for this EnumDescriptor. Guaranteed to be greater - // than zero. - int value_count() const; - // Gets a value by index, where 0 <= index < value_count(). - // These are returned in the order they were defined in the .proto file. - const EnumValueDescriptor* value(int index) const; - - // Looks up a value by name. Returns NULL if no such value exists. - const EnumValueDescriptor* FindValueByName(const string& name) const; - // Looks up a value by number. Returns NULL if no such value exists. If - // multiple values have this number, the first one defined is returned. - const EnumValueDescriptor* FindValueByNumber(int number) const; - - // If this enum type is nested in a message type, this is that message type. - // Otherwise, NULL. - const Descriptor* containing_type() const; - - // Get options for this enum type. These are specified in the .proto file by - // placing lines like "option foo = 1234;" in the enum definition. Allowed - // options are defined by EnumOptions in google/protobuf/descriptor.proto, - // and any available extensions of that message. - const EnumOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(EnumDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - typedef EnumOptions OptionsType; - - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const EnumOptions* options_; - - // True if this is a placeholder for an unknown type. - bool is_placeholder_; - // True if this is a placeholder and the type name wasn't fully-qualified. - bool is_unqualified_placeholder_; - - int value_count_; - EnumValueDescriptor* values_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in - // descriptor.cc and update them to initialize the field. - - // Must be constructed using DescriptorPool. - EnumDescriptor() {} - friend class DescriptorBuilder; - friend class Descriptor; - friend class FieldDescriptor; - friend class EnumValueDescriptor; - friend class FileDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); -}; - -// Describes an individual enum constant of a particular type. To get the -// EnumValueDescriptor for a given enum value, first get the EnumDescriptor -// for its type, then use EnumDescriptor::FindValueByName() or -// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct -// your own descriptors. -class LIBPROTOBUF_EXPORT EnumValueDescriptor { - public: - const string& name() const; // Name of this enum constant. - int index() const; // Index within the enums's Descriptor. - int number() const; // Numeric value of this enum constant. - - // The full_name of an enum value is a sibling symbol of the enum type. - // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually - // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT - // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform - // with C++ scoping rules for enums. - const string& full_name() const; - - // The type of this value. Never NULL. - const EnumDescriptor* type() const; - - // Get options for this enum value. These are specified in the .proto file - // by adding text like "[foo = 1234]" after an enum value definition. - // Allowed options are defined by EnumValueOptions in - // google/protobuf/descriptor.proto, and any available extensions of that - // message. - const EnumValueOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(EnumValueDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - typedef EnumValueOptions OptionsType; - - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - int number_; - const EnumDescriptor* type_; - const EnumValueOptions* options_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() - // in descriptor.cc and update them to initialize the field. - - // Must be constructed using DescriptorPool. - EnumValueDescriptor() {} - friend class DescriptorBuilder; - friend class EnumDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); -}; - -// Describes an RPC service. To get the ServiceDescriptor for a service, -// call Service::GetDescriptor(). Generated service classes also have a -// static method called descriptor() which returns the type's -// ServiceDescriptor. Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT ServiceDescriptor { - public: - // The name of the service, not including its containing scope. - const string& name() const; - // The fully-qualified name of the service, scope delimited by periods. - const string& full_name() const; - // Index of this service within the file's services array. - int index() const; - - // The .proto file in which this service was defined. Never NULL. - const FileDescriptor* file() const; - - // Get options for this service type. These are specified in the .proto file - // by placing lines like "option foo = 1234;" in the service definition. - // Allowed options are defined by ServiceOptions in - // google/protobuf/descriptor.proto, and any available extensions of that - // message. - const ServiceOptions& options() const; - - // The number of methods this service defines. - int method_count() const; - // Gets a MethodDescriptor by index, where 0 <= index < method_count(). - // These are returned in the order they were defined in the .proto file. - const MethodDescriptor* method(int index) const; - - // Look up a MethodDescriptor by name. - const MethodDescriptor* FindMethodByName(const string& name) const; - - // See Descriptor::CopyTo(). - void CopyTo(ServiceDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - typedef ServiceOptions OptionsType; - - // See Descriptor::DebugString(). - void DebugString(string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - const ServiceOptions* options_; - int method_count_; - MethodDescriptor* methods_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in - // descriptor.cc and update them to initialize the field. - - // Must be constructed using DescriptorPool. - ServiceDescriptor() {} - friend class DescriptorBuilder; - friend class FileDescriptor; - friend class MethodDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); -}; - -// Describes an individual service method. To obtain a MethodDescriptor given -// a service, first get its ServiceDescriptor, then call -// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your -// own descriptors. -class LIBPROTOBUF_EXPORT MethodDescriptor { - public: - // Name of this method, not including containing scope. - const string& name() const; - // The fully-qualified name of the method, scope delimited by periods. - const string& full_name() const; - // Index within the service's Descriptor. - int index() const; - - // Gets the service to which this method belongs. Never NULL. - const ServiceDescriptor* service() const; - - // Gets the type of protocol message which this method accepts as input. - const Descriptor* input_type() const; - // Gets the type of protocol message which this message produces as output. - const Descriptor* output_type() const; - - // Get options for this method. These are specified in the .proto file by - // placing lines like "option foo = 1234;" in curly-braces after a method - // declaration. Allowed options are defined by MethodOptions in - // google/protobuf/descriptor.proto, and any available extensions of that - // message. - const MethodOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(MethodDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - typedef MethodOptions OptionsType; - - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const ServiceDescriptor* service_; - const Descriptor* input_type_; - const Descriptor* output_type_; - const MethodOptions* options_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in - // descriptor.cc and update them to initialize the field. - - // Must be constructed using DescriptorPool. - MethodDescriptor() {} - friend class DescriptorBuilder; - friend class ServiceDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor); -}; - -// Describes a whole .proto file. To get the FileDescriptor for a compiled-in -// file, get the descriptor for something defined in that file and call -// descriptor->file(). Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT FileDescriptor { - public: - // The filename, relative to the source tree. - // e.g. "google/protobuf/descriptor.proto" - const string& name() const; - - // The package, e.g. "google.protobuf.compiler". - const string& package() const; - - // The DescriptorPool in which this FileDescriptor and all its contents were - // allocated. Never NULL. - const DescriptorPool* pool() const; - - // The number of files imported by this one. - int dependency_count() const; - // Gets an imported file by index, where 0 <= index < dependency_count(). - // These are returned in the order they were defined in the .proto file. - const FileDescriptor* dependency(int index) const; - - // Number of top-level message types defined in this file. (This does not - // include nested types.) - int message_type_count() const; - // Gets a top-level message type, where 0 <= index < message_type_count(). - // These are returned in the order they were defined in the .proto file. - const Descriptor* message_type(int index) const; - - // Number of top-level enum types defined in this file. (This does not - // include nested types.) - int enum_type_count() const; - // Gets a top-level enum type, where 0 <= index < enum_type_count(). - // These are returned in the order they were defined in the .proto file. - const EnumDescriptor* enum_type(int index) const; - - // Number of services defined in this file. - int service_count() const; - // Gets a service, where 0 <= index < service_count(). - // These are returned in the order they were defined in the .proto file. - const ServiceDescriptor* service(int index) const; - - // Number of extensions defined at file scope. (This does not include - // extensions nested within message types.) - int extension_count() const; - // Gets an extension's descriptor, where 0 <= index < extension_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* extension(int index) const; - - // Get options for this file. These are specified in the .proto file by - // placing lines like "option foo = 1234;" at the top level, outside of any - // other definitions. Allowed options are defined by FileOptions in - // google/protobuf/descriptor.proto, and any available extensions of that - // message. - const FileOptions& options() const; - - // Find a top-level message type by name. Returns NULL if not found. - const Descriptor* FindMessageTypeByName(const string& name) const; - // Find a top-level enum type by name. Returns NULL if not found. - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - // Find an enum value defined in any top-level enum by name. Returns NULL if - // not found. - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - // Find a service definition by name. Returns NULL if not found. - const ServiceDescriptor* FindServiceByName(const string& name) const; - // Find a top-level extension definition by name. Returns NULL if not found. - const FieldDescriptor* FindExtensionByName(const string& name) const; - // Similar to FindExtensionByName(), but searches by lowercased-name. See - // Descriptor::FindFieldByLowercaseName(). - const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; - // Similar to FindExtensionByName(), but searches by camelcased-name. See - // Descriptor::FindFieldByCamelcaseName(). - const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; - - // See Descriptor::CopyTo(). - void CopyTo(FileDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - typedef FileOptions OptionsType; - - const string* name_; - const string* package_; - const DescriptorPool* pool_; - int dependency_count_; - const FileDescriptor** dependencies_; - int message_type_count_; - Descriptor* message_types_; - int enum_type_count_; - EnumDescriptor* enum_types_; - int service_count_; - ServiceDescriptor* services_; - int extension_count_; - FieldDescriptor* extensions_; - const FileOptions* options_; - - const FileDescriptorTables* tables_; - // IMPORTANT: If you add a new field, make sure to search for all instances - // of Allocate() and AllocateArray() in - // descriptor.cc and update them to initialize the field. - - FileDescriptor() {} - friend class DescriptorBuilder; - friend class Descriptor; - friend class FieldDescriptor; - friend class EnumDescriptor; - friend class ServiceDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); -}; - -// =================================================================== - -// Used to construct descriptors. -// -// Normally you won't want to build your own descriptors. Message classes -// constructed by the protocol compiler will provide them for you. However, -// if you are implementing Message on your own, or if you are writing a -// program which can operate on totally arbitrary types and needs to load -// them from some sort of database, you might need to. -// -// Since Descriptors are composed of a whole lot of cross-linked bits of -// data that would be a pain to put together manually, the -// DescriptorPool class is provided to make the process easier. It can -// take a FileDescriptorProto (defined in descriptor.proto), validate it, -// and convert it to a set of nicely cross-linked Descriptors. -// -// DescriptorPool also helps with memory management. Descriptors are -// composed of many objects containing static data and pointers to each -// other. In all likelihood, when it comes time to delete this data, -// you'll want to delete it all at once. In fact, it is not uncommon to -// have a whole pool of descriptors all cross-linked with each other which -// you wish to delete all at once. This class represents such a pool, and -// handles the memory management for you. -// -// You can also search for descriptors within a DescriptorPool by name, and -// extensions by number. -class LIBPROTOBUF_EXPORT DescriptorPool { - public: - // Create a normal, empty DescriptorPool. - DescriptorPool(); - - // Constructs a DescriptorPool that, when it can't find something among the - // descriptors already in the pool, looks for it in the given - // DescriptorDatabase. - // Notes: - // - If a DescriptorPool is constructed this way, its BuildFile*() methods - // must not be called (they will assert-fail). The only way to populate - // the pool with descriptors is to call the Find*By*() methods. - // - The Find*By*() methods may block the calling thread if the - // DescriptorDatabase blocks. This in turn means that parsing messages - // may block if they need to look up extensions. - // - The Find*By*() methods will use mutexes for thread-safety, thus making - // them slower even when they don't have to fall back to the database. - // In fact, even the Find*By*() methods of descriptor objects owned by - // this pool will be slower, since they will have to obtain locks too. - // - An ErrorCollector may optionally be given to collect validation errors - // in files loaded from the database. If not given, errors will be printed - // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this - // ErrorCollector may be called from any thread that calls one of the - // Find*By*() methods. - class ErrorCollector; - explicit DescriptorPool(DescriptorDatabase* fallback_database, - ErrorCollector* error_collector = NULL); - - ~DescriptorPool(); - - // Get a pointer to the generated pool. Generated protocol message classes - // which are compiled into the binary will allocate their descriptors in - // this pool. Do not add your own descriptors to this pool. - static const DescriptorPool* generated_pool(); - - // Find a FileDescriptor in the pool by file name. Returns NULL if not - // found. - const FileDescriptor* FindFileByName(const string& name) const; - - // Find the FileDescriptor in the pool which defines the given symbol. - // If any of the Find*ByName() methods below would succeed, then this is - // equivalent to calling that method and calling the result's file() method. - // Otherwise this returns NULL. - const FileDescriptor* FindFileContainingSymbol( - const string& symbol_name) const; - - // Looking up descriptors ------------------------------------------ - // These find descriptors by fully-qualified name. These will find both - // top-level descriptors and nested descriptors. They return NULL if not - // found. - - const Descriptor* FindMessageTypeByName(const string& name) const; - const FieldDescriptor* FindFieldByName(const string& name) const; - const FieldDescriptor* FindExtensionByName(const string& name) const; - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - const ServiceDescriptor* FindServiceByName(const string& name) const; - const MethodDescriptor* FindMethodByName(const string& name) const; - - // Finds an extension of the given type by number. The extendee must be - // a member of this DescriptorPool or one of its underlays. - const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee, - int number) const; - - // Finds extensions of extendee. The extensions will be appended to - // out in an undefined order. Only extensions defined directly in - // this DescriptorPool or one of its underlays are guaranteed to be - // found: extensions defined in the fallback database might not be found - // depending on the database implementation. - void FindAllExtensions(const Descriptor* extendee, - vector* out) const; - - // Building descriptors -------------------------------------------- - - // When converting a FileDescriptorProto to a FileDescriptor, various - // errors might be detected in the input. The caller may handle these - // programmatically by implementing an ErrorCollector. - class LIBPROTOBUF_EXPORT ErrorCollector { - public: - inline ErrorCollector() {} - virtual ~ErrorCollector(); - - // These constants specify what exact part of the construct is broken. - // This is useful e.g. for mapping the error back to an exact location - // in a .proto file. - enum ErrorLocation { - NAME, // the symbol name, or the package name for files - NUMBER, // field or extension range number - TYPE, // field type - EXTENDEE, // field extendee - DEFAULT_VALUE, // field default value - INPUT_TYPE, // method input type - OUTPUT_TYPE, // method output type - OPTION_NAME, // name in assignment - OPTION_VALUE, // value in option assignment - OTHER // some other problem - }; - - // Reports an error in the FileDescriptorProto. - virtual void AddError( - const string& filename, // File name in which the error occurred. - const string& element_name, // Full name of the erroneous element. - const Message* descriptor, // Descriptor of the erroneous element. - ErrorLocation location, // One of the location constants, above. - const string& message // Human-readable error message. - ) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); - }; - - // Convert the FileDescriptorProto to real descriptors and place them in - // this DescriptorPool. All dependencies of the file must already be in - // the pool. Returns the resulting FileDescriptor, or NULL if there were - // problems with the input (e.g. the message was invalid, or dependencies - // were missing). Details about the errors are written to GOOGLE_LOG(ERROR). - const FileDescriptor* BuildFile(const FileDescriptorProto& proto); - - // Same as BuildFile() except errors are sent to the given ErrorCollector. - const FileDescriptor* BuildFileCollectingErrors( - const FileDescriptorProto& proto, - ErrorCollector* error_collector); - - // By default, it is an error if a FileDescriptorProto contains references - // to types or other files that are not found in the DescriptorPool (or its - // backing DescriptorDatabase, if any). If you call - // AllowUnknownDependencies(), however, then unknown types and files - // will be replaced by placeholder descriptors. This can allow you to - // perform some useful operations with a .proto file even if you do not - // have access to other .proto files on which it depends. However, some - // heuristics must be used to fill in the gaps in information, and these - // can lead to descriptors which are inaccurate. For example, the - // DescriptorPool may be forced to guess whether an unknown type is a message - // or an enum, as well as what package it resides in. Furthermore, - // placeholder types will not be discoverable via FindMessageTypeByName() - // and similar methods, which could confuse some descriptor-based algorithms. - // Generally, the results of this option should only be relied upon for - // debugging purposes. - void AllowUnknownDependencies() { allow_unknown_ = true; } - - // Internal stuff -------------------------------------------------- - // These methods MUST NOT be called from outside the proto2 library. - // These methods may contain hidden pitfalls and may be removed in a - // future library version. - - // Create a DescriptorPool which is overlaid on top of some other pool. - // If you search for a descriptor in the overlay and it is not found, the - // underlay will be searched as a backup. If the underlay has its own - // underlay, that will be searched next, and so on. This also means that - // files built in the overlay will be cross-linked with the underlay's - // descriptors if necessary. The underlay remains property of the caller; - // it must remain valid for the lifetime of the newly-constructed pool. - // - // Example: Say you want to parse a .proto file at runtime in order to use - // its type with a DynamicMessage. Say this .proto file has dependencies, - // but you know that all the dependencies will be things that are already - // compiled into the binary. For ease of use, you'd like to load the types - // right out of generated_pool() rather than have to parse redundant copies - // of all these .protos and runtime. But, you don't want to add the parsed - // types directly into generated_pool(): this is not allowed, and would be - // bad design anyway. So, instead, you could use generated_pool() as an - // underlay for a new DescriptorPool in which you add only the new file. - // - // WARNING: Use of underlays can lead to many subtle gotchas. Instead, - // try to formulate what you want to do in terms of DescriptorDatabases. - explicit DescriptorPool(const DescriptorPool* underlay); - - // Called by generated classes at init time to add their descriptors to - // generated_pool. Do NOT call this in your own code! filename must be a - // permanent string (e.g. a string literal). - static void InternalAddGeneratedFile( - const void* encoded_file_descriptor, int size); - - - // For internal use only: Gets a non-const pointer to the generated pool. - // This is called at static-initialization time only, so thread-safety is - // not a concern. If both an underlay and a fallback database are present, - // the fallback database takes precedence. - static DescriptorPool* internal_generated_pool(); - - // For internal use only: Changes the behavior of BuildFile() such that it - // allows the file to make reference to message types declared in other files - // which it did not officially declare as dependencies. - void InternalDontEnforceDependencies(); - - // For internal use only. - void internal_set_underlay(const DescriptorPool* underlay) { - underlay_ = underlay; - } - - // For internal (unit test) use only: Returns true if a FileDescriptor has - // been constructed for the given file, false otherwise. Useful for testing - // lazy descriptor initialization behavior. - bool InternalIsFileLoaded(const string& filename) const; - - private: - friend class Descriptor; - friend class FieldDescriptor; - friend class EnumDescriptor; - friend class ServiceDescriptor; - friend class FileDescriptor; - friend class DescriptorBuilder; - - // Tries to find something in the fallback database and link in the - // corresponding proto file. Returns true if successful, in which case - // the caller should search for the thing again. These are declared - // const because they are called by (semantically) const methods. - bool TryFindFileInFallbackDatabase(const string& name) const; - bool TryFindSymbolInFallbackDatabase(const string& name) const; - bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, - int field_number) const; - - // Like BuildFile() but called internally when the file has been loaded from - // fallback_database_. Declared const because it is called by (semantically) - // const methods. - const FileDescriptor* BuildFileFromDatabase( - const FileDescriptorProto& proto) const; - - // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex - // which must be locked while accessing tables_. - Mutex* mutex_; - - // See constructor. - DescriptorDatabase* fallback_database_; - ErrorCollector* default_error_collector_; - const DescriptorPool* underlay_; - - // This class contains a lot of hash maps with complicated types that - // we'd like to keep out of the header. - class Tables; - scoped_ptr tables_; - - bool enforce_dependencies_; - bool allow_unknown_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); -}; - -// inline methods ==================================================== - -// These macros makes this repetitive code more readable. -#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \ - inline TYPE CLASS::FIELD() const { return FIELD##_; } - -// Strings fields are stored as pointers but returned as const references. -#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ - inline const string& CLASS::FIELD() const { return *FIELD##_; } - -// Arrays take an index parameter, obviously. -#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ - inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } - -#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ - inline const TYPE& CLASS::options() const { return *options_; } - -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) - -PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) - -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*) - -PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range, - const Descriptor::ExtensionRange*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, - const FieldDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key, - const FieldDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions); -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum, - const EnumValueDescriptor*) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) - -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, - const EnumValueDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) -PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, - const MethodDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions); - -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service, - const ServiceDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, - const FieldDescriptor*) - -#undef PROTOBUF_DEFINE_ACCESSOR -#undef PROTOBUF_DEFINE_STRING_ACCESSOR -#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR - -// A few accessors differ from the macros... - -inline bool FieldDescriptor::is_required() const { - return label() == LABEL_REQUIRED; -} - -inline bool FieldDescriptor::is_optional() const { - return label() == LABEL_OPTIONAL; -} - -inline bool FieldDescriptor::is_repeated() const { - return label() == LABEL_REPEATED; -} - -inline bool FieldDescriptor::is_packable() const { - return is_repeated() && IsTypePackable(type()); -} - -// To save space, index() is computed by looking at the descriptor's position -// in the parent's array of children. -inline int FieldDescriptor::index() const { - if (!is_extension_) { - return this - containing_type_->fields_; - } else if (extension_scope_ != NULL) { - return this - extension_scope_->extensions_; - } else { - return this - file_->extensions_; - } -} - -inline int Descriptor::index() const { - if (containing_type_ == NULL) { - return this - file_->message_types_; - } else { - return this - containing_type_->nested_types_; - } -} - -inline int EnumDescriptor::index() const { - if (containing_type_ == NULL) { - return this - file_->enum_types_; - } else { - return this - containing_type_->enum_types_; - } -} - -inline int EnumValueDescriptor::index() const { - return this - type_->values_; -} - -inline int ServiceDescriptor::index() const { - return this - file_->services_; -} - -inline int MethodDescriptor::index() const { - return this - service_->methods_; -} - -inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { - return kTypeToCppTypeMap[type_]; -} - -inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { - return kTypeToCppTypeMap[type]; -} - -inline bool FieldDescriptor::IsTypePackable(Type field_type) { - return (field_type != FieldDescriptor::TYPE_STRING && - field_type != FieldDescriptor::TYPE_GROUP && - field_type != FieldDescriptor::TYPE_MESSAGE && - field_type != FieldDescriptor::TYPE_BYTES); -} - -inline const FileDescriptor* FileDescriptor::dependency(int index) const { - return dependencies_[index]; -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__ diff --git a/Resources/NetHook/google/protobuf/descriptor.pb.cc b/Resources/NetHook/google/protobuf/descriptor.pb.cc deleted file mode 100644 index f61e7cd0..00000000 --- a/Resources/NetHook/google/protobuf/descriptor.pb.cc +++ /dev/null @@ -1,7029 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "google/protobuf/descriptor.pb.h" -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace google { -namespace protobuf { - -namespace { - -const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileDescriptorSet_reflection_ = NULL; -const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - DescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - DescriptorProto_ExtensionRange_reflection_ = NULL; -const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FieldDescriptorProto_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL; -const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumValueDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - ServiceDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MethodDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileOptions_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL; -const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MessageOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FieldOptions_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL; -const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumValueOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - ServiceOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MethodOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - UninterpretedOption_reflection_ = NULL; -const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - UninterpretedOption_NamePart_reflection_ = NULL; - -} // namespace - - -void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { - protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - const ::google::protobuf::FileDescriptor* file = - ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "google/protobuf/descriptor.proto"); - GOOGLE_CHECK(file != NULL); - FileDescriptorSet_descriptor_ = file->message_type(0); - static const int FileDescriptorSet_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_), - }; - FileDescriptorSet_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileDescriptorSet_descriptor_, - FileDescriptorSet::default_instance_, - FileDescriptorSet_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(FileDescriptorSet)); - FileDescriptorProto_descriptor_ = file->message_type(1); - static const int FileDescriptorProto_offsets_[8] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_), - }; - FileDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileDescriptorProto_descriptor_, - FileDescriptorProto::default_instance_, - FileDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(FileDescriptorProto)); - DescriptorProto_descriptor_ = file->message_type(2); - static const int DescriptorProto_offsets_[7] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_), - }; - DescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - DescriptorProto_descriptor_, - DescriptorProto::default_instance_, - DescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(DescriptorProto)); - DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0); - static const int DescriptorProto_ExtensionRange_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_), - }; - DescriptorProto_ExtensionRange_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - DescriptorProto_ExtensionRange_descriptor_, - DescriptorProto_ExtensionRange::default_instance_, - DescriptorProto_ExtensionRange_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(DescriptorProto_ExtensionRange)); - FieldDescriptorProto_descriptor_ = file->message_type(3); - static const int FieldDescriptorProto_offsets_[8] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_), - }; - FieldDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FieldDescriptorProto_descriptor_, - FieldDescriptorProto::default_instance_, - FieldDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(FieldDescriptorProto)); - FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0); - FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1); - EnumDescriptorProto_descriptor_ = file->message_type(4); - static const int EnumDescriptorProto_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_), - }; - EnumDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumDescriptorProto_descriptor_, - EnumDescriptorProto::default_instance_, - EnumDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(EnumDescriptorProto)); - EnumValueDescriptorProto_descriptor_ = file->message_type(5); - static const int EnumValueDescriptorProto_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_), - }; - EnumValueDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumValueDescriptorProto_descriptor_, - EnumValueDescriptorProto::default_instance_, - EnumValueDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(EnumValueDescriptorProto)); - ServiceDescriptorProto_descriptor_ = file->message_type(6); - static const int ServiceDescriptorProto_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_), - }; - ServiceDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - ServiceDescriptorProto_descriptor_, - ServiceDescriptorProto::default_instance_, - ServiceDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(ServiceDescriptorProto)); - MethodDescriptorProto_descriptor_ = file->message_type(7); - static const int MethodDescriptorProto_offsets_[4] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_), - }; - MethodDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MethodDescriptorProto_descriptor_, - MethodDescriptorProto::default_instance_, - MethodDescriptorProto_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(MethodDescriptorProto)); - FileOptions_descriptor_ = file->message_type(8); - static const int FileOptions_offsets_[8] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_), - }; - FileOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileOptions_descriptor_, - FileOptions::default_instance_, - FileOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(FileOptions)); - FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0); - MessageOptions_descriptor_ = file->message_type(9); - static const int MessageOptions_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_), - }; - MessageOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MessageOptions_descriptor_, - MessageOptions::default_instance_, - MessageOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(MessageOptions)); - FieldOptions_descriptor_ = file->message_type(10); - static const int FieldOptions_offsets_[5] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_), - }; - FieldOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FieldOptions_descriptor_, - FieldOptions::default_instance_, - FieldOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(FieldOptions)); - FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); - EnumOptions_descriptor_ = file->message_type(11); - static const int EnumOptions_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_), - }; - EnumOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumOptions_descriptor_, - EnumOptions::default_instance_, - EnumOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(EnumOptions)); - EnumValueOptions_descriptor_ = file->message_type(12); - static const int EnumValueOptions_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_), - }; - EnumValueOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumValueOptions_descriptor_, - EnumValueOptions::default_instance_, - EnumValueOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(EnumValueOptions)); - ServiceOptions_descriptor_ = file->message_type(13); - static const int ServiceOptions_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_), - }; - ServiceOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - ServiceOptions_descriptor_, - ServiceOptions::default_instance_, - ServiceOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(ServiceOptions)); - MethodOptions_descriptor_ = file->message_type(14); - static const int MethodOptions_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_), - }; - MethodOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MethodOptions_descriptor_, - MethodOptions::default_instance_, - MethodOptions_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_), - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(MethodOptions)); - UninterpretedOption_descriptor_ = file->message_type(15); - static const int UninterpretedOption_offsets_[6] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_), - }; - UninterpretedOption_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - UninterpretedOption_descriptor_, - UninterpretedOption::default_instance_, - UninterpretedOption_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(UninterpretedOption)); - UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0); - static const int UninterpretedOption_NamePart_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_), - }; - UninterpretedOption_NamePart_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - UninterpretedOption_NamePart_descriptor_, - UninterpretedOption_NamePart::default_instance_, - UninterpretedOption_NamePart_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(UninterpretedOption_NamePart)); -} - -namespace { - -GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); -inline void protobuf_AssignDescriptorsOnce() { - ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto); -} - -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - DescriptorProto_descriptor_, &DescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileOptions_descriptor_, &FileOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MessageOptions_descriptor_, &MessageOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FieldOptions_descriptor_, &FieldOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumOptions_descriptor_, &EnumOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumValueOptions_descriptor_, &EnumValueOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - ServiceOptions_descriptor_, &ServiceOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MethodOptions_descriptor_, &MethodOptions::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - UninterpretedOption_descriptor_, &UninterpretedOption::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance()); -} - -} // namespace - -void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() { - delete FileDescriptorSet::default_instance_; - delete FileDescriptorSet_reflection_; - delete FileDescriptorProto::default_instance_; - delete FileDescriptorProto_reflection_; - delete DescriptorProto::default_instance_; - delete DescriptorProto_reflection_; - delete DescriptorProto_ExtensionRange::default_instance_; - delete DescriptorProto_ExtensionRange_reflection_; - delete FieldDescriptorProto::default_instance_; - delete FieldDescriptorProto_reflection_; - delete EnumDescriptorProto::default_instance_; - delete EnumDescriptorProto_reflection_; - delete EnumValueDescriptorProto::default_instance_; - delete EnumValueDescriptorProto_reflection_; - delete ServiceDescriptorProto::default_instance_; - delete ServiceDescriptorProto_reflection_; - delete MethodDescriptorProto::default_instance_; - delete MethodDescriptorProto_reflection_; - delete FileOptions::default_instance_; - delete FileOptions_reflection_; - delete MessageOptions::default_instance_; - delete MessageOptions_reflection_; - delete FieldOptions::default_instance_; - delete FieldOptions_reflection_; - delete EnumOptions::default_instance_; - delete EnumOptions_reflection_; - delete EnumValueOptions::default_instance_; - delete EnumValueOptions_reflection_; - delete ServiceOptions::default_instance_; - delete ServiceOptions_reflection_; - delete MethodOptions::default_instance_; - delete MethodOptions_reflection_; - delete UninterpretedOption::default_instance_; - delete UninterpretedOption_reflection_; - delete UninterpretedOption_NamePart::default_instance_; - delete UninterpretedOption_NamePart_reflection_; -} - -void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n google/protobuf/descriptor.proto\022\017goog" - "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" - "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" - "roto\"\334\002\n\023FileDescriptorProto\022\014\n\004name\030\001 \001" - "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022" - "6\n\014message_type\030\004 \003(\0132 .google.protobuf." - "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo" - "gle.protobuf.EnumDescriptorProto\0228\n\007serv" - "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr" - "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p" - "rotobuf.FieldDescriptorProto\022-\n\007options\030" - "\010 \001(\0132\034.google.protobuf.FileOptions\"\251\003\n\017" - "DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002" - " \003(\0132%.google.protobuf.FieldDescriptorPr" - "oto\0228\n\textension\030\006 \003(\0132%.google.protobuf" - ".FieldDescriptorProto\0225\n\013nested_type\030\003 \003" - "(\0132 .google.protobuf.DescriptorProto\0227\n\t" - "enum_type\030\004 \003(\0132$.google.protobuf.EnumDe" - "scriptorProto\022H\n\017extension_range\030\005 \003(\0132/" - ".google.protobuf.DescriptorProto.Extensi" - "onRange\0220\n\007options\030\007 \001(\0132\037.google.protob" - "uf.MessageOptions\032,\n\016ExtensionRange\022\r\n\005s" - "tart\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescrip" - "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:" - "\n\005label\030\004 \001(\0162+.google.protobuf.FieldDes" - "criptorProto.Label\0228\n\004type\030\005 \001(\0162*.googl" - "e.protobuf.FieldDescriptorProto.Type\022\021\n\t" - "type_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdef" - "ault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.goog" - "le.protobuf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYP" - "E_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64" - "\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014T" - "YPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_" - "BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022" - "\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYP" - "E_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED" - "32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021" - "\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTI" - "ONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPE" - "ATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n\004name\030\001" - " \001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.En" - "umValueDescriptorProto\022-\n\007options\030\003 \001(\0132" - "\034.google.protobuf.EnumOptions\"l\n\030EnumVal" - "ueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numbe" - "r\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.protob" - "uf.EnumValueOptions\"\220\001\n\026ServiceDescripto" - "rProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.g" - "oogle.protobuf.MethodDescriptorProto\0220\n\007" - "options\030\003 \001(\0132\037.google.protobuf.ServiceO" - "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030" - "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type" - "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu" - "f.MethodOptions\"\244\003\n\013FileOptions\022\024\n\014java_" - "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 " - "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022" - "F\n\014optimize_for\030\t \001(\0162).google.protobuf." - "FileOptions.OptimizeMode:\005SPEED\022!\n\023cc_ge" - "neric_services\030\020 \001(\010:\004true\022#\n\025java_gener" - "ic_services\030\021 \001(\010:\004true\022!\n\023py_generic_se" - "rvices\030\022 \001(\010:\004true\022C\n\024uninterpreted_opti" - "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete" - "dOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCO" - "DE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270" - "\001\n\016MessageOptions\022&\n\027message_set_wire_fo" - "rmat\030\001 \001(\010:\005false\022.\n\037no_standard_descrip" - "tor_accessor\030\002 \001(\010:\005false\022C\n\024uninterpret" - "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint" - "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptio" - "ns\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Fiel" - "dOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031" - "\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experimenta" - "l_map_key\030\t \001(\t\022C\n\024uninterpreted_option\030" - "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" - "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S" - "TRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022" - "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." - "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"" - "b\n\020EnumValueOptions\022C\n\024uninterpreted_opt" - "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret" - "edOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n" - "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr" - "otobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n" - "\rMethodOptions\022C\n\024uninterpreted_option\030\347" - "\007 \003(\0132$.google.protobuf.UninterpretedOpt" - "ion*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;" - "\n\004name\030\002 \003(\0132-.google.protobuf.Uninterpr" - "etedOption.NamePart\022\030\n\020identifier_value\030" - "\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022neg" - "ative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 " - "\001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n" - "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)" - "\n\023com.google.protobufB\020DescriptorProtosH" - "\001", 3681); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); - FileDescriptorSet::default_instance_ = new FileDescriptorSet(); - FileDescriptorProto::default_instance_ = new FileDescriptorProto(); - DescriptorProto::default_instance_ = new DescriptorProto(); - DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange(); - FieldDescriptorProto::default_instance_ = new FieldDescriptorProto(); - EnumDescriptorProto::default_instance_ = new EnumDescriptorProto(); - EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto(); - ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto(); - MethodDescriptorProto::default_instance_ = new MethodDescriptorProto(); - FileOptions::default_instance_ = new FileOptions(); - MessageOptions::default_instance_ = new MessageOptions(); - FieldOptions::default_instance_ = new FieldOptions(); - EnumOptions::default_instance_ = new EnumOptions(); - EnumValueOptions::default_instance_ = new EnumValueOptions(); - ServiceOptions::default_instance_ = new ServiceOptions(); - MethodOptions::default_instance_ = new MethodOptions(); - UninterpretedOption::default_instance_ = new UninterpretedOption(); - UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart(); - FileDescriptorSet::default_instance_->InitAsDefaultInstance(); - FileDescriptorProto::default_instance_->InitAsDefaultInstance(); - DescriptorProto::default_instance_->InitAsDefaultInstance(); - DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance(); - FieldDescriptorProto::default_instance_->InitAsDefaultInstance(); - EnumDescriptorProto::default_instance_->InitAsDefaultInstance(); - EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance(); - ServiceDescriptorProto::default_instance_->InitAsDefaultInstance(); - MethodDescriptorProto::default_instance_->InitAsDefaultInstance(); - FileOptions::default_instance_->InitAsDefaultInstance(); - MessageOptions::default_instance_->InitAsDefaultInstance(); - FieldOptions::default_instance_->InitAsDefaultInstance(); - EnumOptions::default_instance_->InitAsDefaultInstance(); - EnumValueOptions::default_instance_->InitAsDefaultInstance(); - ServiceOptions::default_instance_->InitAsDefaultInstance(); - MethodOptions::default_instance_->InitAsDefaultInstance(); - UninterpretedOption::default_instance_->InitAsDefaultInstance(); - UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto); -} - -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { - StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() { - protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - } -} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_; - - -// =================================================================== - -#ifndef _MSC_VER -const int FileDescriptorSet::kFileFieldNumber; -#endif // !_MSC_VER - -FileDescriptorSet::FileDescriptorSet() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void FileDescriptorSet::InitAsDefaultInstance() { -} - -FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void FileDescriptorSet::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -FileDescriptorSet::~FileDescriptorSet() { - SharedDtor(); -} - -void FileDescriptorSet::SharedDtor() { - if (this != default_instance_) { - } -} - -void FileDescriptorSet::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { - protobuf_AssignDescriptorsOnce(); - return FileDescriptorSet_descriptor_; -} - -const FileDescriptorSet& FileDescriptorSet::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL; - -FileDescriptorSet* FileDescriptorSet::New() const { - return new FileDescriptorSet; -} - -void FileDescriptorSet::Clear() { - file_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileDescriptorSet::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.FileDescriptorProto file = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_file: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_file())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(10)) goto parse_file; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void FileDescriptorSet::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.FileDescriptorProto file = 1; - for (int i = 0; i < this->file_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, this->file(i), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.FileDescriptorProto file = 1; - for (int i = 0; i < this->file_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->file(i), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int FileDescriptorSet::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.FileDescriptorProto file = 1; - total_size += 1 * this->file_size(); - for (int i = 0; i < this->file_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->file(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileDescriptorSet* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { - GOOGLE_CHECK_NE(&from, this); - file_.MergeFrom(from.file_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileDescriptorSet::IsInitialized() const { - - for (int i = 0; i < file_size(); i++) { - if (!this->file(i).IsInitialized()) return false; - } - return true; -} - -void FileDescriptorSet::Swap(FileDescriptorSet* other) { - if (other != this) { - file_.Swap(&other->file_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = FileDescriptorSet_descriptor_; - metadata.reflection = FileDescriptorSet_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string FileDescriptorProto::_default_name_; -const ::std::string FileDescriptorProto::_default_package_; -#ifndef _MSC_VER -const int FileDescriptorProto::kNameFieldNumber; -const int FileDescriptorProto::kPackageFieldNumber; -const int FileDescriptorProto::kDependencyFieldNumber; -const int FileDescriptorProto::kMessageTypeFieldNumber; -const int FileDescriptorProto::kEnumTypeFieldNumber; -const int FileDescriptorProto::kServiceFieldNumber; -const int FileDescriptorProto::kExtensionFieldNumber; -const int FileDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -FileDescriptorProto::FileDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void FileDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); -} - -FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void FileDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - package_ = const_cast< ::std::string*>(&_default_package_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -FileDescriptorProto::~FileDescriptorProto() { - SharedDtor(); -} - -void FileDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (package_ != &_default_package_) { - delete package_; - } - if (this != default_instance_) { - delete options_; - } -} - -void FileDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return FileDescriptorProto_descriptor_; -} - -const FileDescriptorProto& FileDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL; - -FileDescriptorProto* FileDescriptorProto::New() const { - return new FileDescriptorProto; -} - -void FileDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(1)) { - if (package_ != &_default_package_) { - package_->clear(); - } - } - if (_has_bit(7)) { - if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); - } - } - dependency_.Clear(); - message_type_.Clear(); - enum_type_.Clear(); - service_.Clear(); - extension_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_package; - break; - } - - // optional string package = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_package: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_package())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->package().data(), this->package().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(26)) goto parse_dependency; - break; - } - - // repeated string dependency = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_dependency: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->add_dependency())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->dependency(0).data(), this->dependency(0).length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(26)) goto parse_dependency; - if (input->ExpectTag(34)) goto parse_message_type; - break; - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_message_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_message_type())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(34)) goto parse_message_type; - if (input->ExpectTag(42)) goto parse_enum_type; - break; - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_enum_type())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(42)) goto parse_enum_type; - if (input->ExpectTag(50)) goto parse_service; - break; - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_service: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_service())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(50)) goto parse_service; - if (input->ExpectTag(58)) goto parse_extension; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(58)) goto parse_extension; - if (input->ExpectTag(66)) goto parse_options; - break; - } - - // optional .google.protobuf.FileOptions options = 8; - case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void FileDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // optional string package = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->package().data(), this->package().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 2, this->package(), output); - } - - // repeated string dependency = 3; - for (int i = 0; i < this->dependency_size(); i++) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->dependency(i).data(), this->dependency(i).length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 3, this->dependency(i), output); - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - for (int i = 0; i < this->message_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 4, this->message_type(i), output); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 5, this->enum_type(i), output); - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - for (int i = 0; i < this->service_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 6, this->service(i), output); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 7, this->extension(i), output); - } - - // optional .google.protobuf.FileOptions options = 8; - if (_has_bit(7)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 8, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional string package = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->package().data(), this->package().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 2, this->package(), target); - } - - // repeated string dependency = 3; - for (int i = 0; i < this->dependency_size(); i++) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->dependency(i).data(), this->dependency(i).length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = ::google::protobuf::internal::WireFormatLite:: - WriteStringToArray(3, this->dependency(i), target); - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - for (int i = 0; i < this->message_type_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->message_type(i), target); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - for (int i = 0; i < this->enum_type_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, this->enum_type(i), target); - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - for (int i = 0; i < this->service_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->service(i), target); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - for (int i = 0; i < this->extension_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, this->extension(i), target); - } - - // optional .google.protobuf.FileOptions options = 8; - if (_has_bit(7)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 8, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int FileDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional string package = 2; - if (has_package()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->package()); - } - - // optional .google.protobuf.FileOptions options = 8; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated string dependency = 3; - total_size += 1 * this->dependency_size(); - for (int i = 0; i < this->dependency_size(); i++) { - total_size += ::google::protobuf::internal::WireFormatLite::StringSize( - this->dependency(i)); - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - total_size += 1 * this->message_type_size(); - for (int i = 0; i < this->message_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->message_type(i)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - total_size += 1 * this->enum_type_size(); - for (int i = 0; i < this->enum_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->enum_type(i)); - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - total_size += 1 * this->service_size(); - for (int i = 0; i < this->service_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->service(i)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - total_size += 1 * this->extension_size(); - for (int i = 0; i < this->extension_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->extension(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - dependency_.MergeFrom(from.dependency_); - message_type_.MergeFrom(from.message_type_); - enum_type_.MergeFrom(from.enum_type_); - service_.MergeFrom(from.service_); - extension_.MergeFrom(from.extension_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_package(from.package()); - } - if (from._has_bit(7)) { - mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileDescriptorProto::IsInitialized() const { - - for (int i = 0; i < message_type_size(); i++) { - if (!this->message_type(i).IsInitialized()) return false; - } - for (int i = 0; i < enum_type_size(); i++) { - if (!this->enum_type(i).IsInitialized()) return false; - } - for (int i = 0; i < service_size(); i++) { - if (!this->service(i).IsInitialized()) return false; - } - for (int i = 0; i < extension_size(); i++) { - if (!this->extension(i).IsInitialized()) return false; - } - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void FileDescriptorProto::Swap(FileDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - std::swap(package_, other->package_); - dependency_.Swap(&other->dependency_); - message_type_.Swap(&other->message_type_); - enum_type_.Swap(&other->enum_type_); - service_.Swap(&other->service_); - extension_.Swap(&other->extension_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = FileDescriptorProto_descriptor_; - metadata.reflection = FileDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int DescriptorProto_ExtensionRange::kStartFieldNumber; -const int DescriptorProto_ExtensionRange::kEndFieldNumber; -#endif // !_MSC_VER - -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { -} - -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void DescriptorProto_ExtensionRange::SharedCtor() { - _cached_size_ = 0; - start_ = 0; - end_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { - SharedDtor(); -} - -void DescriptorProto_ExtensionRange::SharedDtor() { - if (this != default_instance_) { - } -} - -void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() { - protobuf_AssignDescriptorsOnce(); - return DescriptorProto_ExtensionRange_descriptor_; -} - -const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL; - -DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const { - return new DescriptorProto_ExtensionRange; -} - -void DescriptorProto_ExtensionRange::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - start_ = 0; - end_ = 0; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional int32 start = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &start_))); - _set_bit(0); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_end; - break; - } - - // optional int32 end = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_end: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &end_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional int32 start = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); - } - - // optional int32 end = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional int32 start = 1; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); - } - - // optional int32 end = 2; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int DescriptorProto_ExtensionRange::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional int32 start = 1; - if (has_start()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->start()); - } - - // optional int32 end = 2; - if (has_end()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->end()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const DescriptorProto_ExtensionRange* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_start(from.start()); - } - if (from._has_bit(1)) { - set_end(from.end()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DescriptorProto_ExtensionRange::IsInitialized() const { - - return true; -} - -void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) { - if (other != this) { - std::swap(start_, other->start_); - std::swap(end_, other->end_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_; - metadata.reflection = DescriptorProto_ExtensionRange_reflection_; - return metadata; -} - - -// ------------------------------------------------------------------- - -const ::std::string DescriptorProto::_default_name_; -#ifndef _MSC_VER -const int DescriptorProto::kNameFieldNumber; -const int DescriptorProto::kFieldFieldNumber; -const int DescriptorProto::kExtensionFieldNumber; -const int DescriptorProto::kNestedTypeFieldNumber; -const int DescriptorProto::kEnumTypeFieldNumber; -const int DescriptorProto::kExtensionRangeFieldNumber; -const int DescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -DescriptorProto::DescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void DescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); -} - -DescriptorProto::DescriptorProto(const DescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void DescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -DescriptorProto::~DescriptorProto() { - SharedDtor(); -} - -void DescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != default_instance_) { - delete options_; - } -} - -void DescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return DescriptorProto_descriptor_; -} - -const DescriptorProto& DescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -DescriptorProto* DescriptorProto::default_instance_ = NULL; - -DescriptorProto* DescriptorProto::New() const { - return new DescriptorProto; -} - -void DescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(6)) { - if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); - } - } - field_.Clear(); - extension_.Clear(); - nested_type_.Clear(); - enum_type_.Clear(); - extension_range_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool DescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_field; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_field: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_field())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_field; - if (input->ExpectTag(26)) goto parse_nested_type; - break; - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_nested_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_nested_type())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(26)) goto parse_nested_type; - if (input->ExpectTag(34)) goto parse_enum_type; - break; - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_enum_type())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(34)) goto parse_enum_type; - if (input->ExpectTag(42)) goto parse_extension_range; - break; - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_extension_range: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension_range())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(42)) goto parse_extension_range; - if (input->ExpectTag(50)) goto parse_extension; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(50)) goto parse_extension; - if (input->ExpectTag(58)) goto parse_options; - break; - } - - // optional .google.protobuf.MessageOptions options = 7; - case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void DescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - for (int i = 0; i < this->field_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, this->field(i), output); - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - for (int i = 0; i < this->nested_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->nested_type(i), output); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 4, this->enum_type(i), output); - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - for (int i = 0; i < this->extension_range_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 5, this->extension_range(i), output); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 6, this->extension(i), output); - } - - // optional .google.protobuf.MessageOptions options = 7; - if (_has_bit(6)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 7, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - for (int i = 0; i < this->field_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->field(i), target); - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - for (int i = 0; i < this->nested_type_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->nested_type(i), target); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - for (int i = 0; i < this->enum_type_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->enum_type(i), target); - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - for (int i = 0; i < this->extension_range_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, this->extension_range(i), target); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - for (int i = 0; i < this->extension_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, this->extension(i), target); - } - - // optional .google.protobuf.MessageOptions options = 7; - if (_has_bit(6)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int DescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional .google.protobuf.MessageOptions options = 7; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.FieldDescriptorProto field = 2; - total_size += 1 * this->field_size(); - for (int i = 0; i < this->field_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->field(i)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - total_size += 1 * this->extension_size(); - for (int i = 0; i < this->extension_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->extension(i)); - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - total_size += 1 * this->nested_type_size(); - for (int i = 0; i < this->nested_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->nested_type(i)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - total_size += 1 * this->enum_type_size(); - for (int i = 0; i < this->enum_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->enum_type(i)); - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - total_size += 1 * this->extension_range_size(); - for (int i = 0; i < this->extension_range_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->extension_range(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const DescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void DescriptorProto::MergeFrom(const DescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - field_.MergeFrom(from.field_); - extension_.MergeFrom(from.extension_); - nested_type_.MergeFrom(from.nested_type_); - enum_type_.MergeFrom(from.enum_type_); - extension_range_.MergeFrom(from.extension_range_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(6)) { - mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void DescriptorProto::CopyFrom(const DescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DescriptorProto::IsInitialized() const { - - for (int i = 0; i < field_size(); i++) { - if (!this->field(i).IsInitialized()) return false; - } - for (int i = 0; i < extension_size(); i++) { - if (!this->extension(i).IsInitialized()) return false; - } - for (int i = 0; i < nested_type_size(); i++) { - if (!this->nested_type(i).IsInitialized()) return false; - } - for (int i = 0; i < enum_type_size(); i++) { - if (!this->enum_type(i).IsInitialized()) return false; - } - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void DescriptorProto::Swap(DescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - field_.Swap(&other->field_); - extension_.Swap(&other->extension_); - nested_type_.Swap(&other->nested_type_); - enum_type_.Swap(&other->enum_type_); - extension_range_.Swap(&other->extension_range_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata DescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = DescriptorProto_descriptor_; - metadata.reflection = DescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { - protobuf_AssignDescriptorsOnce(); - return FieldDescriptorProto_Type_descriptor_; -} -bool FieldDescriptorProto_Type_IsValid(int value) { - switch(value) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64; -const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN; -const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX; -const int FieldDescriptorProto::Type_ARRAYSIZE; -#endif // _MSC_VER -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() { - protobuf_AssignDescriptorsOnce(); - return FieldDescriptorProto_Label_descriptor_; -} -bool FieldDescriptorProto_Label_IsValid(int value) { - switch(value) { - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL; -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED; -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED; -const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; -const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; -const int FieldDescriptorProto::Label_ARRAYSIZE; -#endif // _MSC_VER -const ::std::string FieldDescriptorProto::_default_name_; -const ::std::string FieldDescriptorProto::_default_type_name_; -const ::std::string FieldDescriptorProto::_default_extendee_; -const ::std::string FieldDescriptorProto::_default_default_value_; -#ifndef _MSC_VER -const int FieldDescriptorProto::kNameFieldNumber; -const int FieldDescriptorProto::kNumberFieldNumber; -const int FieldDescriptorProto::kLabelFieldNumber; -const int FieldDescriptorProto::kTypeFieldNumber; -const int FieldDescriptorProto::kTypeNameFieldNumber; -const int FieldDescriptorProto::kExtendeeFieldNumber; -const int FieldDescriptorProto::kDefaultValueFieldNumber; -const int FieldDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -FieldDescriptorProto::FieldDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void FieldDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); -} - -FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void FieldDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - number_ = 0; - label_ = 1; - type_ = 1; - type_name_ = const_cast< ::std::string*>(&_default_type_name_); - extendee_ = const_cast< ::std::string*>(&_default_extendee_); - default_value_ = const_cast< ::std::string*>(&_default_default_value_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -FieldDescriptorProto::~FieldDescriptorProto() { - SharedDtor(); -} - -void FieldDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (type_name_ != &_default_type_name_) { - delete type_name_; - } - if (extendee_ != &_default_extendee_) { - delete extendee_; - } - if (default_value_ != &_default_default_value_) { - delete default_value_; - } - if (this != default_instance_) { - delete options_; - } -} - -void FieldDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return FieldDescriptorProto_descriptor_; -} - -const FieldDescriptorProto& FieldDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL; - -FieldDescriptorProto* FieldDescriptorProto::New() const { - return new FieldDescriptorProto; -} - -void FieldDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - number_ = 0; - label_ = 1; - type_ = 1; - if (_has_bit(4)) { - if (type_name_ != &_default_type_name_) { - type_name_->clear(); - } - } - if (_has_bit(5)) { - if (extendee_ != &_default_extendee_) { - extendee_->clear(); - } - } - if (_has_bit(6)) { - if (default_value_ != &_default_default_value_) { - default_value_->clear(); - } - } - if (_has_bit(7)) { - if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FieldDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_extendee; - break; - } - - // optional string extendee = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_extendee: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_extendee())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extendee().data(), this->extendee().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(24)) goto parse_number; - break; - } - - // optional int32 number = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_number: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &number_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(32)) goto parse_label; - break; - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_label: - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { - set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); - } else { - mutable_unknown_fields()->AddVarint(4, value); - } - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(40)) goto parse_type; - break; - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_type: - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { - set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); - } else { - mutable_unknown_fields()->AddVarint(5, value); - } - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(50)) goto parse_type_name; - break; - } - - // optional string type_name = 6; - case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_type_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_type_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->type_name().data(), this->type_name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(58)) goto parse_default_value; - break; - } - - // optional string default_value = 7; - case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_default_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_default_value())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->default_value().data(), this->default_value().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(66)) goto parse_options; - break; - } - - // optional .google.protobuf.FieldOptions options = 8; - case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void FieldDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // optional string extendee = 2; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extendee().data(), this->extendee().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 2, this->extendee(), output); - } - - // optional int32 number = 3; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 4, this->label(), output); - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 5, this->type(), output); - } - - // optional string type_name = 6; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->type_name().data(), this->type_name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 6, this->type_name(), output); - } - - // optional string default_value = 7; - if (_has_bit(6)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->default_value().data(), this->default_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 7, this->default_value(), output); - } - - // optional .google.protobuf.FieldOptions options = 8; - if (_has_bit(7)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 8, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional string extendee = 2; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extendee().data(), this->extendee().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 2, this->extendee(), target); - } - - // optional int32 number = 3; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 4, this->label(), target); - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 5, this->type(), target); - } - - // optional string type_name = 6; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->type_name().data(), this->type_name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 6, this->type_name(), target); - } - - // optional string default_value = 7; - if (_has_bit(6)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->default_value().data(), this->default_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 7, this->default_value(), target); - } - - // optional .google.protobuf.FieldOptions options = 8; - if (_has_bit(7)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 8, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int FieldDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional int32 number = 3; - if (has_number()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->number()); - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (has_label()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->label()); - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (has_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); - } - - // optional string type_name = 6; - if (has_type_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->type_name()); - } - - // optional string extendee = 2; - if (has_extendee()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->extendee()); - } - - // optional string default_value = 7; - if (has_default_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->default_value()); - } - - // optional .google.protobuf.FieldOptions options = 8; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FieldDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_number(from.number()); - } - if (from._has_bit(2)) { - set_label(from.label()); - } - if (from._has_bit(3)) { - set_type(from.type()); - } - if (from._has_bit(4)) { - set_type_name(from.type_name()); - } - if (from._has_bit(5)) { - set_extendee(from.extendee()); - } - if (from._has_bit(6)) { - set_default_value(from.default_value()); - } - if (from._has_bit(7)) { - mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FieldDescriptorProto::IsInitialized() const { - - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - std::swap(number_, other->number_); - std::swap(label_, other->label_); - std::swap(type_, other->type_); - std::swap(type_name_, other->type_name_); - std::swap(extendee_, other->extendee_); - std::swap(default_value_, other->default_value_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = FieldDescriptorProto_descriptor_; - metadata.reflection = FieldDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string EnumDescriptorProto::_default_name_; -#ifndef _MSC_VER -const int EnumDescriptorProto::kNameFieldNumber; -const int EnumDescriptorProto::kValueFieldNumber; -const int EnumDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -EnumDescriptorProto::EnumDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void EnumDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); -} - -EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void EnumDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -EnumDescriptorProto::~EnumDescriptorProto() { - SharedDtor(); -} - -void EnumDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != default_instance_) { - delete options_; - } -} - -void EnumDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return EnumDescriptorProto_descriptor_; -} - -const EnumDescriptorProto& EnumDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL; - -EnumDescriptorProto* EnumDescriptorProto::New() const { - return new EnumDescriptorProto; -} - -void EnumDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); - } - } - value_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_value; - break; - } - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_value())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_value; - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.EnumOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void EnumDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - for (int i = 0; i < this->value_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, this->value(i), output); - } - - // optional .google.protobuf.EnumOptions options = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - for (int i = 0; i < this->value_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->value(i), target); - } - - // optional .google.protobuf.EnumOptions options = 3; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int EnumDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional .google.protobuf.EnumOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - total_size += 1 * this->value_size(); - for (int i = 0; i < this->value_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->value(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - value_.MergeFrom(from.value_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumDescriptorProto::IsInitialized() const { - - for (int i = 0; i < value_size(); i++) { - if (!this->value(i).IsInitialized()) return false; - } - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - value_.Swap(&other->value_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = EnumDescriptorProto_descriptor_; - metadata.reflection = EnumDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string EnumValueDescriptorProto::_default_name_; -#ifndef _MSC_VER -const int EnumValueDescriptorProto::kNameFieldNumber; -const int EnumValueDescriptorProto::kNumberFieldNumber; -const int EnumValueDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -EnumValueDescriptorProto::EnumValueDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void EnumValueDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); -} - -EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void EnumValueDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - number_ = 0; - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -EnumValueDescriptorProto::~EnumValueDescriptorProto() { - SharedDtor(); -} - -void EnumValueDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != default_instance_) { - delete options_; - } -} - -void EnumValueDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return EnumValueDescriptorProto_descriptor_; -} - -const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL; - -EnumValueDescriptorProto* EnumValueDescriptorProto::New() const { - return new EnumValueDescriptorProto; -} - -void EnumValueDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - number_ = 0; - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumValueDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_number; - break; - } - - // optional int32 number = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_number: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &number_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.EnumValueOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void EnumValueDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // optional int32 number = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); - } - - // optional .google.protobuf.EnumValueOptions options = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional int32 number = 2; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); - } - - // optional .google.protobuf.EnumValueOptions options = 3; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int EnumValueDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional int32 number = 2; - if (has_number()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->number()); - } - - // optional .google.protobuf.EnumValueOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumValueDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_number(from.number()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumValueDescriptorProto::IsInitialized() const { - - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - std::swap(number_, other->number_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = EnumValueDescriptorProto_descriptor_; - metadata.reflection = EnumValueDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string ServiceDescriptorProto::_default_name_; -#ifndef _MSC_VER -const int ServiceDescriptorProto::kNameFieldNumber; -const int ServiceDescriptorProto::kMethodFieldNumber; -const int ServiceDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -ServiceDescriptorProto::ServiceDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void ServiceDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); -} - -ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void ServiceDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -ServiceDescriptorProto::~ServiceDescriptorProto() { - SharedDtor(); -} - -void ServiceDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != default_instance_) { - delete options_; - } -} - -void ServiceDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return ServiceDescriptorProto_descriptor_; -} - -const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL; - -ServiceDescriptorProto* ServiceDescriptorProto::New() const { - return new ServiceDescriptorProto; -} - -void ServiceDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); - } - } - method_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool ServiceDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_method; - break; - } - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_method: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_method())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_method; - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.ServiceOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void ServiceDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - for (int i = 0; i < this->method_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, this->method(i), output); - } - - // optional .google.protobuf.ServiceOptions options = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - for (int i = 0; i < this->method_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->method(i), target); - } - - // optional .google.protobuf.ServiceOptions options = 3; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 3, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int ServiceDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional .google.protobuf.ServiceOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.MethodDescriptorProto method = 2; - total_size += 1 * this->method_size(); - for (int i = 0; i < this->method_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->method(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const ServiceDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - method_.MergeFrom(from.method_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool ServiceDescriptorProto::IsInitialized() const { - - for (int i = 0; i < method_size(); i++) { - if (!this->method(i).IsInitialized()) return false; - } - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - method_.Swap(&other->method_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = ServiceDescriptorProto_descriptor_; - metadata.reflection = ServiceDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string MethodDescriptorProto::_default_name_; -const ::std::string MethodDescriptorProto::_default_input_type_; -const ::std::string MethodDescriptorProto::_default_output_type_; -#ifndef _MSC_VER -const int MethodDescriptorProto::kNameFieldNumber; -const int MethodDescriptorProto::kInputTypeFieldNumber; -const int MethodDescriptorProto::kOutputTypeFieldNumber; -const int MethodDescriptorProto::kOptionsFieldNumber; -#endif // !_MSC_VER - -MethodDescriptorProto::MethodDescriptorProto() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void MethodDescriptorProto::InitAsDefaultInstance() { - options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); -} - -MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void MethodDescriptorProto::SharedCtor() { - _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - input_type_ = const_cast< ::std::string*>(&_default_input_type_); - output_type_ = const_cast< ::std::string*>(&_default_output_type_); - options_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -MethodDescriptorProto::~MethodDescriptorProto() { - SharedDtor(); -} - -void MethodDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { - delete name_; - } - if (input_type_ != &_default_input_type_) { - delete input_type_; - } - if (output_type_ != &_default_output_type_) { - delete output_type_; - } - if (this != default_instance_) { - delete options_; - } -} - -void MethodDescriptorProto::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { - protobuf_AssignDescriptorsOnce(); - return MethodDescriptorProto_descriptor_; -} - -const MethodDescriptorProto& MethodDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL; - -MethodDescriptorProto* MethodDescriptorProto::New() const { - return new MethodDescriptorProto; -} - -void MethodDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(1)) { - if (input_type_ != &_default_input_type_) { - input_type_->clear(); - } - } - if (_has_bit(2)) { - if (output_type_ != &_default_output_type_) { - output_type_->clear(); - } - } - if (_has_bit(3)) { - if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MethodDescriptorProto::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_input_type; - break; - } - - // optional string input_type = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_input_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_input_type())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->input_type().data(), this->input_type().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(26)) goto parse_output_type; - break; - } - - // optional string output_type = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_output_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_output_type())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->output_type().data(), this->output_type().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(34)) goto parse_options; - break; - } - - // optional .google.protobuf.MethodOptions options = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void MethodDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name(), output); - } - - // optional string input_type = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->input_type().data(), this->input_type().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 2, this->input_type(), output); - } - - // optional string output_type = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->output_type().data(), this->output_type().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 3, this->output_type(), output); - } - - // optional .google.protobuf.MethodOptions options = 4; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 4, this->options(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string name = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional string input_type = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->input_type().data(), this->input_type().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 2, this->input_type(), target); - } - - // optional string output_type = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->output_type().data(), this->output_type().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 3, this->output_type(), target); - } - - // optional .google.protobuf.MethodOptions options = 4; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, this->options(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int MethodDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional string input_type = 2; - if (has_input_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->input_type()); - } - - // optional string output_type = 3; - if (has_output_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->output_type()); - } - - // optional .google.protobuf.MethodOptions options = 4; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MethodDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_input_type(from.input_type()); - } - if (from._has_bit(2)) { - set_output_type(from.output_type()); - } - if (from._has_bit(3)) { - mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MethodDescriptorProto::IsInitialized() const { - - if (has_options()) { - if (!this->options().IsInitialized()) return false; - } - return true; -} - -void MethodDescriptorProto::Swap(MethodDescriptorProto* other) { - if (other != this) { - std::swap(name_, other->name_); - std::swap(input_type_, other->input_type_); - std::swap(output_type_, other->output_type_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = MethodDescriptorProto_descriptor_; - metadata.reflection = MethodDescriptorProto_reflection_; - return metadata; -} - - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() { - protobuf_AssignDescriptorsOnce(); - return FileOptions_OptimizeMode_descriptor_; -} -bool FileOptions_OptimizeMode_IsValid(int value) { - switch(value) { - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FileOptions_OptimizeMode FileOptions::SPEED; -const FileOptions_OptimizeMode FileOptions::CODE_SIZE; -const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME; -const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; -const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; -const int FileOptions::OptimizeMode_ARRAYSIZE; -#endif // _MSC_VER -const ::std::string FileOptions::_default_java_package_; -const ::std::string FileOptions::_default_java_outer_classname_; -#ifndef _MSC_VER -const int FileOptions::kJavaPackageFieldNumber; -const int FileOptions::kJavaOuterClassnameFieldNumber; -const int FileOptions::kJavaMultipleFilesFieldNumber; -const int FileOptions::kOptimizeForFieldNumber; -const int FileOptions::kCcGenericServicesFieldNumber; -const int FileOptions::kJavaGenericServicesFieldNumber; -const int FileOptions::kPyGenericServicesFieldNumber; -const int FileOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -FileOptions::FileOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void FileOptions::InitAsDefaultInstance() { -} - -FileOptions::FileOptions(const FileOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void FileOptions::SharedCtor() { - _cached_size_ = 0; - java_package_ = const_cast< ::std::string*>(&_default_java_package_); - java_outer_classname_ = const_cast< ::std::string*>(&_default_java_outer_classname_); - java_multiple_files_ = false; - optimize_for_ = 1; - cc_generic_services_ = true; - java_generic_services_ = true; - py_generic_services_ = true; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -FileOptions::~FileOptions() { - SharedDtor(); -} - -void FileOptions::SharedDtor() { - if (java_package_ != &_default_java_package_) { - delete java_package_; - } - if (java_outer_classname_ != &_default_java_outer_classname_) { - delete java_outer_classname_; - } - if (this != default_instance_) { - } -} - -void FileOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FileOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return FileOptions_descriptor_; -} - -const FileOptions& FileOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -FileOptions* FileOptions::default_instance_ = NULL; - -FileOptions* FileOptions::New() const { - return new FileOptions; -} - -void FileOptions::Clear() { - _extensions_.Clear(); - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (java_package_ != &_default_java_package_) { - java_package_->clear(); - } - } - if (_has_bit(1)) { - if (java_outer_classname_ != &_default_java_outer_classname_) { - java_outer_classname_->clear(); - } - } - java_multiple_files_ = false; - optimize_for_ = 1; - cc_generic_services_ = true; - java_generic_services_ = true; - py_generic_services_ = true; - } - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string java_package = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_java_package())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_package().data(), this->java_package().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(66)) goto parse_java_outer_classname; - break; - } - - // optional string java_outer_classname = 8; - case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_java_outer_classname: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_java_outer_classname())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_outer_classname().data(), this->java_outer_classname().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(72)) goto parse_optimize_for; - break; - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - case 9: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_optimize_for: - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { - set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); - } else { - mutable_unknown_fields()->AddVarint(9, value); - } - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(80)) goto parse_java_multiple_files; - break; - } - - // optional bool java_multiple_files = 10 [default = false]; - case 10: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_java_multiple_files: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &java_multiple_files_))); - _set_bit(2); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(128)) goto parse_cc_generic_services; - break; - } - - // optional bool cc_generic_services = 16 [default = true]; - case 16: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_cc_generic_services: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &cc_generic_services_))); - _set_bit(4); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(136)) goto parse_java_generic_services; - break; - } - - // optional bool java_generic_services = 17 [default = true]; - case 17: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_java_generic_services: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &java_generic_services_))); - _set_bit(5); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(144)) goto parse_py_generic_services; - break; - } - - // optional bool py_generic_services = 18 [default = true]; - case 18: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_py_generic_services: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &py_generic_services_))); - _set_bit(6); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - break; - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void FileOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional string java_package = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_package().data(), this->java_package().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->java_package(), output); - } - - // optional string java_outer_classname = 8; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_outer_classname().data(), this->java_outer_classname().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 8, this->java_outer_classname(), output); - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 9, this->optimize_for(), output); - } - - // optional bool java_multiple_files = 10 [default = false]; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); - } - - // optional bool cc_generic_services = 16 [default = true]; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output); - } - - // optional bool java_generic_services = 17 [default = true]; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output); - } - - // optional bool py_generic_services = 18 [default = true]; - if (_has_bit(6)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional string java_package = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_package().data(), this->java_package().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->java_package(), target); - } - - // optional string java_outer_classname = 8; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_outer_classname().data(), this->java_outer_classname().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 8, this->java_outer_classname(), target); - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 9, this->optimize_for(), target); - } - - // optional bool java_multiple_files = 10 [default = false]; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); - } - - // optional bool cc_generic_services = 16 [default = true]; - if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target); - } - - // optional bool java_generic_services = 17 [default = true]; - if (_has_bit(5)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target); - } - - // optional bool py_generic_services = 18 [default = true]; - if (_has_bit(6)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int FileOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string java_package = 1; - if (has_java_package()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->java_package()); - } - - // optional string java_outer_classname = 8; - if (has_java_outer_classname()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->java_outer_classname()); - } - - // optional bool java_multiple_files = 10 [default = false]; - if (has_java_multiple_files()) { - total_size += 1 + 1; - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (has_optimize_for()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for()); - } - - // optional bool cc_generic_services = 16 [default = true]; - if (has_cc_generic_services()) { - total_size += 2 + 1; - } - - // optional bool java_generic_services = 17 [default = true]; - if (has_java_generic_services()) { - total_size += 2 + 1; - } - - // optional bool py_generic_services = 18 [default = true]; - if (has_py_generic_services()) { - total_size += 2 + 1; - } - - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FileOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileOptions::MergeFrom(const FileOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_java_package(from.java_package()); - } - if (from._has_bit(1)) { - set_java_outer_classname(from.java_outer_classname()); - } - if (from._has_bit(2)) { - set_java_multiple_files(from.java_multiple_files()); - } - if (from._has_bit(3)) { - set_optimize_for(from.optimize_for()); - } - if (from._has_bit(4)) { - set_cc_generic_services(from.cc_generic_services()); - } - if (from._has_bit(5)) { - set_java_generic_services(from.java_generic_services()); - } - if (from._has_bit(6)) { - set_py_generic_services(from.py_generic_services()); - } - } - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileOptions::CopyFrom(const FileOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void FileOptions::Swap(FileOptions* other) { - if (other != this) { - std::swap(java_package_, other->java_package_); - std::swap(java_outer_classname_, other->java_outer_classname_); - std::swap(java_multiple_files_, other->java_multiple_files_); - std::swap(optimize_for_, other->optimize_for_); - std::swap(cc_generic_services_, other->cc_generic_services_); - std::swap(java_generic_services_, other->java_generic_services_); - std::swap(py_generic_services_, other->py_generic_services_); - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata FileOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = FileOptions_descriptor_; - metadata.reflection = FileOptions_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int MessageOptions::kMessageSetWireFormatFieldNumber; -const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber; -const int MessageOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -MessageOptions::MessageOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void MessageOptions::InitAsDefaultInstance() { -} - -MessageOptions::MessageOptions(const MessageOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void MessageOptions::SharedCtor() { - _cached_size_ = 0; - message_set_wire_format_ = false; - no_standard_descriptor_accessor_ = false; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -MessageOptions::~MessageOptions() { - SharedDtor(); -} - -void MessageOptions::SharedDtor() { - if (this != default_instance_) { - } -} - -void MessageOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* MessageOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return MessageOptions_descriptor_; -} - -const MessageOptions& MessageOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -MessageOptions* MessageOptions::default_instance_ = NULL; - -MessageOptions* MessageOptions::New() const { - return new MessageOptions; -} - -void MessageOptions::Clear() { - _extensions_.Clear(); - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - message_set_wire_format_ = false; - no_standard_descriptor_accessor_ = false; - } - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MessageOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional bool message_set_wire_format = 1 [default = false]; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &message_set_wire_format_))); - _set_bit(0); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor; - break; - } - - // optional bool no_standard_descriptor_accessor = 2 [default = false]; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_no_standard_descriptor_accessor: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &no_standard_descriptor_accessor_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - break; - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void MessageOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional bool message_set_wire_format = 1 [default = false]; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); - } - - // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional bool message_set_wire_format = 1 [default = false]; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target); - } - - // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int MessageOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional bool message_set_wire_format = 1 [default = false]; - if (has_message_set_wire_format()) { - total_size += 1 + 1; - } - - // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (has_no_standard_descriptor_accessor()) { - total_size += 1 + 1; - } - - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MessageOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void MessageOptions::MergeFrom(const MessageOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_message_set_wire_format(from.message_set_wire_format()); - } - if (from._has_bit(1)) { - set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor()); - } - } - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MessageOptions::CopyFrom(const MessageOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MessageOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void MessageOptions::Swap(MessageOptions* other) { - if (other != this) { - std::swap(message_set_wire_format_, other->message_set_wire_format_); - std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata MessageOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = MessageOptions_descriptor_; - metadata.reflection = MessageOptions_reflection_; - return metadata; -} - - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() { - protobuf_AssignDescriptorsOnce(); - return FieldOptions_CType_descriptor_; -} -bool FieldOptions_CType_IsValid(int value) { - switch(value) { - case 0: - case 1: - case 2: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldOptions_CType FieldOptions::STRING; -const FieldOptions_CType FieldOptions::CORD; -const FieldOptions_CType FieldOptions::STRING_PIECE; -const FieldOptions_CType FieldOptions::CType_MIN; -const FieldOptions_CType FieldOptions::CType_MAX; -const int FieldOptions::CType_ARRAYSIZE; -#endif // _MSC_VER -const ::std::string FieldOptions::_default_experimental_map_key_; -#ifndef _MSC_VER -const int FieldOptions::kCtypeFieldNumber; -const int FieldOptions::kPackedFieldNumber; -const int FieldOptions::kDeprecatedFieldNumber; -const int FieldOptions::kExperimentalMapKeyFieldNumber; -const int FieldOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -FieldOptions::FieldOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void FieldOptions::InitAsDefaultInstance() { -} - -FieldOptions::FieldOptions(const FieldOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void FieldOptions::SharedCtor() { - _cached_size_ = 0; - ctype_ = 0; - packed_ = false; - deprecated_ = false; - experimental_map_key_ = const_cast< ::std::string*>(&_default_experimental_map_key_); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -FieldOptions::~FieldOptions() { - SharedDtor(); -} - -void FieldOptions::SharedDtor() { - if (experimental_map_key_ != &_default_experimental_map_key_) { - delete experimental_map_key_; - } - if (this != default_instance_) { - } -} - -void FieldOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FieldOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return FieldOptions_descriptor_; -} - -const FieldOptions& FieldOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -FieldOptions* FieldOptions::default_instance_ = NULL; - -FieldOptions* FieldOptions::New() const { - return new FieldOptions; -} - -void FieldOptions::Clear() { - _extensions_.Clear(); - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - ctype_ = 0; - packed_ = false; - deprecated_ = false; - if (_has_bit(3)) { - if (experimental_map_key_ != &_default_experimental_map_key_) { - experimental_map_key_->clear(); - } - } - } - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FieldOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::google::protobuf::FieldOptions_CType_IsValid(value)) { - set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); - } else { - mutable_unknown_fields()->AddVarint(1, value); - } - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_packed; - break; - } - - // optional bool packed = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_packed: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &packed_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(24)) goto parse_deprecated; - break; - } - - // optional bool deprecated = 3 [default = false]; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_deprecated: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &deprecated_))); - _set_bit(2); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(74)) goto parse_experimental_map_key; - break; - } - - // optional string experimental_map_key = 9; - case 9: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_experimental_map_key: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_experimental_map_key())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->experimental_map_key().data(), this->experimental_map_key().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - break; - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void FieldOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 1, this->ctype(), output); - } - - // optional bool packed = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output); - } - - // optional bool deprecated = 3 [default = false]; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); - } - - // optional string experimental_map_key = 9; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->experimental_map_key().data(), this->experimental_map_key().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 9, this->experimental_map_key(), output); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 1, this->ctype(), target); - } - - // optional bool packed = 2; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target); - } - - // optional bool deprecated = 3 [default = false]; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); - } - - // optional string experimental_map_key = 9; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->experimental_map_key().data(), this->experimental_map_key().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 9, this->experimental_map_key(), target); - } - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int FieldOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (has_ctype()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype()); - } - - // optional bool packed = 2; - if (has_packed()) { - total_size += 1 + 1; - } - - // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { - total_size += 1 + 1; - } - - // optional string experimental_map_key = 9; - if (has_experimental_map_key()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->experimental_map_key()); - } - - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FieldOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FieldOptions::MergeFrom(const FieldOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_ctype(from.ctype()); - } - if (from._has_bit(1)) { - set_packed(from.packed()); - } - if (from._has_bit(2)) { - set_deprecated(from.deprecated()); - } - if (from._has_bit(3)) { - set_experimental_map_key(from.experimental_map_key()); - } - } - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FieldOptions::CopyFrom(const FieldOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FieldOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void FieldOptions::Swap(FieldOptions* other) { - if (other != this) { - std::swap(ctype_, other->ctype_); - std::swap(packed_, other->packed_); - std::swap(deprecated_, other->deprecated_); - std::swap(experimental_map_key_, other->experimental_map_key_); - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata FieldOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = FieldOptions_descriptor_; - metadata.reflection = FieldOptions_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int EnumOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -EnumOptions::EnumOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void EnumOptions::InitAsDefaultInstance() { -} - -EnumOptions::EnumOptions(const EnumOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void EnumOptions::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -EnumOptions::~EnumOptions() { - SharedDtor(); -} - -void EnumOptions::SharedDtor() { - if (this != default_instance_) { - } -} - -void EnumOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* EnumOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return EnumOptions_descriptor_; -} - -const EnumOptions& EnumOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -EnumOptions* EnumOptions::default_instance_ = NULL; - -EnumOptions* EnumOptions::New() const { - return new EnumOptions; -} - -void EnumOptions::Clear() { - _extensions_.Clear(); - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void EnumOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int EnumOptions::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void EnumOptions::MergeFrom(const EnumOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumOptions::CopyFrom(const EnumOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void EnumOptions::Swap(EnumOptions* other) { - if (other != this) { - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata EnumOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = EnumOptions_descriptor_; - metadata.reflection = EnumOptions_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int EnumValueOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -EnumValueOptions::EnumValueOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void EnumValueOptions::InitAsDefaultInstance() { -} - -EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void EnumValueOptions::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -EnumValueOptions::~EnumValueOptions() { - SharedDtor(); -} - -void EnumValueOptions::SharedDtor() { - if (this != default_instance_) { - } -} - -void EnumValueOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return EnumValueOptions_descriptor_; -} - -const EnumValueOptions& EnumValueOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -EnumValueOptions* EnumValueOptions::default_instance_ = NULL; - -EnumValueOptions* EnumValueOptions::New() const { - return new EnumValueOptions; -} - -void EnumValueOptions::Clear() { - _extensions_.Clear(); - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumValueOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void EnumValueOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int EnumValueOptions::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumValueOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumValueOptions::CopyFrom(const EnumValueOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumValueOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void EnumValueOptions::Swap(EnumValueOptions* other) { - if (other != this) { - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = EnumValueOptions_descriptor_; - metadata.reflection = EnumValueOptions_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int ServiceOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -ServiceOptions::ServiceOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void ServiceOptions::InitAsDefaultInstance() { -} - -ServiceOptions::ServiceOptions(const ServiceOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void ServiceOptions::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -ServiceOptions::~ServiceOptions() { - SharedDtor(); -} - -void ServiceOptions::SharedDtor() { - if (this != default_instance_) { - } -} - -void ServiceOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return ServiceOptions_descriptor_; -} - -const ServiceOptions& ServiceOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -ServiceOptions* ServiceOptions::default_instance_ = NULL; - -ServiceOptions* ServiceOptions::New() const { - return new ServiceOptions; -} - -void ServiceOptions::Clear() { - _extensions_.Clear(); - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool ServiceOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void ServiceOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int ServiceOptions::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const ServiceOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void ServiceOptions::MergeFrom(const ServiceOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void ServiceOptions::CopyFrom(const ServiceOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool ServiceOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void ServiceOptions::Swap(ServiceOptions* other) { - if (other != this) { - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata ServiceOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = ServiceOptions_descriptor_; - metadata.reflection = ServiceOptions_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int MethodOptions::kUninterpretedOptionFieldNumber; -#endif // !_MSC_VER - -MethodOptions::MethodOptions() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void MethodOptions::InitAsDefaultInstance() { -} - -MethodOptions::MethodOptions(const MethodOptions& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void MethodOptions::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -MethodOptions::~MethodOptions() { - SharedDtor(); -} - -void MethodOptions::SharedDtor() { - if (this != default_instance_) { - } -} - -void MethodOptions::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* MethodOptions::descriptor() { - protobuf_AssignDescriptorsOnce(); - return MethodOptions_descriptor_; -} - -const MethodOptions& MethodOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -MethodOptions* MethodOptions::default_instance_ = NULL; - -MethodOptions* MethodOptions::New() const { - return new MethodOptions; -} - -void MethodOptions::Clear() { - _extensions_.Clear(); - uninterpreted_option_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MethodOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void MethodOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 999, this->uninterpreted_option(i), output); - } - - // Extension range [1000, 536870912) - _extensions_.SerializeWithCachedSizes( - 1000, 536870912, output); - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), target); - } - - // Extension range [1000, 536870912) - target = _extensions_.SerializeWithCachedSizesToArray( - 1000, 536870912, target); - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int MethodOptions::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - total_size += 2 * this->uninterpreted_option_size(); - for (int i = 0; i < this->uninterpreted_option_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->uninterpreted_option(i)); - } - - total_size += _extensions_.ByteSize(); - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MethodOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void MethodOptions::MergeFrom(const MethodOptions& from) { - GOOGLE_CHECK_NE(&from, this); - uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - _extensions_.MergeFrom(from._extensions_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MethodOptions::CopyFrom(const MethodOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MethodOptions::IsInitialized() const { - - for (int i = 0; i < uninterpreted_option_size(); i++) { - if (!this->uninterpreted_option(i).IsInitialized()) return false; - } - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void MethodOptions::Swap(MethodOptions* other) { - if (other != this) { - uninterpreted_option_.Swap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); - } -} - -::google::protobuf::Metadata MethodOptions::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = MethodOptions_descriptor_; - metadata.reflection = MethodOptions_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string UninterpretedOption_NamePart::_default_name_part_; -#ifndef _MSC_VER -const int UninterpretedOption_NamePart::kNamePartFieldNumber; -const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; -#endif // !_MSC_VER - -UninterpretedOption_NamePart::UninterpretedOption_NamePart() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void UninterpretedOption_NamePart::InitAsDefaultInstance() { -} - -UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void UninterpretedOption_NamePart::SharedCtor() { - _cached_size_ = 0; - name_part_ = const_cast< ::std::string*>(&_default_name_part_); - is_extension_ = false; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { - SharedDtor(); -} - -void UninterpretedOption_NamePart::SharedDtor() { - if (name_part_ != &_default_name_part_) { - delete name_part_; - } - if (this != default_instance_) { - } -} - -void UninterpretedOption_NamePart::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() { - protobuf_AssignDescriptorsOnce(); - return UninterpretedOption_NamePart_descriptor_; -} - -const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL; - -UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const { - return new UninterpretedOption_NamePart; -} - -void UninterpretedOption_NamePart::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_part_ != &_default_name_part_) { - name_part_->clear(); - } - } - is_extension_ = false; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool UninterpretedOption_NamePart::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required string name_part = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name_part())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name_part().data(), this->name_part().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_is_extension; - break; - } - - // required bool is_extension = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_is_extension: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &is_extension_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void UninterpretedOption_NamePart::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // required string name_part = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name_part().data(), this->name_part().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 1, this->name_part(), output); - } - - // required bool is_extension = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // required string name_part = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name_part().data(), this->name_part().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name_part(), target); - } - - // required bool is_extension = 2; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int UninterpretedOption_NamePart::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required string name_part = 1; - if (has_name_part()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name_part()); - } - - // required bool is_extension = 2; - if (has_is_extension()) { - total_size += 1 + 1; - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const UninterpretedOption_NamePart* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name_part(from.name_part()); - } - if (from._has_bit(1)) { - set_is_extension(from.is_extension()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool UninterpretedOption_NamePart::IsInitialized() const { - if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; - - return true; -} - -void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) { - if (other != this) { - std::swap(name_part_, other->name_part_); - std::swap(is_extension_, other->is_extension_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = UninterpretedOption_NamePart_descriptor_; - metadata.reflection = UninterpretedOption_NamePart_reflection_; - return metadata; -} - - -// ------------------------------------------------------------------- - -const ::std::string UninterpretedOption::_default_identifier_value_; -const ::std::string UninterpretedOption::_default_string_value_; -#ifndef _MSC_VER -const int UninterpretedOption::kNameFieldNumber; -const int UninterpretedOption::kIdentifierValueFieldNumber; -const int UninterpretedOption::kPositiveIntValueFieldNumber; -const int UninterpretedOption::kNegativeIntValueFieldNumber; -const int UninterpretedOption::kDoubleValueFieldNumber; -const int UninterpretedOption::kStringValueFieldNumber; -#endif // !_MSC_VER - -UninterpretedOption::UninterpretedOption() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void UninterpretedOption::InitAsDefaultInstance() { -} - -UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void UninterpretedOption::SharedCtor() { - _cached_size_ = 0; - identifier_value_ = const_cast< ::std::string*>(&_default_identifier_value_); - positive_int_value_ = GOOGLE_ULONGLONG(0); - negative_int_value_ = GOOGLE_LONGLONG(0); - double_value_ = 0; - string_value_ = const_cast< ::std::string*>(&_default_string_value_); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -UninterpretedOption::~UninterpretedOption() { - SharedDtor(); -} - -void UninterpretedOption::SharedDtor() { - if (identifier_value_ != &_default_identifier_value_) { - delete identifier_value_; - } - if (string_value_ != &_default_string_value_) { - delete string_value_; - } - if (this != default_instance_) { - } -} - -void UninterpretedOption::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() { - protobuf_AssignDescriptorsOnce(); - return UninterpretedOption_descriptor_; -} - -const UninterpretedOption& UninterpretedOption::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; -} - -UninterpretedOption* UninterpretedOption::default_instance_ = NULL; - -UninterpretedOption* UninterpretedOption::New() const { - return new UninterpretedOption; -} - -void UninterpretedOption::Clear() { - if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (_has_bit(1)) { - if (identifier_value_ != &_default_identifier_value_) { - identifier_value_->clear(); - } - } - positive_int_value_ = GOOGLE_ULONGLONG(0); - negative_int_value_ = GOOGLE_LONGLONG(0); - double_value_ = 0; - if (_has_bit(5)) { - if (string_value_ != &_default_string_value_) { - string_value_->clear(); - } - } - } - name_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool UninterpretedOption::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_name())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_name; - if (input->ExpectTag(26)) goto parse_identifier_value; - break; - } - - // optional string identifier_value = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_identifier_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_identifier_value())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->identifier_value().data(), this->identifier_value().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(32)) goto parse_positive_int_value; - break; - } - - // optional uint64 positive_int_value = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_positive_int_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &positive_int_value_))); - _set_bit(2); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(40)) goto parse_negative_int_value; - break; - } - - // optional int64 negative_int_value = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_negative_int_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( - input, &negative_int_value_))); - _set_bit(3); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(49)) goto parse_double_value; - break; - } - - // optional double double_value = 6; - case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_double_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( - input, &double_value_))); - _set_bit(4); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(58)) goto parse_string_value; - break; - } - - // optional bytes string_value = 7; - case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_string_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( - input, this->mutable_string_value())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void UninterpretedOption::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - for (int i = 0; i < this->name_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, this->name(i), output); - } - - // optional string identifier_value = 3; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->identifier_value().data(), this->identifier_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 3, this->identifier_value(), output); - } - - // optional uint64 positive_int_value = 4; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output); - } - - // optional int64 negative_int_value = 5; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output); - } - - // optional double double_value = 6; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output); - } - - // optional bytes string_value = 7; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormatLite::WriteBytes( - 7, this->string_value(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - for (int i = 0; i < this->name_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, this->name(i), target); - } - - // optional string identifier_value = 3; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->identifier_value().data(), this->identifier_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 3, this->identifier_value(), target); - } - - // optional uint64 positive_int_value = 4; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target); - } - - // optional int64 negative_int_value = 5; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target); - } - - // optional double double_value = 6; - if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target); - } - - // optional bytes string_value = 7; - if (_has_bit(5)) { - target = - ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( - 7, this->string_value(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int UninterpretedOption::ByteSize() const { - int total_size = 0; - - if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { - // optional string identifier_value = 3; - if (has_identifier_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->identifier_value()); - } - - // optional uint64 positive_int_value = 4; - if (has_positive_int_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->positive_int_value()); - } - - // optional int64 negative_int_value = 5; - if (has_negative_int_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int64Size( - this->negative_int_value()); - } - - // optional double double_value = 6; - if (has_double_value()) { - total_size += 1 + 8; - } - - // optional bytes string_value = 7; - if (has_string_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->string_value()); - } - - } - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - total_size += 1 * this->name_size(); - for (int i = 0; i < this->name_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->name(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const UninterpretedOption* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { - GOOGLE_CHECK_NE(&from, this); - name_.MergeFrom(from.name_); - if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (from._has_bit(1)) { - set_identifier_value(from.identifier_value()); - } - if (from._has_bit(2)) { - set_positive_int_value(from.positive_int_value()); - } - if (from._has_bit(3)) { - set_negative_int_value(from.negative_int_value()); - } - if (from._has_bit(4)) { - set_double_value(from.double_value()); - } - if (from._has_bit(5)) { - set_string_value(from.string_value()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void UninterpretedOption::CopyFrom(const UninterpretedOption& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool UninterpretedOption::IsInitialized() const { - - for (int i = 0; i < name_size(); i++) { - if (!this->name(i).IsInitialized()) return false; - } - return true; -} - -void UninterpretedOption::Swap(UninterpretedOption* other) { - if (other != this) { - name_.Swap(&other->name_); - std::swap(identifier_value_, other->identifier_value_); - std::swap(positive_int_value_, other->positive_int_value_); - std::swap(negative_int_value_, other->negative_int_value_); - std::swap(double_value_, other->double_value_); - std::swap(string_value_, other->string_value_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = UninterpretedOption_descriptor_; - metadata.reflection = UninterpretedOption_reflection_; - return metadata; -} - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace protobuf -} // namespace google - -// @@protoc_insertion_point(global_scope) diff --git a/Resources/NetHook/google/protobuf/descriptor.pb.h b/Resources/NetHook/google/protobuf/descriptor.pb.h deleted file mode 100644 index 2743b6f5..00000000 --- a/Resources/NetHook/google/protobuf/descriptor.pb.h +++ /dev/null @@ -1,4355 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/descriptor.proto - -#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED -#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 2003000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace google { -namespace protobuf { - -// Internal implementation detail -- do not call these. -void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); -void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); -void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - -class FileDescriptorSet; -class FileDescriptorProto; -class DescriptorProto; -class DescriptorProto_ExtensionRange; -class FieldDescriptorProto; -class EnumDescriptorProto; -class EnumValueDescriptorProto; -class ServiceDescriptorProto; -class MethodDescriptorProto; -class FileOptions; -class MessageOptions; -class FieldOptions; -class EnumOptions; -class EnumValueOptions; -class ServiceOptions; -class MethodOptions; -class UninterpretedOption; -class UninterpretedOption_NamePart; - -enum FieldDescriptorProto_Type { - FieldDescriptorProto_Type_TYPE_DOUBLE = 1, - FieldDescriptorProto_Type_TYPE_FLOAT = 2, - FieldDescriptorProto_Type_TYPE_INT64 = 3, - FieldDescriptorProto_Type_TYPE_UINT64 = 4, - FieldDescriptorProto_Type_TYPE_INT32 = 5, - FieldDescriptorProto_Type_TYPE_FIXED64 = 6, - FieldDescriptorProto_Type_TYPE_FIXED32 = 7, - FieldDescriptorProto_Type_TYPE_BOOL = 8, - FieldDescriptorProto_Type_TYPE_STRING = 9, - FieldDescriptorProto_Type_TYPE_GROUP = 10, - FieldDescriptorProto_Type_TYPE_MESSAGE = 11, - FieldDescriptorProto_Type_TYPE_BYTES = 12, - FieldDescriptorProto_Type_TYPE_UINT32 = 13, - FieldDescriptorProto_Type_TYPE_ENUM = 14, - FieldDescriptorProto_Type_TYPE_SFIXED32 = 15, - FieldDescriptorProto_Type_TYPE_SFIXED64 = 16, - FieldDescriptorProto_Type_TYPE_SINT32 = 17, - FieldDescriptorProto_Type_TYPE_SINT64 = 18 -}; -LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); -const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; -const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; -const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1; - -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); -inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) { - return ::google::protobuf::internal::NameOfEnum( - FieldDescriptorProto_Type_descriptor(), value); -} -inline bool FieldDescriptorProto_Type_Parse( - const ::std::string& name, FieldDescriptorProto_Type* value) { - return ::google::protobuf::internal::ParseNamedEnum( - FieldDescriptorProto_Type_descriptor(), name, value); -} -enum FieldDescriptorProto_Label { - FieldDescriptorProto_Label_LABEL_OPTIONAL = 1, - FieldDescriptorProto_Label_LABEL_REQUIRED = 2, - FieldDescriptorProto_Label_LABEL_REPEATED = 3 -}; -LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); -const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; -const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; -const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1; - -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); -inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) { - return ::google::protobuf::internal::NameOfEnum( - FieldDescriptorProto_Label_descriptor(), value); -} -inline bool FieldDescriptorProto_Label_Parse( - const ::std::string& name, FieldDescriptorProto_Label* value) { - return ::google::protobuf::internal::ParseNamedEnum( - FieldDescriptorProto_Label_descriptor(), name, value); -} -enum FileOptions_OptimizeMode { - FileOptions_OptimizeMode_SPEED = 1, - FileOptions_OptimizeMode_CODE_SIZE = 2, - FileOptions_OptimizeMode_LITE_RUNTIME = 3 -}; -LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); -const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; -const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; -const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1; - -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); -inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) { - return ::google::protobuf::internal::NameOfEnum( - FileOptions_OptimizeMode_descriptor(), value); -} -inline bool FileOptions_OptimizeMode_Parse( - const ::std::string& name, FileOptions_OptimizeMode* value) { - return ::google::protobuf::internal::ParseNamedEnum( - FileOptions_OptimizeMode_descriptor(), name, value); -} -enum FieldOptions_CType { - FieldOptions_CType_STRING = 0, - FieldOptions_CType_CORD = 1, - FieldOptions_CType_STRING_PIECE = 2 -}; -LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); -const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING; -const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; -const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1; - -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); -inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) { - return ::google::protobuf::internal::NameOfEnum( - FieldOptions_CType_descriptor(), value); -} -inline bool FieldOptions_CType_Parse( - const ::std::string& name, FieldOptions_CType* value) { - return ::google::protobuf::internal::ParseNamedEnum( - FieldOptions_CType_descriptor(), name, value); -} -// =================================================================== - -class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message { - public: - FileDescriptorSet(); - virtual ~FileDescriptorSet(); - - FileDescriptorSet(const FileDescriptorSet& from); - - inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FileDescriptorSet& default_instance(); - - void Swap(FileDescriptorSet* other); - - // implements Message ---------------------------------------------- - - FileDescriptorSet* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileDescriptorSet& from); - void MergeFrom(const FileDescriptorSet& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.FileDescriptorProto file = 1; - inline int file_size() const; - inline void clear_file(); - static const int kFileFieldNumber = 1; - inline const ::google::protobuf::FileDescriptorProto& file(int index) const; - inline ::google::protobuf::FileDescriptorProto* mutable_file(int index); - inline ::google::protobuf::FileDescriptorProto* add_file(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& - file() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* - mutable_file(); - - // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static FileDescriptorSet* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message { - public: - FileDescriptorProto(); - virtual ~FileDescriptorProto(); - - FileDescriptorProto(const FileDescriptorProto& from); - - inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FileDescriptorProto& default_instance(); - - void Swap(FileDescriptorProto* other); - - // implements Message ---------------------------------------------- - - FileDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileDescriptorProto& from); - void MergeFrom(const FileDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // optional string package = 2; - inline bool has_package() const; - inline void clear_package(); - static const int kPackageFieldNumber = 2; - inline const ::std::string& package() const; - inline void set_package(const ::std::string& value); - inline void set_package(const char* value); - inline void set_package(const char* value, size_t size); - inline ::std::string* mutable_package(); - - // repeated string dependency = 3; - inline int dependency_size() const; - inline void clear_dependency(); - static const int kDependencyFieldNumber = 3; - inline const ::std::string& dependency(int index) const; - inline ::std::string* mutable_dependency(int index); - inline void set_dependency(int index, const ::std::string& value); - inline void set_dependency(int index, const char* value); - inline void set_dependency(int index, const char* value, size_t size); - inline ::std::string* add_dependency(); - inline void add_dependency(const ::std::string& value); - inline void add_dependency(const char* value); - inline void add_dependency(const char* value, size_t size); - inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; - inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); - - // repeated .google.protobuf.DescriptorProto message_type = 4; - inline int message_type_size() const; - inline void clear_message_type(); - static const int kMessageTypeFieldNumber = 4; - inline const ::google::protobuf::DescriptorProto& message_type(int index) const; - inline ::google::protobuf::DescriptorProto* mutable_message_type(int index); - inline ::google::protobuf::DescriptorProto* add_message_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& - message_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* - mutable_message_type(); - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - inline int enum_type_size() const; - inline void clear_enum_type(); - static const int kEnumTypeFieldNumber = 5; - inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; - inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& - enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* - mutable_enum_type(); - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - inline int service_size() const; - inline void clear_service(); - static const int kServiceFieldNumber = 6; - inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const; - inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); - inline ::google::protobuf::ServiceDescriptorProto* add_service(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& - service() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* - mutable_service(); - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - inline int extension_size() const; - inline void clear_extension(); - static const int kExtensionFieldNumber = 7; - inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - inline ::google::protobuf::FieldDescriptorProto* add_extension(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_extension(); - - // optional .google.protobuf.FileOptions options = 8; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 8; - inline const ::google::protobuf::FileOptions& options() const; - inline ::google::protobuf::FileOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::std::string* package_; - static const ::std::string _default_package_; - ::google::protobuf::RepeatedPtrField< ::std::string> dependency_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; - ::google::protobuf::FileOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static FileDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message { - public: - DescriptorProto_ExtensionRange(); - virtual ~DescriptorProto_ExtensionRange(); - - DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); - - inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const DescriptorProto_ExtensionRange& default_instance(); - - void Swap(DescriptorProto_ExtensionRange* other); - - // implements Message ---------------------------------------------- - - DescriptorProto_ExtensionRange* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const DescriptorProto_ExtensionRange& from); - void MergeFrom(const DescriptorProto_ExtensionRange& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional int32 start = 1; - inline bool has_start() const; - inline void clear_start(); - static const int kStartFieldNumber = 1; - inline ::google::protobuf::int32 start() const; - inline void set_start(::google::protobuf::int32 value); - - // optional int32 end = 2; - inline bool has_end() const; - inline void clear_end(); - static const int kEndFieldNumber = 2; - inline ::google::protobuf::int32 end() const; - inline void set_end(::google::protobuf::int32 value); - - // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::int32 start_; - ::google::protobuf::int32 end_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static DescriptorProto_ExtensionRange* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { - public: - DescriptorProto(); - virtual ~DescriptorProto(); - - DescriptorProto(const DescriptorProto& from); - - inline DescriptorProto& operator=(const DescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const DescriptorProto& default_instance(); - - void Swap(DescriptorProto* other); - - // implements Message ---------------------------------------------- - - DescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const DescriptorProto& from); - void MergeFrom(const DescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef DescriptorProto_ExtensionRange ExtensionRange; - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - inline int field_size() const; - inline void clear_field(); - static const int kFieldFieldNumber = 2; - inline const ::google::protobuf::FieldDescriptorProto& field(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index); - inline ::google::protobuf::FieldDescriptorProto* add_field(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - field() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_field(); - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - inline int extension_size() const; - inline void clear_extension(); - static const int kExtensionFieldNumber = 6; - inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - inline ::google::protobuf::FieldDescriptorProto* add_extension(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_extension(); - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - inline int nested_type_size() const; - inline void clear_nested_type(); - static const int kNestedTypeFieldNumber = 3; - inline const ::google::protobuf::DescriptorProto& nested_type(int index) const; - inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index); - inline ::google::protobuf::DescriptorProto* add_nested_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& - nested_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* - mutable_nested_type(); - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - inline int enum_type_size() const; - inline void clear_enum_type(); - static const int kEnumTypeFieldNumber = 4; - inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; - inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& - enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* - mutable_enum_type(); - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - inline int extension_range_size() const; - inline void clear_extension_range(); - static const int kExtensionRangeFieldNumber = 5; - inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; - inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); - inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& - extension_range() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* - mutable_extension_range(); - - // optional .google.protobuf.MessageOptions options = 7; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 7; - inline const ::google::protobuf::MessageOptions& options() const; - inline ::google::protobuf::MessageOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; - ::google::protobuf::MessageOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static DescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message { - public: - FieldDescriptorProto(); - virtual ~FieldDescriptorProto(); - - FieldDescriptorProto(const FieldDescriptorProto& from); - - inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FieldDescriptorProto& default_instance(); - - void Swap(FieldDescriptorProto* other); - - // implements Message ---------------------------------------------- - - FieldDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FieldDescriptorProto& from); - void MergeFrom(const FieldDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef FieldDescriptorProto_Type Type; - static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE; - static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT; - static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64; - static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64; - static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32; - static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64; - static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32; - static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL; - static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING; - static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP; - static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE; - static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES; - static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32; - static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM; - static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32; - static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64; - static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32; - static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64; - static inline bool Type_IsValid(int value) { - return FieldDescriptorProto_Type_IsValid(value); - } - static const Type Type_MIN = - FieldDescriptorProto_Type_Type_MIN; - static const Type Type_MAX = - FieldDescriptorProto_Type_Type_MAX; - static const int Type_ARRAYSIZE = - FieldDescriptorProto_Type_Type_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* - Type_descriptor() { - return FieldDescriptorProto_Type_descriptor(); - } - static inline const ::std::string& Type_Name(Type value) { - return FieldDescriptorProto_Type_Name(value); - } - static inline bool Type_Parse(const ::std::string& name, - Type* value) { - return FieldDescriptorProto_Type_Parse(name, value); - } - - typedef FieldDescriptorProto_Label Label; - static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL; - static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED; - static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED; - static inline bool Label_IsValid(int value) { - return FieldDescriptorProto_Label_IsValid(value); - } - static const Label Label_MIN = - FieldDescriptorProto_Label_Label_MIN; - static const Label Label_MAX = - FieldDescriptorProto_Label_Label_MAX; - static const int Label_ARRAYSIZE = - FieldDescriptorProto_Label_Label_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* - Label_descriptor() { - return FieldDescriptorProto_Label_descriptor(); - } - static inline const ::std::string& Label_Name(Label value) { - return FieldDescriptorProto_Label_Name(value); - } - static inline bool Label_Parse(const ::std::string& name, - Label* value) { - return FieldDescriptorProto_Label_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // optional int32 number = 3; - inline bool has_number() const; - inline void clear_number(); - static const int kNumberFieldNumber = 3; - inline ::google::protobuf::int32 number() const; - inline void set_number(::google::protobuf::int32 value); - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - inline bool has_label() const; - inline void clear_label(); - static const int kLabelFieldNumber = 4; - inline ::google::protobuf::FieldDescriptorProto_Label label() const; - inline void set_label(::google::protobuf::FieldDescriptorProto_Label value); - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - inline bool has_type() const; - inline void clear_type(); - static const int kTypeFieldNumber = 5; - inline ::google::protobuf::FieldDescriptorProto_Type type() const; - inline void set_type(::google::protobuf::FieldDescriptorProto_Type value); - - // optional string type_name = 6; - inline bool has_type_name() const; - inline void clear_type_name(); - static const int kTypeNameFieldNumber = 6; - inline const ::std::string& type_name() const; - inline void set_type_name(const ::std::string& value); - inline void set_type_name(const char* value); - inline void set_type_name(const char* value, size_t size); - inline ::std::string* mutable_type_name(); - - // optional string extendee = 2; - inline bool has_extendee() const; - inline void clear_extendee(); - static const int kExtendeeFieldNumber = 2; - inline const ::std::string& extendee() const; - inline void set_extendee(const ::std::string& value); - inline void set_extendee(const char* value); - inline void set_extendee(const char* value, size_t size); - inline ::std::string* mutable_extendee(); - - // optional string default_value = 7; - inline bool has_default_value() const; - inline void clear_default_value(); - static const int kDefaultValueFieldNumber = 7; - inline const ::std::string& default_value() const; - inline void set_default_value(const ::std::string& value); - inline void set_default_value(const char* value); - inline void set_default_value(const char* value, size_t size); - inline ::std::string* mutable_default_value(); - - // optional .google.protobuf.FieldOptions options = 8; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 8; - inline const ::google::protobuf::FieldOptions& options() const; - inline ::google::protobuf::FieldOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::int32 number_; - int label_; - int type_; - ::std::string* type_name_; - static const ::std::string _default_type_name_; - ::std::string* extendee_; - static const ::std::string _default_extendee_; - ::std::string* default_value_; - static const ::std::string _default_default_value_; - ::google::protobuf::FieldOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static FieldDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message { - public: - EnumDescriptorProto(); - virtual ~EnumDescriptorProto(); - - EnumDescriptorProto(const EnumDescriptorProto& from); - - inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const EnumDescriptorProto& default_instance(); - - void Swap(EnumDescriptorProto* other); - - // implements Message ---------------------------------------------- - - EnumDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumDescriptorProto& from); - void MergeFrom(const EnumDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - inline int value_size() const; - inline void clear_value(); - static const int kValueFieldNumber = 2; - inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; - inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); - inline ::google::protobuf::EnumValueDescriptorProto* add_value(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& - value() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* - mutable_value(); - - // optional .google.protobuf.EnumOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 3; - inline const ::google::protobuf::EnumOptions& options() const; - inline ::google::protobuf::EnumOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; - ::google::protobuf::EnumOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static EnumDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message { - public: - EnumValueDescriptorProto(); - virtual ~EnumValueDescriptorProto(); - - EnumValueDescriptorProto(const EnumValueDescriptorProto& from); - - inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const EnumValueDescriptorProto& default_instance(); - - void Swap(EnumValueDescriptorProto* other); - - // implements Message ---------------------------------------------- - - EnumValueDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumValueDescriptorProto& from); - void MergeFrom(const EnumValueDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // optional int32 number = 2; - inline bool has_number() const; - inline void clear_number(); - static const int kNumberFieldNumber = 2; - inline ::google::protobuf::int32 number() const; - inline void set_number(::google::protobuf::int32 value); - - // optional .google.protobuf.EnumValueOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 3; - inline const ::google::protobuf::EnumValueOptions& options() const; - inline ::google::protobuf::EnumValueOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::int32 number_; - ::google::protobuf::EnumValueOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static EnumValueDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message { - public: - ServiceDescriptorProto(); - virtual ~ServiceDescriptorProto(); - - ServiceDescriptorProto(const ServiceDescriptorProto& from); - - inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const ServiceDescriptorProto& default_instance(); - - void Swap(ServiceDescriptorProto* other); - - // implements Message ---------------------------------------------- - - ServiceDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const ServiceDescriptorProto& from); - void MergeFrom(const ServiceDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - inline int method_size() const; - inline void clear_method(); - static const int kMethodFieldNumber = 2; - inline const ::google::protobuf::MethodDescriptorProto& method(int index) const; - inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index); - inline ::google::protobuf::MethodDescriptorProto* add_method(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& - method() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* - mutable_method(); - - // optional .google.protobuf.ServiceOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 3; - inline const ::google::protobuf::ServiceOptions& options() const; - inline ::google::protobuf::ServiceOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; - ::google::protobuf::ServiceOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static ServiceDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message { - public: - MethodDescriptorProto(); - virtual ~MethodDescriptorProto(); - - MethodDescriptorProto(const MethodDescriptorProto& from); - - inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const MethodDescriptorProto& default_instance(); - - void Swap(MethodDescriptorProto* other); - - // implements Message ---------------------------------------------- - - MethodDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MethodDescriptorProto& from); - void MergeFrom(const MethodDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - - // optional string input_type = 2; - inline bool has_input_type() const; - inline void clear_input_type(); - static const int kInputTypeFieldNumber = 2; - inline const ::std::string& input_type() const; - inline void set_input_type(const ::std::string& value); - inline void set_input_type(const char* value); - inline void set_input_type(const char* value, size_t size); - inline ::std::string* mutable_input_type(); - - // optional string output_type = 3; - inline bool has_output_type() const; - inline void clear_output_type(); - static const int kOutputTypeFieldNumber = 3; - inline const ::std::string& output_type() const; - inline void set_output_type(const ::std::string& value); - inline void set_output_type(const char* value); - inline void set_output_type(const char* value, size_t size); - inline ::std::string* mutable_output_type(); - - // optional .google.protobuf.MethodOptions options = 4; - inline bool has_options() const; - inline void clear_options(); - static const int kOptionsFieldNumber = 4; - inline const ::google::protobuf::MethodOptions& options() const; - inline ::google::protobuf::MethodOptions* mutable_options(); - - // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_; - static const ::std::string _default_name_; - ::std::string* input_type_; - static const ::std::string _default_input_type_; - ::std::string* output_type_; - static const ::std::string _default_output_type_; - ::google::protobuf::MethodOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static MethodDescriptorProto* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { - public: - FileOptions(); - virtual ~FileOptions(); - - FileOptions(const FileOptions& from); - - inline FileOptions& operator=(const FileOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FileOptions& default_instance(); - - void Swap(FileOptions* other); - - // implements Message ---------------------------------------------- - - FileOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileOptions& from); - void MergeFrom(const FileOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef FileOptions_OptimizeMode OptimizeMode; - static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED; - static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE; - static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME; - static inline bool OptimizeMode_IsValid(int value) { - return FileOptions_OptimizeMode_IsValid(value); - } - static const OptimizeMode OptimizeMode_MIN = - FileOptions_OptimizeMode_OptimizeMode_MIN; - static const OptimizeMode OptimizeMode_MAX = - FileOptions_OptimizeMode_OptimizeMode_MAX; - static const int OptimizeMode_ARRAYSIZE = - FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* - OptimizeMode_descriptor() { - return FileOptions_OptimizeMode_descriptor(); - } - static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) { - return FileOptions_OptimizeMode_Name(value); - } - static inline bool OptimizeMode_Parse(const ::std::string& name, - OptimizeMode* value) { - return FileOptions_OptimizeMode_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - // optional string java_package = 1; - inline bool has_java_package() const; - inline void clear_java_package(); - static const int kJavaPackageFieldNumber = 1; - inline const ::std::string& java_package() const; - inline void set_java_package(const ::std::string& value); - inline void set_java_package(const char* value); - inline void set_java_package(const char* value, size_t size); - inline ::std::string* mutable_java_package(); - - // optional string java_outer_classname = 8; - inline bool has_java_outer_classname() const; - inline void clear_java_outer_classname(); - static const int kJavaOuterClassnameFieldNumber = 8; - inline const ::std::string& java_outer_classname() const; - inline void set_java_outer_classname(const ::std::string& value); - inline void set_java_outer_classname(const char* value); - inline void set_java_outer_classname(const char* value, size_t size); - inline ::std::string* mutable_java_outer_classname(); - - // optional bool java_multiple_files = 10 [default = false]; - inline bool has_java_multiple_files() const; - inline void clear_java_multiple_files(); - static const int kJavaMultipleFilesFieldNumber = 10; - inline bool java_multiple_files() const; - inline void set_java_multiple_files(bool value); - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - inline bool has_optimize_for() const; - inline void clear_optimize_for(); - static const int kOptimizeForFieldNumber = 9; - inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; - inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); - - // optional bool cc_generic_services = 16 [default = true]; - inline bool has_cc_generic_services() const; - inline void clear_cc_generic_services(); - static const int kCcGenericServicesFieldNumber = 16; - inline bool cc_generic_services() const; - inline void set_cc_generic_services(bool value); - - // optional bool java_generic_services = 17 [default = true]; - inline bool has_java_generic_services() const; - inline void clear_java_generic_services(); - static const int kJavaGenericServicesFieldNumber = 17; - inline bool java_generic_services() const; - inline void set_java_generic_services(bool value); - - // optional bool py_generic_services = 18 [default = true]; - inline bool has_py_generic_services() const; - inline void clear_py_generic_services(); - static const int kPyGenericServicesFieldNumber = 18; - inline bool py_generic_services() const; - inline void set_py_generic_services(bool value); - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* java_package_; - static const ::std::string _default_java_package_; - ::std::string* java_outer_classname_; - static const ::std::string _default_java_outer_classname_; - bool java_multiple_files_; - int optimize_for_; - bool cc_generic_services_; - bool java_generic_services_; - bool py_generic_services_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static FileOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { - public: - MessageOptions(); - virtual ~MessageOptions(); - - MessageOptions(const MessageOptions& from); - - inline MessageOptions& operator=(const MessageOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const MessageOptions& default_instance(); - - void Swap(MessageOptions* other); - - // implements Message ---------------------------------------------- - - MessageOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MessageOptions& from); - void MergeFrom(const MessageOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional bool message_set_wire_format = 1 [default = false]; - inline bool has_message_set_wire_format() const; - inline void clear_message_set_wire_format(); - static const int kMessageSetWireFormatFieldNumber = 1; - inline bool message_set_wire_format() const; - inline void set_message_set_wire_format(bool value); - - // optional bool no_standard_descriptor_accessor = 2 [default = false]; - inline bool has_no_standard_descriptor_accessor() const; - inline void clear_no_standard_descriptor_accessor(); - static const int kNoStandardDescriptorAccessorFieldNumber = 2; - inline bool no_standard_descriptor_accessor() const; - inline void set_no_standard_descriptor_accessor(bool value); - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - bool message_set_wire_format_; - bool no_standard_descriptor_accessor_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static MessageOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { - public: - FieldOptions(); - virtual ~FieldOptions(); - - FieldOptions(const FieldOptions& from); - - inline FieldOptions& operator=(const FieldOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FieldOptions& default_instance(); - - void Swap(FieldOptions* other); - - // implements Message ---------------------------------------------- - - FieldOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FieldOptions& from); - void MergeFrom(const FieldOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef FieldOptions_CType CType; - static const CType STRING = FieldOptions_CType_STRING; - static const CType CORD = FieldOptions_CType_CORD; - static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE; - static inline bool CType_IsValid(int value) { - return FieldOptions_CType_IsValid(value); - } - static const CType CType_MIN = - FieldOptions_CType_CType_MIN; - static const CType CType_MAX = - FieldOptions_CType_CType_MAX; - static const int CType_ARRAYSIZE = - FieldOptions_CType_CType_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* - CType_descriptor() { - return FieldOptions_CType_descriptor(); - } - static inline const ::std::string& CType_Name(CType value) { - return FieldOptions_CType_Name(value); - } - static inline bool CType_Parse(const ::std::string& name, - CType* value) { - return FieldOptions_CType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - inline bool has_ctype() const; - inline void clear_ctype(); - static const int kCtypeFieldNumber = 1; - inline ::google::protobuf::FieldOptions_CType ctype() const; - inline void set_ctype(::google::protobuf::FieldOptions_CType value); - - // optional bool packed = 2; - inline bool has_packed() const; - inline void clear_packed(); - static const int kPackedFieldNumber = 2; - inline bool packed() const; - inline void set_packed(bool value); - - // optional bool deprecated = 3 [default = false]; - inline bool has_deprecated() const; - inline void clear_deprecated(); - static const int kDeprecatedFieldNumber = 3; - inline bool deprecated() const; - inline void set_deprecated(bool value); - - // optional string experimental_map_key = 9; - inline bool has_experimental_map_key() const; - inline void clear_experimental_map_key(); - static const int kExperimentalMapKeyFieldNumber = 9; - inline const ::std::string& experimental_map_key() const; - inline void set_experimental_map_key(const ::std::string& value); - inline void set_experimental_map_key(const char* value); - inline void set_experimental_map_key(const char* value, size_t size); - inline ::std::string* mutable_experimental_map_key(); - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - int ctype_; - bool packed_; - bool deprecated_; - ::std::string* experimental_map_key_; - static const ::std::string _default_experimental_map_key_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static FieldOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { - public: - EnumOptions(); - virtual ~EnumOptions(); - - EnumOptions(const EnumOptions& from); - - inline EnumOptions& operator=(const EnumOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const EnumOptions& default_instance(); - - void Swap(EnumOptions* other); - - // implements Message ---------------------------------------------- - - EnumOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumOptions& from); - void MergeFrom(const EnumOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static EnumOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { - public: - EnumValueOptions(); - virtual ~EnumValueOptions(); - - EnumValueOptions(const EnumValueOptions& from); - - inline EnumValueOptions& operator=(const EnumValueOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const EnumValueOptions& default_instance(); - - void Swap(EnumValueOptions* other); - - // implements Message ---------------------------------------------- - - EnumValueOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumValueOptions& from); - void MergeFrom(const EnumValueOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static EnumValueOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { - public: - ServiceOptions(); - virtual ~ServiceOptions(); - - ServiceOptions(const ServiceOptions& from); - - inline ServiceOptions& operator=(const ServiceOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const ServiceOptions& default_instance(); - - void Swap(ServiceOptions* other); - - // implements Message ---------------------------------------------- - - ServiceOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const ServiceOptions& from); - void MergeFrom(const ServiceOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static ServiceOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { - public: - MethodOptions(); - virtual ~MethodOptions(); - - MethodOptions(const MethodOptions& from); - - inline MethodOptions& operator=(const MethodOptions& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const MethodOptions& default_instance(); - - void Swap(MethodOptions* other); - - // implements Message ---------------------------------------------- - - MethodOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MethodOptions& from); - void MergeFrom(const MethodOptions& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - inline int uninterpreted_option_size() const; - inline void clear_uninterpreted_option(); - static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; - inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) - // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) - private: - ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static MethodOptions* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message { - public: - UninterpretedOption_NamePart(); - virtual ~UninterpretedOption_NamePart(); - - UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from); - - inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const UninterpretedOption_NamePart& default_instance(); - - void Swap(UninterpretedOption_NamePart* other); - - // implements Message ---------------------------------------------- - - UninterpretedOption_NamePart* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const UninterpretedOption_NamePart& from); - void MergeFrom(const UninterpretedOption_NamePart& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // required string name_part = 1; - inline bool has_name_part() const; - inline void clear_name_part(); - static const int kNamePartFieldNumber = 1; - inline const ::std::string& name_part() const; - inline void set_name_part(const ::std::string& value); - inline void set_name_part(const char* value); - inline void set_name_part(const char* value, size_t size); - inline ::std::string* mutable_name_part(); - - // required bool is_extension = 2; - inline bool has_is_extension() const; - inline void clear_is_extension(); - static const int kIsExtensionFieldNumber = 2; - inline bool is_extension() const; - inline void set_is_extension(bool value); - - // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::std::string* name_part_; - static const ::std::string _default_name_part_; - bool is_extension_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static UninterpretedOption_NamePart* default_instance_; -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message { - public: - UninterpretedOption(); - virtual ~UninterpretedOption(); - - UninterpretedOption(const UninterpretedOption& from); - - inline UninterpretedOption& operator=(const UninterpretedOption& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const UninterpretedOption& default_instance(); - - void Swap(UninterpretedOption* other); - - // implements Message ---------------------------------------------- - - UninterpretedOption* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const UninterpretedOption& from); - void MergeFrom(const UninterpretedOption& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef UninterpretedOption_NamePart NamePart; - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - inline int name_size() const; - inline void clear_name(); - static const int kNameFieldNumber = 2; - inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const; - inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index); - inline ::google::protobuf::UninterpretedOption_NamePart* add_name(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& - name() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* - mutable_name(); - - // optional string identifier_value = 3; - inline bool has_identifier_value() const; - inline void clear_identifier_value(); - static const int kIdentifierValueFieldNumber = 3; - inline const ::std::string& identifier_value() const; - inline void set_identifier_value(const ::std::string& value); - inline void set_identifier_value(const char* value); - inline void set_identifier_value(const char* value, size_t size); - inline ::std::string* mutable_identifier_value(); - - // optional uint64 positive_int_value = 4; - inline bool has_positive_int_value() const; - inline void clear_positive_int_value(); - static const int kPositiveIntValueFieldNumber = 4; - inline ::google::protobuf::uint64 positive_int_value() const; - inline void set_positive_int_value(::google::protobuf::uint64 value); - - // optional int64 negative_int_value = 5; - inline bool has_negative_int_value() const; - inline void clear_negative_int_value(); - static const int kNegativeIntValueFieldNumber = 5; - inline ::google::protobuf::int64 negative_int_value() const; - inline void set_negative_int_value(::google::protobuf::int64 value); - - // optional double double_value = 6; - inline bool has_double_value() const; - inline void clear_double_value(); - static const int kDoubleValueFieldNumber = 6; - inline double double_value() const; - inline void set_double_value(double value); - - // optional bytes string_value = 7; - inline bool has_string_value() const; - inline void clear_string_value(); - static const int kStringValueFieldNumber = 7; - inline const ::std::string& string_value() const; - inline void set_string_value(const ::std::string& value); - inline void set_string_value(const char* value); - inline void set_string_value(const void* value, size_t size); - inline ::std::string* mutable_string_value(); - - // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_; - ::std::string* identifier_value_; - static const ::std::string _default_identifier_value_; - ::google::protobuf::uint64 positive_int_value_; - ::google::protobuf::int64 negative_int_value_; - double double_value_; - ::std::string* string_value_; - static const ::std::string _default_string_value_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static UninterpretedOption* default_instance_; -}; -// =================================================================== - - -// =================================================================== - -// FileDescriptorSet - -// repeated .google.protobuf.FileDescriptorProto file = 1; -inline int FileDescriptorSet::file_size() const { - return file_.size(); -} -inline void FileDescriptorSet::clear_file() { - file_.Clear(); -} -inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { - return file_.Get(index); -} -inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) { - return file_.Mutable(index); -} -inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() { - return file_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& -FileDescriptorSet::file() const { - return file_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* -FileDescriptorSet::mutable_file() { - return &file_; -} - -// ------------------------------------------------------------------- - -// FileDescriptorProto - -// optional string name = 1; -inline bool FileDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void FileDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& FileDescriptorProto::name() const { - return *name_; -} -inline void FileDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FileDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FileDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FileDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional string package = 2; -inline bool FileDescriptorProto::has_package() const { - return _has_bit(1); -} -inline void FileDescriptorProto::clear_package() { - if (package_ != &_default_package_) { - package_->clear(); - } - _clear_bit(1); -} -inline const ::std::string& FileDescriptorProto::package() const { - return *package_; -} -inline void FileDescriptorProto::set_package(const ::std::string& value) { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - package_->assign(value); -} -inline void FileDescriptorProto::set_package(const char* value) { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - package_->assign(value); -} -inline void FileDescriptorProto::set_package(const char* value, size_t size) { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - package_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FileDescriptorProto::mutable_package() { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - return package_; -} - -// repeated string dependency = 3; -inline int FileDescriptorProto::dependency_size() const { - return dependency_.size(); -} -inline void FileDescriptorProto::clear_dependency() { - dependency_.Clear(); -} -inline const ::std::string& FileDescriptorProto::dependency(int index) const { - return dependency_.Get(index); -} -inline ::std::string* FileDescriptorProto::mutable_dependency(int index) { - return dependency_.Mutable(index); -} -inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) { - dependency_.Mutable(index)->assign(value); -} -inline void FileDescriptorProto::set_dependency(int index, const char* value) { - dependency_.Mutable(index)->assign(value); -} -inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) { - dependency_.Mutable(index)->assign( - reinterpret_cast(value), size); -} -inline ::std::string* FileDescriptorProto::add_dependency() { - return dependency_.Add(); -} -inline void FileDescriptorProto::add_dependency(const ::std::string& value) { - dependency_.Add()->assign(value); -} -inline void FileDescriptorProto::add_dependency(const char* value) { - dependency_.Add()->assign(value); -} -inline void FileDescriptorProto::add_dependency(const char* value, size_t size) { - dependency_.Add()->assign(reinterpret_cast(value), size); -} -inline const ::google::protobuf::RepeatedPtrField< ::std::string>& -FileDescriptorProto::dependency() const { - return dependency_; -} -inline ::google::protobuf::RepeatedPtrField< ::std::string>* -FileDescriptorProto::mutable_dependency() { - return &dependency_; -} - -// repeated .google.protobuf.DescriptorProto message_type = 4; -inline int FileDescriptorProto::message_type_size() const { - return message_type_.size(); -} -inline void FileDescriptorProto::clear_message_type() { - message_type_.Clear(); -} -inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { - return message_type_.Get(index); -} -inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) { - return message_type_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() { - return message_type_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -FileDescriptorProto::message_type() const { - return message_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -FileDescriptorProto::mutable_message_type() { - return &message_type_; -} - -// repeated .google.protobuf.EnumDescriptorProto enum_type = 5; -inline int FileDescriptorProto::enum_type_size() const { - return enum_type_.size(); -} -inline void FileDescriptorProto::clear_enum_type() { - enum_type_.Clear(); -} -inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { - return enum_type_.Get(index); -} -inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) { - return enum_type_.Mutable(index); -} -inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { - return enum_type_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -FileDescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -FileDescriptorProto::mutable_enum_type() { - return &enum_type_; -} - -// repeated .google.protobuf.ServiceDescriptorProto service = 6; -inline int FileDescriptorProto::service_size() const { - return service_.size(); -} -inline void FileDescriptorProto::clear_service() { - service_.Clear(); -} -inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { - return service_.Get(index); -} -inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) { - return service_.Mutable(index); -} -inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() { - return service_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& -FileDescriptorProto::service() const { - return service_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* -FileDescriptorProto::mutable_service() { - return &service_; -} - -// repeated .google.protobuf.FieldDescriptorProto extension = 7; -inline int FileDescriptorProto::extension_size() const { - return extension_.size(); -} -inline void FileDescriptorProto::clear_extension() { - extension_.Clear(); -} -inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { - return extension_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) { - return extension_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() { - return extension_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -FileDescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -FileDescriptorProto::mutable_extension() { - return &extension_; -} - -// optional .google.protobuf.FileOptions options = 8; -inline bool FileDescriptorProto::has_options() const { - return _has_bit(7); -} -inline void FileDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); - _clear_bit(7); -} -inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { - _set_bit(7); - if (options_ == NULL) options_ = new ::google::protobuf::FileOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// DescriptorProto_ExtensionRange - -// optional int32 start = 1; -inline bool DescriptorProto_ExtensionRange::has_start() const { - return _has_bit(0); -} -inline void DescriptorProto_ExtensionRange::clear_start() { - start_ = 0; - _clear_bit(0); -} -inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const { - return start_; -} -inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) { - _set_bit(0); - start_ = value; -} - -// optional int32 end = 2; -inline bool DescriptorProto_ExtensionRange::has_end() const { - return _has_bit(1); -} -inline void DescriptorProto_ExtensionRange::clear_end() { - end_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const { - return end_; -} -inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { - _set_bit(1); - end_ = value; -} - -// ------------------------------------------------------------------- - -// DescriptorProto - -// optional string name = 1; -inline bool DescriptorProto::has_name() const { - return _has_bit(0); -} -inline void DescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& DescriptorProto::name() const { - return *name_; -} -inline void DescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void DescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void DescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* DescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.FieldDescriptorProto field = 2; -inline int DescriptorProto::field_size() const { - return field_.size(); -} -inline void DescriptorProto::clear_field() { - field_.Clear(); -} -inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { - return field_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) { - return field_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() { - return field_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::field() const { - return field_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_field() { - return &field_; -} - -// repeated .google.protobuf.FieldDescriptorProto extension = 6; -inline int DescriptorProto::extension_size() const { - return extension_.size(); -} -inline void DescriptorProto::clear_extension() { - extension_.Clear(); -} -inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { - return extension_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) { - return extension_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() { - return extension_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_extension() { - return &extension_; -} - -// repeated .google.protobuf.DescriptorProto nested_type = 3; -inline int DescriptorProto::nested_type_size() const { - return nested_type_.size(); -} -inline void DescriptorProto::clear_nested_type() { - nested_type_.Clear(); -} -inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { - return nested_type_.Get(index); -} -inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) { - return nested_type_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() { - return nested_type_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -DescriptorProto::nested_type() const { - return nested_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -DescriptorProto::mutable_nested_type() { - return &nested_type_; -} - -// repeated .google.protobuf.EnumDescriptorProto enum_type = 4; -inline int DescriptorProto::enum_type_size() const { - return enum_type_.size(); -} -inline void DescriptorProto::clear_enum_type() { - enum_type_.Clear(); -} -inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { - return enum_type_.Get(index); -} -inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) { - return enum_type_.Mutable(index); -} -inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() { - return enum_type_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -DescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -DescriptorProto::mutable_enum_type() { - return &enum_type_; -} - -// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; -inline int DescriptorProto::extension_range_size() const { - return extension_range_.size(); -} -inline void DescriptorProto::clear_extension_range() { - extension_range_.Clear(); -} -inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { - return extension_range_.Get(index); -} -inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) { - return extension_range_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { - return extension_range_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& -DescriptorProto::extension_range() const { - return extension_range_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* -DescriptorProto::mutable_extension_range() { - return &extension_range_; -} - -// optional .google.protobuf.MessageOptions options = 7; -inline bool DescriptorProto::has_options() const { - return _has_bit(6); -} -inline void DescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); - _clear_bit(6); -} -inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { - _set_bit(6); - if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// FieldDescriptorProto - -// optional string name = 1; -inline bool FieldDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void FieldDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& FieldDescriptorProto::name() const { - return *name_; -} -inline void FieldDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FieldDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FieldDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FieldDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional int32 number = 3; -inline bool FieldDescriptorProto::has_number() const { - return _has_bit(1); -} -inline void FieldDescriptorProto::clear_number() { - number_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 FieldDescriptorProto::number() const { - return number_; -} -inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); - number_ = value; -} - -// optional .google.protobuf.FieldDescriptorProto.Label label = 4; -inline bool FieldDescriptorProto::has_label() const { - return _has_bit(2); -} -inline void FieldDescriptorProto::clear_label() { - label_ = 1; - _clear_bit(2); -} -inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const { - return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_); -} -inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) { - GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value)); - _set_bit(2); - label_ = value; -} - -// optional .google.protobuf.FieldDescriptorProto.Type type = 5; -inline bool FieldDescriptorProto::has_type() const { - return _has_bit(3); -} -inline void FieldDescriptorProto::clear_type() { - type_ = 1; - _clear_bit(3); -} -inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const { - return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_); -} -inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) { - GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value)); - _set_bit(3); - type_ = value; -} - -// optional string type_name = 6; -inline bool FieldDescriptorProto::has_type_name() const { - return _has_bit(4); -} -inline void FieldDescriptorProto::clear_type_name() { - if (type_name_ != &_default_type_name_) { - type_name_->clear(); - } - _clear_bit(4); -} -inline const ::std::string& FieldDescriptorProto::type_name() const { - return *type_name_; -} -inline void FieldDescriptorProto::set_type_name(const ::std::string& value) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { - type_name_ = new ::std::string; - } - type_name_->assign(value); -} -inline void FieldDescriptorProto::set_type_name(const char* value) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { - type_name_ = new ::std::string; - } - type_name_->assign(value); -} -inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { - type_name_ = new ::std::string; - } - type_name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FieldDescriptorProto::mutable_type_name() { - _set_bit(4); - if (type_name_ == &_default_type_name_) { - type_name_ = new ::std::string; - } - return type_name_; -} - -// optional string extendee = 2; -inline bool FieldDescriptorProto::has_extendee() const { - return _has_bit(5); -} -inline void FieldDescriptorProto::clear_extendee() { - if (extendee_ != &_default_extendee_) { - extendee_->clear(); - } - _clear_bit(5); -} -inline const ::std::string& FieldDescriptorProto::extendee() const { - return *extendee_; -} -inline void FieldDescriptorProto::set_extendee(const ::std::string& value) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - extendee_->assign(value); -} -inline void FieldDescriptorProto::set_extendee(const char* value) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - extendee_->assign(value); -} -inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - extendee_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FieldDescriptorProto::mutable_extendee() { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - return extendee_; -} - -// optional string default_value = 7; -inline bool FieldDescriptorProto::has_default_value() const { - return _has_bit(6); -} -inline void FieldDescriptorProto::clear_default_value() { - if (default_value_ != &_default_default_value_) { - default_value_->clear(); - } - _clear_bit(6); -} -inline const ::std::string& FieldDescriptorProto::default_value() const { - return *default_value_; -} -inline void FieldDescriptorProto::set_default_value(const ::std::string& value) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { - default_value_ = new ::std::string; - } - default_value_->assign(value); -} -inline void FieldDescriptorProto::set_default_value(const char* value) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { - default_value_ = new ::std::string; - } - default_value_->assign(value); -} -inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { - default_value_ = new ::std::string; - } - default_value_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FieldDescriptorProto::mutable_default_value() { - _set_bit(6); - if (default_value_ == &_default_default_value_) { - default_value_ = new ::std::string; - } - return default_value_; -} - -// optional .google.protobuf.FieldOptions options = 8; -inline bool FieldDescriptorProto::has_options() const { - return _has_bit(7); -} -inline void FieldDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); - _clear_bit(7); -} -inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { - _set_bit(7); - if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// EnumDescriptorProto - -// optional string name = 1; -inline bool EnumDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void EnumDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& EnumDescriptorProto::name() const { - return *name_; -} -inline void EnumDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* EnumDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.EnumValueDescriptorProto value = 2; -inline int EnumDescriptorProto::value_size() const { - return value_.size(); -} -inline void EnumDescriptorProto::clear_value() { - value_.Clear(); -} -inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { - return value_.Get(index); -} -inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) { - return value_.Mutable(index); -} -inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { - return value_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& -EnumDescriptorProto::value() const { - return value_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* -EnumDescriptorProto::mutable_value() { - return &value_; -} - -// optional .google.protobuf.EnumOptions options = 3; -inline bool EnumDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void EnumDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); - _clear_bit(2); -} -inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { - _set_bit(2); - if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// EnumValueDescriptorProto - -// optional string name = 1; -inline bool EnumValueDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void EnumValueDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& EnumValueDescriptorProto::name() const { - return *name_; -} -inline void EnumValueDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumValueDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* EnumValueDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional int32 number = 2; -inline bool EnumValueDescriptorProto::has_number() const { - return _has_bit(1); -} -inline void EnumValueDescriptorProto::clear_number() { - number_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const { - return number_; -} -inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); - number_ = value; -} - -// optional .google.protobuf.EnumValueOptions options = 3; -inline bool EnumValueDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void EnumValueDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); - _clear_bit(2); -} -inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { - _set_bit(2); - if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// ServiceDescriptorProto - -// optional string name = 1; -inline bool ServiceDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void ServiceDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& ServiceDescriptorProto::name() const { - return *name_; -} -inline void ServiceDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void ServiceDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* ServiceDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.MethodDescriptorProto method = 2; -inline int ServiceDescriptorProto::method_size() const { - return method_.size(); -} -inline void ServiceDescriptorProto::clear_method() { - method_.Clear(); -} -inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { - return method_.Get(index); -} -inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) { - return method_.Mutable(index); -} -inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() { - return method_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& -ServiceDescriptorProto::method() const { - return method_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* -ServiceDescriptorProto::mutable_method() { - return &method_; -} - -// optional .google.protobuf.ServiceOptions options = 3; -inline bool ServiceDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void ServiceDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); - _clear_bit(2); -} -inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { - _set_bit(2); - if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// MethodDescriptorProto - -// optional string name = 1; -inline bool MethodDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void MethodDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& MethodDescriptorProto::name() const { - return *name_; -} -inline void MethodDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void MethodDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void MethodDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* MethodDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional string input_type = 2; -inline bool MethodDescriptorProto::has_input_type() const { - return _has_bit(1); -} -inline void MethodDescriptorProto::clear_input_type() { - if (input_type_ != &_default_input_type_) { - input_type_->clear(); - } - _clear_bit(1); -} -inline const ::std::string& MethodDescriptorProto::input_type() const { - return *input_type_; -} -inline void MethodDescriptorProto::set_input_type(const ::std::string& value) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { - input_type_ = new ::std::string; - } - input_type_->assign(value); -} -inline void MethodDescriptorProto::set_input_type(const char* value) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { - input_type_ = new ::std::string; - } - input_type_->assign(value); -} -inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { - input_type_ = new ::std::string; - } - input_type_->assign(reinterpret_cast(value), size); -} -inline ::std::string* MethodDescriptorProto::mutable_input_type() { - _set_bit(1); - if (input_type_ == &_default_input_type_) { - input_type_ = new ::std::string; - } - return input_type_; -} - -// optional string output_type = 3; -inline bool MethodDescriptorProto::has_output_type() const { - return _has_bit(2); -} -inline void MethodDescriptorProto::clear_output_type() { - if (output_type_ != &_default_output_type_) { - output_type_->clear(); - } - _clear_bit(2); -} -inline const ::std::string& MethodDescriptorProto::output_type() const { - return *output_type_; -} -inline void MethodDescriptorProto::set_output_type(const ::std::string& value) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { - output_type_ = new ::std::string; - } - output_type_->assign(value); -} -inline void MethodDescriptorProto::set_output_type(const char* value) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { - output_type_ = new ::std::string; - } - output_type_->assign(value); -} -inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { - output_type_ = new ::std::string; - } - output_type_->assign(reinterpret_cast(value), size); -} -inline ::std::string* MethodDescriptorProto::mutable_output_type() { - _set_bit(2); - if (output_type_ == &_default_output_type_) { - output_type_ = new ::std::string; - } - return output_type_; -} - -// optional .google.protobuf.MethodOptions options = 4; -inline bool MethodDescriptorProto::has_options() const { - return _has_bit(3); -} -inline void MethodDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); - _clear_bit(3); -} -inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { - return options_ != NULL ? *options_ : *default_instance_->options_; -} -inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { - _set_bit(3); - if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// FileOptions - -// optional string java_package = 1; -inline bool FileOptions::has_java_package() const { - return _has_bit(0); -} -inline void FileOptions::clear_java_package() { - if (java_package_ != &_default_java_package_) { - java_package_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& FileOptions::java_package() const { - return *java_package_; -} -inline void FileOptions::set_java_package(const ::std::string& value) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { - java_package_ = new ::std::string; - } - java_package_->assign(value); -} -inline void FileOptions::set_java_package(const char* value) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { - java_package_ = new ::std::string; - } - java_package_->assign(value); -} -inline void FileOptions::set_java_package(const char* value, size_t size) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { - java_package_ = new ::std::string; - } - java_package_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FileOptions::mutable_java_package() { - _set_bit(0); - if (java_package_ == &_default_java_package_) { - java_package_ = new ::std::string; - } - return java_package_; -} - -// optional string java_outer_classname = 8; -inline bool FileOptions::has_java_outer_classname() const { - return _has_bit(1); -} -inline void FileOptions::clear_java_outer_classname() { - if (java_outer_classname_ != &_default_java_outer_classname_) { - java_outer_classname_->clear(); - } - _clear_bit(1); -} -inline const ::std::string& FileOptions::java_outer_classname() const { - return *java_outer_classname_; -} -inline void FileOptions::set_java_outer_classname(const ::std::string& value) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { - java_outer_classname_ = new ::std::string; - } - java_outer_classname_->assign(value); -} -inline void FileOptions::set_java_outer_classname(const char* value) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { - java_outer_classname_ = new ::std::string; - } - java_outer_classname_->assign(value); -} -inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { - java_outer_classname_ = new ::std::string; - } - java_outer_classname_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FileOptions::mutable_java_outer_classname() { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { - java_outer_classname_ = new ::std::string; - } - return java_outer_classname_; -} - -// optional bool java_multiple_files = 10 [default = false]; -inline bool FileOptions::has_java_multiple_files() const { - return _has_bit(2); -} -inline void FileOptions::clear_java_multiple_files() { - java_multiple_files_ = false; - _clear_bit(2); -} -inline bool FileOptions::java_multiple_files() const { - return java_multiple_files_; -} -inline void FileOptions::set_java_multiple_files(bool value) { - _set_bit(2); - java_multiple_files_ = value; -} - -// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; -inline bool FileOptions::has_optimize_for() const { - return _has_bit(3); -} -inline void FileOptions::clear_optimize_for() { - optimize_for_ = 1; - _clear_bit(3); -} -inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const { - return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_); -} -inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { - GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value)); - _set_bit(3); - optimize_for_ = value; -} - -// optional bool cc_generic_services = 16 [default = true]; -inline bool FileOptions::has_cc_generic_services() const { - return _has_bit(4); -} -inline void FileOptions::clear_cc_generic_services() { - cc_generic_services_ = true; - _clear_bit(4); -} -inline bool FileOptions::cc_generic_services() const { - return cc_generic_services_; -} -inline void FileOptions::set_cc_generic_services(bool value) { - _set_bit(4); - cc_generic_services_ = value; -} - -// optional bool java_generic_services = 17 [default = true]; -inline bool FileOptions::has_java_generic_services() const { - return _has_bit(5); -} -inline void FileOptions::clear_java_generic_services() { - java_generic_services_ = true; - _clear_bit(5); -} -inline bool FileOptions::java_generic_services() const { - return java_generic_services_; -} -inline void FileOptions::set_java_generic_services(bool value) { - _set_bit(5); - java_generic_services_ = value; -} - -// optional bool py_generic_services = 18 [default = true]; -inline bool FileOptions::has_py_generic_services() const { - return _has_bit(6); -} -inline void FileOptions::clear_py_generic_services() { - py_generic_services_ = true; - _clear_bit(6); -} -inline bool FileOptions::py_generic_services() const { - return py_generic_services_; -} -inline void FileOptions::set_py_generic_services(bool value) { - _set_bit(6); - py_generic_services_ = value; -} - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int FileOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void FileOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -FileOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -FileOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// MessageOptions - -// optional bool message_set_wire_format = 1 [default = false]; -inline bool MessageOptions::has_message_set_wire_format() const { - return _has_bit(0); -} -inline void MessageOptions::clear_message_set_wire_format() { - message_set_wire_format_ = false; - _clear_bit(0); -} -inline bool MessageOptions::message_set_wire_format() const { - return message_set_wire_format_; -} -inline void MessageOptions::set_message_set_wire_format(bool value) { - _set_bit(0); - message_set_wire_format_ = value; -} - -// optional bool no_standard_descriptor_accessor = 2 [default = false]; -inline bool MessageOptions::has_no_standard_descriptor_accessor() const { - return _has_bit(1); -} -inline void MessageOptions::clear_no_standard_descriptor_accessor() { - no_standard_descriptor_accessor_ = false; - _clear_bit(1); -} -inline bool MessageOptions::no_standard_descriptor_accessor() const { - return no_standard_descriptor_accessor_; -} -inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { - _set_bit(1); - no_standard_descriptor_accessor_ = value; -} - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int MessageOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void MessageOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -MessageOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -MessageOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// FieldOptions - -// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; -inline bool FieldOptions::has_ctype() const { - return _has_bit(0); -} -inline void FieldOptions::clear_ctype() { - ctype_ = 0; - _clear_bit(0); -} -inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { - return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_); -} -inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { - GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value)); - _set_bit(0); - ctype_ = value; -} - -// optional bool packed = 2; -inline bool FieldOptions::has_packed() const { - return _has_bit(1); -} -inline void FieldOptions::clear_packed() { - packed_ = false; - _clear_bit(1); -} -inline bool FieldOptions::packed() const { - return packed_; -} -inline void FieldOptions::set_packed(bool value) { - _set_bit(1); - packed_ = value; -} - -// optional bool deprecated = 3 [default = false]; -inline bool FieldOptions::has_deprecated() const { - return _has_bit(2); -} -inline void FieldOptions::clear_deprecated() { - deprecated_ = false; - _clear_bit(2); -} -inline bool FieldOptions::deprecated() const { - return deprecated_; -} -inline void FieldOptions::set_deprecated(bool value) { - _set_bit(2); - deprecated_ = value; -} - -// optional string experimental_map_key = 9; -inline bool FieldOptions::has_experimental_map_key() const { - return _has_bit(3); -} -inline void FieldOptions::clear_experimental_map_key() { - if (experimental_map_key_ != &_default_experimental_map_key_) { - experimental_map_key_->clear(); - } - _clear_bit(3); -} -inline const ::std::string& FieldOptions::experimental_map_key() const { - return *experimental_map_key_; -} -inline void FieldOptions::set_experimental_map_key(const ::std::string& value) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - experimental_map_key_->assign(value); -} -inline void FieldOptions::set_experimental_map_key(const char* value) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - experimental_map_key_->assign(value); -} -inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - experimental_map_key_->assign(reinterpret_cast(value), size); -} -inline ::std::string* FieldOptions::mutable_experimental_map_key() { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - return experimental_map_key_; -} - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int FieldOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void FieldOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -FieldOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -FieldOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// EnumOptions - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int EnumOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void EnumOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -EnumOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -EnumOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// EnumValueOptions - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int EnumValueOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void EnumValueOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -EnumValueOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -EnumValueOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// ServiceOptions - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int ServiceOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void ServiceOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -ServiceOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -ServiceOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// MethodOptions - -// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int MethodOptions::uninterpreted_option_size() const { - return uninterpreted_option_.size(); -} -inline void MethodOptions::clear_uninterpreted_option() { - uninterpreted_option_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { - return uninterpreted_option_.Get(index); -} -inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) { - return uninterpreted_option_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() { - return uninterpreted_option_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -MethodOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -MethodOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} - -// ------------------------------------------------------------------- - -// UninterpretedOption_NamePart - -// required string name_part = 1; -inline bool UninterpretedOption_NamePart::has_name_part() const { - return _has_bit(0); -} -inline void UninterpretedOption_NamePart::clear_name_part() { - if (name_part_ != &_default_name_part_) { - name_part_->clear(); - } - _clear_bit(0); -} -inline const ::std::string& UninterpretedOption_NamePart::name_part() const { - return *name_part_; -} -inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { - name_part_ = new ::std::string; - } - name_part_->assign(value); -} -inline void UninterpretedOption_NamePart::set_name_part(const char* value) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { - name_part_ = new ::std::string; - } - name_part_->assign(value); -} -inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { - name_part_ = new ::std::string; - } - name_part_->assign(reinterpret_cast(value), size); -} -inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() { - _set_bit(0); - if (name_part_ == &_default_name_part_) { - name_part_ = new ::std::string; - } - return name_part_; -} - -// required bool is_extension = 2; -inline bool UninterpretedOption_NamePart::has_is_extension() const { - return _has_bit(1); -} -inline void UninterpretedOption_NamePart::clear_is_extension() { - is_extension_ = false; - _clear_bit(1); -} -inline bool UninterpretedOption_NamePart::is_extension() const { - return is_extension_; -} -inline void UninterpretedOption_NamePart::set_is_extension(bool value) { - _set_bit(1); - is_extension_ = value; -} - -// ------------------------------------------------------------------- - -// UninterpretedOption - -// repeated .google.protobuf.UninterpretedOption.NamePart name = 2; -inline int UninterpretedOption::name_size() const { - return name_.size(); -} -inline void UninterpretedOption::clear_name() { - name_.Clear(); -} -inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { - return name_.Get(index); -} -inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) { - return name_.Mutable(index); -} -inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() { - return name_.Add(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& -UninterpretedOption::name() const { - return name_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* -UninterpretedOption::mutable_name() { - return &name_; -} - -// optional string identifier_value = 3; -inline bool UninterpretedOption::has_identifier_value() const { - return _has_bit(1); -} -inline void UninterpretedOption::clear_identifier_value() { - if (identifier_value_ != &_default_identifier_value_) { - identifier_value_->clear(); - } - _clear_bit(1); -} -inline const ::std::string& UninterpretedOption::identifier_value() const { - return *identifier_value_; -} -inline void UninterpretedOption::set_identifier_value(const ::std::string& value) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { - identifier_value_ = new ::std::string; - } - identifier_value_->assign(value); -} -inline void UninterpretedOption::set_identifier_value(const char* value) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { - identifier_value_ = new ::std::string; - } - identifier_value_->assign(value); -} -inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { - identifier_value_ = new ::std::string; - } - identifier_value_->assign(reinterpret_cast(value), size); -} -inline ::std::string* UninterpretedOption::mutable_identifier_value() { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { - identifier_value_ = new ::std::string; - } - return identifier_value_; -} - -// optional uint64 positive_int_value = 4; -inline bool UninterpretedOption::has_positive_int_value() const { - return _has_bit(2); -} -inline void UninterpretedOption::clear_positive_int_value() { - positive_int_value_ = GOOGLE_ULONGLONG(0); - _clear_bit(2); -} -inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const { - return positive_int_value_; -} -inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) { - _set_bit(2); - positive_int_value_ = value; -} - -// optional int64 negative_int_value = 5; -inline bool UninterpretedOption::has_negative_int_value() const { - return _has_bit(3); -} -inline void UninterpretedOption::clear_negative_int_value() { - negative_int_value_ = GOOGLE_LONGLONG(0); - _clear_bit(3); -} -inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const { - return negative_int_value_; -} -inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) { - _set_bit(3); - negative_int_value_ = value; -} - -// optional double double_value = 6; -inline bool UninterpretedOption::has_double_value() const { - return _has_bit(4); -} -inline void UninterpretedOption::clear_double_value() { - double_value_ = 0; - _clear_bit(4); -} -inline double UninterpretedOption::double_value() const { - return double_value_; -} -inline void UninterpretedOption::set_double_value(double value) { - _set_bit(4); - double_value_ = value; -} - -// optional bytes string_value = 7; -inline bool UninterpretedOption::has_string_value() const { - return _has_bit(5); -} -inline void UninterpretedOption::clear_string_value() { - if (string_value_ != &_default_string_value_) { - string_value_->clear(); - } - _clear_bit(5); -} -inline const ::std::string& UninterpretedOption::string_value() const { - return *string_value_; -} -inline void UninterpretedOption::set_string_value(const ::std::string& value) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { - string_value_ = new ::std::string; - } - string_value_->assign(value); -} -inline void UninterpretedOption::set_string_value(const char* value) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { - string_value_ = new ::std::string; - } - string_value_->assign(value); -} -inline void UninterpretedOption::set_string_value(const void* value, size_t size) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { - string_value_ = new ::std::string; - } - string_value_->assign(reinterpret_cast(value), size); -} -inline ::std::string* UninterpretedOption::mutable_string_value() { - _set_bit(5); - if (string_value_ == &_default_string_value_) { - string_value_ = new ::std::string; - } - return string_value_; -} - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace protobuf -} // namespace google - -#ifndef SWIG -namespace google { -namespace protobuf { - -template <> -inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() { - return ::google::protobuf::FieldDescriptorProto_Type_descriptor(); -} -template <> -inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() { - return ::google::protobuf::FieldDescriptorProto_Label_descriptor(); -} -template <> -inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() { - return ::google::protobuf::FileOptions_OptimizeMode_descriptor(); -} -template <> -inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() { - return ::google::protobuf::FieldOptions_CType_descriptor(); -} - -} // namespace google -} // namespace protobuf -#endif // SWIG - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/Resources/NetHook/google/protobuf/descriptor.proto b/Resources/NetHook/google/protobuf/descriptor.proto deleted file mode 100644 index cc04aa8e..00000000 --- a/Resources/NetHook/google/protobuf/descriptor.proto +++ /dev/null @@ -1,433 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// The messages in this file describe the definitions found in .proto files. -// A valid .proto file can be translated directly to a FileDescriptorProto -// without any other information (e.g. without reading its imports). - - - -package google.protobuf; -option java_package = "com.google.protobuf"; -option java_outer_classname = "DescriptorProtos"; - -// descriptor.proto must be optimized for speed because reflection-based -// algorithms don't work during bootstrapping. -option optimize_for = SPEED; - -// The protocol compiler can output a FileDescriptorSet containing the .proto -// files it parses. -message FileDescriptorSet { - repeated FileDescriptorProto file = 1; -} - -// Describes a complete .proto file. -message FileDescriptorProto { - optional string name = 1; // file name, relative to root of source tree - optional string package = 2; // e.g. "foo", "foo.bar", etc. - - // Names of files imported by this file. - repeated string dependency = 3; - - // All top-level definitions in this file. - repeated DescriptorProto message_type = 4; - repeated EnumDescriptorProto enum_type = 5; - repeated ServiceDescriptorProto service = 6; - repeated FieldDescriptorProto extension = 7; - - optional FileOptions options = 8; -} - -// Describes a message type. -message DescriptorProto { - optional string name = 1; - - repeated FieldDescriptorProto field = 2; - repeated FieldDescriptorProto extension = 6; - - repeated DescriptorProto nested_type = 3; - repeated EnumDescriptorProto enum_type = 4; - - message ExtensionRange { - optional int32 start = 1; - optional int32 end = 2; - } - repeated ExtensionRange extension_range = 5; - - optional MessageOptions options = 7; -} - -// Describes a field within a message. -message FieldDescriptorProto { - enum Type { - // 0 is reserved for errors. - // Order is weird for historical reasons. - TYPE_DOUBLE = 1; - TYPE_FLOAT = 2; - TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4; - TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6; - TYPE_FIXED32 = 7; - TYPE_BOOL = 8; - TYPE_STRING = 9; - TYPE_GROUP = 10; // Tag-delimited aggregate. - TYPE_MESSAGE = 11; // Length-delimited aggregate. - - // New in version 2. - TYPE_BYTES = 12; - TYPE_UINT32 = 13; - TYPE_ENUM = 14; - TYPE_SFIXED32 = 15; - TYPE_SFIXED64 = 16; - TYPE_SINT32 = 17; // Uses ZigZag encoding. - TYPE_SINT64 = 18; // Uses ZigZag encoding. - }; - - enum Label { - // 0 is reserved for errors - LABEL_OPTIONAL = 1; - LABEL_REQUIRED = 2; - LABEL_REPEATED = 3; - // TODO(sanjay): Should we add LABEL_MAP? - }; - - optional string name = 1; - optional int32 number = 3; - optional Label label = 4; - - // If type_name is set, this need not be set. If both this and type_name - // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. - optional Type type = 5; - - // For message and enum types, this is the name of the type. If the name - // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping - // rules are used to find the type (i.e. first the nested types within this - // message are searched, then within the parent, on up to the root - // namespace). - optional string type_name = 6; - - // For extensions, this is the name of the type being extended. It is - // resolved in the same manner as type_name. - optional string extendee = 2; - - // For numeric types, contains the original text representation of the value. - // For booleans, "true" or "false". - // For strings, contains the default text contents (not escaped in any way). - // For bytes, contains the C escaped value. All bytes >= 128 are escaped. - // TODO(kenton): Base-64 encode? - optional string default_value = 7; - - optional FieldOptions options = 8; -} - -// Describes an enum type. -message EnumDescriptorProto { - optional string name = 1; - - repeated EnumValueDescriptorProto value = 2; - - optional EnumOptions options = 3; -} - -// Describes a value within an enum. -message EnumValueDescriptorProto { - optional string name = 1; - optional int32 number = 2; - - optional EnumValueOptions options = 3; -} - -// Describes a service. -message ServiceDescriptorProto { - optional string name = 1; - repeated MethodDescriptorProto method = 2; - - optional ServiceOptions options = 3; -} - -// Describes a method of a service. -message MethodDescriptorProto { - optional string name = 1; - - // Input and output type names. These are resolved in the same way as - // FieldDescriptorProto.type_name, but must refer to a message type. - optional string input_type = 2; - optional string output_type = 3; - - optional MethodOptions options = 4; -} - -// =================================================================== -// Options - -// Each of the definitions above may have "options" attached. These are -// just annotations which may cause code to be generated slightly differently -// or may contain hints for code that manipulates protocol messages. -// -// Clients may define custom options as extensions of the *Options messages. -// These extensions may not yet be known at parsing time, so the parser cannot -// store the values in them. Instead it stores them in a field in the *Options -// message called uninterpreted_option. This field must have the same name -// across all *Options messages. We then use this field to populate the -// extensions when we build a descriptor, at which point all protos have been -// parsed and so all extensions are known. -// -// Extension numbers for custom options may be chosen as follows: -// * For options which will only be used within a single application or -// organization, or for experimental options, use field numbers 50000 -// through 99999. It is up to you to ensure that you do not use the -// same number for multiple options. -// * For options which will be published and used publicly by multiple -// independent entities, e-mail kenton@google.com to reserve extension -// numbers. Simply tell me how many you need and I'll send you back a -// set of numbers to use -- there's no need to explain how you intend to -// use them. If this turns out to be popular, a web service will be set up -// to automatically assign option numbers. - - -message FileOptions { - - // Sets the Java package where classes generated from this .proto will be - // placed. By default, the proto package is used, but this is often - // inappropriate because proto packages do not normally start with backwards - // domain names. - optional string java_package = 1; - - - // If set, all the classes from the .proto file are wrapped in a single - // outer class with the given name. This applies to both Proto1 - // (equivalent to the old "--one_java_file" option) and Proto2 (where - // a .proto always translates to a single class, but you may want to - // explicitly choose the class name). - optional string java_outer_classname = 8; - - // If set true, then the Java code generator will generate a separate .java - // file for each top-level message, enum, and service defined in the .proto - // file. Thus, these types will *not* be nested inside the outer class - // named by java_outer_classname. However, the outer class will still be - // generated to contain the file's getDescriptor() method as well as any - // top-level extensions defined in the file. - optional bool java_multiple_files = 10 [default=false]; - - // Generated classes can be optimized for speed or code size. - enum OptimizeMode { - SPEED = 1; // Generate complete code for parsing, serialization, - // etc. - CODE_SIZE = 2; // Use ReflectionOps to implement these methods. - LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. - } - optional OptimizeMode optimize_for = 9 [default=SPEED]; - - - - - // Should generic services be generated in each language? "Generic" services - // are not specific to any particular RPC system. They are generated by the - // main code generators in each language (without additional plugins). - // Generic services were the only kind of service generation supported by - // early versions of proto2. - // - // Generic services are now considered deprecated in favor of using plugins - // that generate code specific to your particular RPC system. If you are - // using such a plugin, set these to false. In the future, we may change - // the default to false, so if you explicitly want generic services, you - // should explicitly set these to true. - optional bool cc_generic_services = 16 [default=true]; - optional bool java_generic_services = 17 [default=true]; - optional bool py_generic_services = 18 [default=true]; - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message MessageOptions { - // Set true to use the old proto1 MessageSet wire format for extensions. - // This is provided for backwards-compatibility with the MessageSet wire - // format. You should not use this for any other reason: It's less - // efficient, has fewer features, and is more complicated. - // - // The message must be defined exactly as follows: - // message Foo { - // option message_set_wire_format = true; - // extensions 4 to max; - // } - // Note that the message cannot have any defined fields; MessageSets only - // have extensions. - // - // All extensions of your type must be singular messages; e.g. they cannot - // be int32s, enums, or repeated messages. - // - // Because this is an option, the above two restrictions are not enforced by - // the protocol compiler. - optional bool message_set_wire_format = 1 [default=false]; - - // Disables the generation of the standard "descriptor()" accessor, which can - // conflict with a field of the same name. This is meant to make migration - // from proto1 easier; new code should avoid fields named "descriptor". - optional bool no_standard_descriptor_accessor = 2 [default=false]; - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message FieldOptions { - // The ctype option instructs the C++ code generator to use a different - // representation of the field than it normally would. See the specific - // options below. This option is not yet implemented in the open source - // release -- sorry, we'll try to include it in a future version! - optional CType ctype = 1 [default = STRING]; - enum CType { - // Default mode. - STRING = 0; - - CORD = 1; - - STRING_PIECE = 2; - } - // The packed option can be enabled for repeated primitive fields to enable - // a more efficient representation on the wire. Rather than repeatedly - // writing the tag and type for each element, the entire array is encoded as - // a single length-delimited blob. - optional bool packed = 2; - - - // Is this field deprecated? - // Depending on the target platform, this can emit Deprecated annotations - // for accessors, or it will be completely ignored; in the very least, this - // is a formalization for deprecating fields. - optional bool deprecated = 3 [default=false]; - - // EXPERIMENTAL. DO NOT USE. - // For "map" fields, the name of the field in the enclosed type that - // is the key for this map. For example, suppose we have: - // message Item { - // required string name = 1; - // required string value = 2; - // } - // message Config { - // repeated Item items = 1 [experimental_map_key="name"]; - // } - // In this situation, the map key for Item will be set to "name". - // TODO: Fully-implement this, then remove the "experimental_" prefix. - optional string experimental_map_key = 9; - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message EnumOptions { - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message EnumValueOptions { - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message ServiceOptions { - - // Note: Field numbers 1 through 32 are reserved for Google's internal RPC - // framework. We apologize for hoarding these numbers to ourselves, but - // we were already using them long before we decided to release Protocol - // Buffers. - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -message MethodOptions { - - // Note: Field numbers 1 through 32 are reserved for Google's internal RPC - // framework. We apologize for hoarding these numbers to ourselves, but - // we were already using them long before we decided to release Protocol - // Buffers. - - // The parser stores options it doesn't recognize here. See above. - repeated UninterpretedOption uninterpreted_option = 999; - - // Clients can define custom options in extensions of this message. See above. - extensions 1000 to max; -} - -// A message representing a option the parser does not recognize. This only -// appears in options protos created by the compiler::Parser class. -// DescriptorPool resolves these when building Descriptor objects. Therefore, -// options protos in descriptor objects (e.g. returned by Descriptor::options(), -// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions -// in them. -message UninterpretedOption { - // The name of the uninterpreted option. Each string represents a segment in - // a dot-separated name. is_extension is true iff a segment represents an - // extension (denoted with parentheses in options specs in .proto files). - // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents - // "foo.(bar.baz).qux". - message NamePart { - required string name_part = 1; - required bool is_extension = 2; - } - repeated NamePart name = 2; - - // The value of the uninterpreted option, in whatever type the tokenizer - // identified it as during parsing. Exactly one of these should be set. - optional string identifier_value = 3; - optional uint64 positive_int_value = 4; - optional int64 negative_int_value = 5; - optional double double_value = 6; - optional bytes string_value = 7; -} diff --git a/Resources/NetHook/google/protobuf/descriptor_database.cc b/Resources/NetHook/google/protobuf/descriptor_database.cc deleted file mode 100644 index 95708d94..00000000 --- a/Resources/NetHook/google/protobuf/descriptor_database.cc +++ /dev/null @@ -1,541 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -#include - -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -DescriptorDatabase::~DescriptorDatabase() {} - -// =================================================================== - -template -bool SimpleDescriptorDatabase::DescriptorIndex::AddFile( - const FileDescriptorProto& file, - Value value) { - if (!InsertIfNotPresent(&by_name_, file.name(), value)) { - GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name(); - return false; - } - - // We must be careful here -- calling file.package() if file.has_package() is - // false could access an uninitialized static-storage variable if we are being - // run at startup time. - string path = file.has_package() ? file.package() : string(); - if (!path.empty()) path += '.'; - - for (int i = 0; i < file.message_type_size(); i++) { - if (!AddSymbol(path + file.message_type(i).name(), value)) return false; - if (!AddNestedExtensions(file.message_type(i), value)) return false; - } - for (int i = 0; i < file.enum_type_size(); i++) { - if (!AddSymbol(path + file.enum_type(i).name(), value)) return false; - } - for (int i = 0; i < file.extension_size(); i++) { - if (!AddSymbol(path + file.extension(i).name(), value)) return false; - if (!AddExtension(file.extension(i), value)) return false; - } - for (int i = 0; i < file.service_size(); i++) { - if (!AddSymbol(path + file.service(i).name(), value)) return false; - } - - return true; -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::AddSymbol( - const string& name, Value value) { - // We need to make sure not to violate our map invariant. - - // If the symbol name is invalid it could break our lookup algorithm (which - // relies on the fact that '.' sorts before all other characters that are - // valid in symbol names). - if (!ValidateSymbolName(name)) { - GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name; - return false; - } - - // Try to look up the symbol to make sure a super-symbol doesn't already - // exist. - typename map::iterator iter = FindLastLessOrEqual(name); - - if (iter == by_symbol_.end()) { - // Apparently the map is currently empty. Just insert and be done with it. - by_symbol_.insert(make_pair(name, value)); - return true; - } - - if (IsSubSymbol(iter->first, name)) { - GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing " - "symbol \"" << iter->first << "\"."; - return false; - } - - // OK, that worked. Now we have to make sure that no symbol in the map is - // a sub-symbol of the one we are inserting. The only symbol which could - // be so is the first symbol that is greater than the new symbol. Since - // |iter| points at the last symbol that is less than or equal, we just have - // to increment it. - ++iter; - - if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) { - GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing " - "symbol \"" << iter->first << "\"."; - return false; - } - - // OK, no conflicts. - - // Insert the new symbol using the iterator as a hint, the new entry will - // appear immediately before the one the iterator is pointing at. - by_symbol_.insert(iter, make_pair(name, value)); - - return true; -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::AddNestedExtensions( - const DescriptorProto& message_type, - Value value) { - for (int i = 0; i < message_type.nested_type_size(); i++) { - if (!AddNestedExtensions(message_type.nested_type(i), value)) return false; - } - for (int i = 0; i < message_type.extension_size(); i++) { - if (!AddExtension(message_type.extension(i), value)) return false; - } - return true; -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::AddExtension( - const FieldDescriptorProto& field, - Value value) { - if (!field.extendee().empty() && field.extendee()[0] == '.') { - // The extension is fully-qualified. We can use it as a lookup key in - // the by_symbol_ table. - if (!InsertIfNotPresent(&by_extension_, - make_pair(field.extendee().substr(1), - field.number()), - value)) { - GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: " - "extend " << field.extendee() << " { " - << field.name() << " = " << field.number() << " }"; - return false; - } - } else { - // Not fully-qualified. We can't really do anything here, unfortunately. - // We don't consider this an error, though, because the descriptor is - // valid. - } - return true; -} - -template -Value SimpleDescriptorDatabase::DescriptorIndex::FindFile( - const string& filename) { - return FindWithDefault(by_name_, filename, Value()); -} - -template -Value SimpleDescriptorDatabase::DescriptorIndex::FindSymbol( - const string& name) { - typename map::iterator iter = FindLastLessOrEqual(name); - - return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ? - iter->second : Value(); -} - -template -Value SimpleDescriptorDatabase::DescriptorIndex::FindExtension( - const string& containing_type, - int field_number) { - return FindWithDefault(by_extension_, - make_pair(containing_type, field_number), - Value()); -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( - const string& containing_type, - vector* output) { - typename map, Value >::const_iterator it = - by_extension_.lower_bound(make_pair(containing_type, 0)); - bool success = false; - - for (; it != by_extension_.end() && it->first.first == containing_type; - ++it) { - output->push_back(it->first.second); - success = true; - } - - return success; -} - -template -typename map::iterator -SimpleDescriptorDatabase::DescriptorIndex::FindLastLessOrEqual( - const string& name) { - // Find the last key in the map which sorts less than or equal to the - // symbol name. Since upper_bound() returns the *first* key that sorts - // *greater* than the input, we want the element immediately before that. - typename map::iterator iter = by_symbol_.upper_bound(name); - if (iter != by_symbol_.begin()) --iter; - return iter; -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::IsSubSymbol( - const string& sub_symbol, const string& super_symbol) { - return sub_symbol == super_symbol || - (HasPrefixString(super_symbol, sub_symbol) && - super_symbol[sub_symbol.size()] == '.'); -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::ValidateSymbolName( - const string& name) { - for (int i = 0; i < name.size(); i++) { - // I don't trust ctype.h due to locales. :( - if (name[i] != '.' && name[i] != '_' && - (name[i] < '0' || name[i] > '9') && - (name[i] < 'A' || name[i] > 'Z') && - (name[i] < 'a' || name[i] > 'z')) { - return false; - } - } - return true; -} - -// ------------------------------------------------------------------- - -SimpleDescriptorDatabase::SimpleDescriptorDatabase() {} -SimpleDescriptorDatabase::~SimpleDescriptorDatabase() { - STLDeleteElements(&files_to_delete_); -} - -bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) { - FileDescriptorProto* new_file = new FileDescriptorProto; - new_file->CopyFrom(file); - return AddAndOwn(new_file); -} - -bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) { - files_to_delete_.push_back(file); - return index_.AddFile(*file, file); -} - -bool SimpleDescriptorDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - return MaybeCopy(index_.FindFile(filename), output); -} - -bool SimpleDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - return MaybeCopy(index_.FindSymbol(symbol_name), output); -} - -bool SimpleDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return MaybeCopy(index_.FindExtension(containing_type, field_number), output); -} - -bool SimpleDescriptorDatabase::FindAllExtensionNumbers( - const string& extendee_type, - vector* output) { - return index_.FindAllExtensionNumbers(extendee_type, output); -} - -bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file, - FileDescriptorProto* output) { - if (file == NULL) return false; - output->CopyFrom(*file); - return true; -} - -// ------------------------------------------------------------------- - -EncodedDescriptorDatabase::EncodedDescriptorDatabase() {} -EncodedDescriptorDatabase::~EncodedDescriptorDatabase() { - for (int i = 0; i < files_to_delete_.size(); i++) { - operator delete(files_to_delete_[i]); - } -} - -bool EncodedDescriptorDatabase::Add( - const void* encoded_file_descriptor, int size) { - FileDescriptorProto file; - if (file.ParseFromArray(encoded_file_descriptor, size)) { - return index_.AddFile(file, make_pair(encoded_file_descriptor, size)); - } else { - GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " - "EncodedDescriptorDatabase::Add()."; - return false; - } -} - -bool EncodedDescriptorDatabase::AddCopy( - const void* encoded_file_descriptor, int size) { - void* copy = operator new(size); - memcpy(copy, encoded_file_descriptor, size); - files_to_delete_.push_back(copy); - return Add(copy, size); -} - -bool EncodedDescriptorDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - return MaybeParse(index_.FindFile(filename), output); -} - -bool EncodedDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - return MaybeParse(index_.FindSymbol(symbol_name), output); -} - -bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( - const string& symbol_name, - string* output) { - pair encoded_file = index_.FindSymbol(symbol_name); - if (encoded_file.first == NULL) return false; - - // Optimization: The name should be the first field in the encoded message. - // Try to just read it directly. - io::CodedInputStream input(reinterpret_cast(encoded_file.first), - encoded_file.second); - - const uint32 kNameTag = internal::WireFormatLite::MakeTag( - FileDescriptorProto::kNameFieldNumber, - internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - - if (input.ReadTag() == kNameTag) { - // Success! - return internal::WireFormatLite::ReadString(&input, output); - } else { - // Slow path. Parse whole message. - FileDescriptorProto file_proto; - if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) { - return false; - } - *output = file_proto.name(); - return true; - } -} - -bool EncodedDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return MaybeParse(index_.FindExtension(containing_type, field_number), - output); -} - -bool EncodedDescriptorDatabase::FindAllExtensionNumbers( - const string& extendee_type, - vector* output) { - return index_.FindAllExtensionNumbers(extendee_type, output); -} - -bool EncodedDescriptorDatabase::MaybeParse( - pair encoded_file, - FileDescriptorProto* output) { - if (encoded_file.first == NULL) return false; - return output->ParseFromArray(encoded_file.first, encoded_file.second); -} - -// =================================================================== - -DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool) - : pool_(pool) {} -DescriptorPoolDatabase::~DescriptorPoolDatabase() {} - -bool DescriptorPoolDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - const FileDescriptor* file = pool_.FindFileByName(filename); - if (file == NULL) return false; - output->Clear(); - file->CopyTo(output); - return true; -} - -bool DescriptorPoolDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name); - if (file == NULL) return false; - output->Clear(); - file->CopyTo(output); - return true; -} - -bool DescriptorPoolDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type); - if (extendee == NULL) return false; - - const FieldDescriptor* extension = - pool_.FindExtensionByNumber(extendee, field_number); - if (extension == NULL) return false; - - output->Clear(); - extension->file()->CopyTo(output); - return true; -} - -bool DescriptorPoolDatabase::FindAllExtensionNumbers( - const string& extendee_type, - vector* output) { - const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type); - if (extendee == NULL) return false; - - vector extensions; - pool_.FindAllExtensions(extendee, &extensions); - - for (int i = 0; i < extensions.size(); ++i) { - output->push_back(extensions[i]->number()); - } - - return true; -} - -// =================================================================== - -MergedDescriptorDatabase::MergedDescriptorDatabase( - DescriptorDatabase* source1, - DescriptorDatabase* source2) { - sources_.push_back(source1); - sources_.push_back(source2); -} -MergedDescriptorDatabase::MergedDescriptorDatabase( - const vector& sources) - : sources_(sources) {} -MergedDescriptorDatabase::~MergedDescriptorDatabase() {} - -bool MergedDescriptorDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileByName(filename, output)) { - return true; - } - } - return false; -} - -bool MergedDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { - // The symbol was found in source i. However, if one of the previous - // sources defines a file with the same name (which presumably doesn't - // contain the symbol, since it wasn't found in that source), then we - // must hide it from the caller. - FileDescriptorProto temp; - for (int j = 0; j < i; j++) { - if (sources_[j]->FindFileByName(output->name(), &temp)) { - // Found conflicting file in a previous source. - return false; - } - } - return true; - } - } - return false; -} - -bool MergedDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileContainingExtension( - containing_type, field_number, output)) { - // The symbol was found in source i. However, if one of the previous - // sources defines a file with the same name (which presumably doesn't - // contain the symbol, since it wasn't found in that source), then we - // must hide it from the caller. - FileDescriptorProto temp; - for (int j = 0; j < i; j++) { - if (sources_[j]->FindFileByName(output->name(), &temp)) { - // Found conflicting file in a previous source. - return false; - } - } - return true; - } - } - return false; -} - -bool MergedDescriptorDatabase::FindAllExtensionNumbers( - const string& extendee_type, - vector* output) { - set merged_results; - vector results; - bool success = false; - - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { - copy(results.begin(), results.end(), - insert_iterator >(merged_results, merged_results.begin())); - success = true; - } - results.clear(); - } - - copy(merged_results.begin(), merged_results.end(), - insert_iterator >(*output, output->end())); - - return success; -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/descriptor_database.h b/Resources/NetHook/google/protobuf/descriptor_database.h deleted file mode 100644 index f32b1db9..00000000 --- a/Resources/NetHook/google/protobuf/descriptor_database.h +++ /dev/null @@ -1,366 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Interface for manipulating databases of descriptors. - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ -#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ - -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -// Defined in this file. -class DescriptorDatabase; -class SimpleDescriptorDatabase; -class EncodedDescriptorDatabase; -class DescriptorPoolDatabase; -class MergedDescriptorDatabase; - -// Abstract interface for a database of descriptors. -// -// This is useful if you want to create a DescriptorPool which loads -// descriptors on-demand from some sort of large database. If the database -// is large, it may be inefficient to enumerate every .proto file inside it -// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool -// can be created which wraps a DescriptorDatabase and only builds particular -// descriptors when they are needed. -class LIBPROTOBUF_EXPORT DescriptorDatabase { - public: - inline DescriptorDatabase() {} - virtual ~DescriptorDatabase(); - - // Find a file by file name. Fills in in *output and returns true if found. - // Otherwise, returns false, leaving the contents of *output undefined. - virtual bool FindFileByName(const string& filename, - FileDescriptorProto* output) = 0; - - // Find the file that declares the given fully-qualified symbol name. - // If found, fills in *output and returns true, otherwise returns false - // and leaves *output undefined. - virtual bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) = 0; - - // Find the file which defines an extension extending the given message type - // with the given field number. If found, fills in *output and returns true, - // otherwise returns false and leaves *output undefined. containing_type - // must be a fully-qualified type name. - virtual bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) = 0; - - // Finds the tag numbers used by all known extensions of - // extendee_type, and appends them to output in an undefined - // order. This method is best-effort: it's not guaranteed that the - // database will find all extensions, and it's not guaranteed that - // FindFileContainingExtension will return true on all of the found - // numbers. Returns true if the search was successful, otherwise - // returns false and leaves output unchanged. - // - // This method has a default implementation that always returns - // false. - virtual bool FindAllExtensionNumbers(const string& extendee_type, - vector* output) { - return false; - } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); -}; - -// A DescriptorDatabase into which you can insert files manually. -// -// FindFileContainingSymbol() is fully-implemented. When you add a file, its -// symbols will be indexed for this purpose. Note that the implementation -// may return false positives, but only if it isn't possible for the symbol -// to be defined in any other file. In particular, if a file defines a symbol -// "Foo", then searching for "Foo.[anything]" will match that file. This way, -// the database does not need to aggressively index all children of a symbol. -// -// FindFileContainingExtension() is mostly-implemented. It works if and only -// if the original FieldDescriptorProto defining the extension has a -// fully-qualified type name in its "extendee" field (i.e. starts with a '.'). -// If the extendee is a relative name, SimpleDescriptorDatabase will not -// attempt to resolve the type, so it will not know what type the extension is -// extending. Therefore, calling FindFileContainingExtension() with the -// extension's containing type will never actually find that extension. Note -// that this is an unlikely problem, as all FileDescriptorProtos created by the -// protocol compiler (as well as ones created by calling -// FileDescriptor::CopyTo()) will always use fully-qualified names for all -// types. You only need to worry if you are constructing FileDescriptorProtos -// yourself, or are calling compiler::Parser directly. -class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { - public: - SimpleDescriptorDatabase(); - ~SimpleDescriptorDatabase(); - - // Adds the FileDescriptorProto to the database, making a copy. The object - // can be deleted after Add() returns. Returns false if the file conflicted - // with a file already in the database, in which case an error will have - // been written to GOOGLE_LOG(ERROR). - bool Add(const FileDescriptorProto& file); - - // Adds the FileDescriptorProto to the database and takes ownership of it. - bool AddAndOwn(const FileDescriptorProto* file); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - bool FindAllExtensionNumbers(const string& extendee_type, - vector* output); - - private: - // So that it can use DescriptorIndex. - friend class EncodedDescriptorDatabase; - - // An index mapping file names, symbol names, and extension numbers to - // some sort of values. - template - class DescriptorIndex { - public: - // Helpers to recursively add particular descriptors and all their contents - // to the index. - bool AddFile(const FileDescriptorProto& file, - Value value); - bool AddSymbol(const string& name, Value value); - bool AddNestedExtensions(const DescriptorProto& message_type, - Value value); - bool AddExtension(const FieldDescriptorProto& field, - Value value); - - Value FindFile(const string& filename); - Value FindSymbol(const string& name); - Value FindExtension(const string& containing_type, int field_number); - bool FindAllExtensionNumbers(const string& containing_type, - vector* output); - - private: - map by_name_; - map by_symbol_; - map, Value> by_extension_; - - // Invariant: The by_symbol_ map does not contain any symbols which are - // prefixes of other symbols in the map. For example, "foo.bar" is a - // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz"). - // - // This invariant is important because it means that given a symbol name, - // we can find a key in the map which is a prefix of the symbol in O(lg n) - // time, and we know that there is at most one such key. - // - // The prefix lookup algorithm works like so: - // 1) Find the last key in the map which is less than or equal to the - // search key. - // 2) If the found key is a prefix of the search key, then return it. - // Otherwise, there is no match. - // - // I am sure this algorithm has been described elsewhere, but since I - // wasn't able to find it quickly I will instead prove that it works - // myself. The key to the algorithm is that if a match exists, step (1) - // will find it. Proof: - // 1) Define the "search key" to be the key we are looking for, the "found - // key" to be the key found in step (1), and the "match key" to be the - // key which actually matches the serach key (i.e. the key we're trying - // to find). - // 2) The found key must be less than or equal to the search key by - // definition. - // 3) The match key must also be less than or equal to the search key - // (because it is a prefix). - // 4) The match key cannot be greater than the found key, because if it - // were, then step (1) of the algorithm would have returned the match - // key instead (since it finds the *greatest* key which is less than or - // equal to the search key). - // 5) Therefore, the found key must be between the match key and the search - // key, inclusive. - // 6) Since the search key must be a sub-symbol of the match key, if it is - // not equal to the match key, then search_key[match_key.size()] must - // be '.'. - // 7) Since '.' sorts before any other character that is valid in a symbol - // name, then if the found key is not equal to the match key, then - // found_key[match_key.size()] must also be '.', because any other value - // would make it sort after the search key. - // 8) Therefore, if the found key is not equal to the match key, then the - // found key must be a sub-symbol of the match key. However, this would - // contradict our map invariant which says that no symbol in the map is - // a sub-symbol of any other. - // 9) Therefore, the found key must match the match key. - // - // The above proof assumes the match key exists. In the case that the - // match key does not exist, then step (1) will return some other symbol. - // That symbol cannot be a super-symbol of the search key since if it were, - // then it would be a match, and we're assuming the match key doesn't exist. - // Therefore, step 2 will correctly return no match. - - // Find the last entry in the by_symbol_ map whose key is less than or - // equal to the given name. - typename map::iterator FindLastLessOrEqual( - const string& name); - - // True if either the arguments are equal or super_symbol identifies a - // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of - // "foo.bar.baz", but not a parent of "foo.barbaz"). - bool IsSubSymbol(const string& sub_symbol, const string& super_symbol); - - // Returns true if and only if all characters in the name are alphanumerics, - // underscores, or periods. - bool ValidateSymbolName(const string& name); - }; - - - DescriptorIndex index_; - vector files_to_delete_; - - // If file is non-NULL, copy it into *output and return true, otherwise - // return false. - bool MaybeCopy(const FileDescriptorProto* file, - FileDescriptorProto* output); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase); -}; - -// Very similar to SimpleDescriptorDatabase, but stores all the descriptors -// as raw bytes and generally tries to use as little memory as possible. -// -// The same caveats regarding FindFileContainingExtension() apply as with -// SimpleDescriptorDatabase. -class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { - public: - EncodedDescriptorDatabase(); - ~EncodedDescriptorDatabase(); - - // Adds the FileDescriptorProto to the database. The descriptor is provided - // in encoded form. The database does not make a copy of the bytes, nor - // does it take ownership; it's up to the caller to make sure the bytes - // remain valid for the life of the database. Returns false and logs an error - // if the bytes are not a valid FileDescriptorProto or if the file conflicted - // with a file already in the database. - bool Add(const void* encoded_file_descriptor, int size); - - // Like Add(), but makes a copy of the data, so that the caller does not - // need to keep it around. - bool AddCopy(const void* encoded_file_descriptor, int size); - - // Like FindFileContainingSymbol but returns only the name of the file. - bool FindNameOfFileContainingSymbol(const string& symbol_name, - string* output); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - bool FindAllExtensionNumbers(const string& extendee_type, - vector* output); - - private: - SimpleDescriptorDatabase::DescriptorIndex > index_; - vector files_to_delete_; - - // If encoded_file.first is non-NULL, parse the data into *output and return - // true, otherwise return false. - bool MaybeParse(pair encoded_file, - FileDescriptorProto* output); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase); -}; - -// A DescriptorDatabase that fetches files from a given pool. -class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { - public: - DescriptorPoolDatabase(const DescriptorPool& pool); - ~DescriptorPoolDatabase(); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - bool FindAllExtensionNumbers(const string& extendee_type, - vector* output); - - private: - const DescriptorPool& pool_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase); -}; - -// A DescriptorDatabase that wraps two or more others. It first searches the -// first database and, if that fails, tries the second, and so on. -class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { - public: - // Merge just two databases. The sources remain property of the caller. - MergedDescriptorDatabase(DescriptorDatabase* source1, - DescriptorDatabase* source2); - // Merge more than two databases. The sources remain property of the caller. - // The vector may be deleted after the constructor returns but the - // DescriptorDatabases need to stick around. - MergedDescriptorDatabase(const vector& sources); - ~MergedDescriptorDatabase(); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - // Merges the results of calling all databases. Returns true iff any - // of the databases returned true. - bool FindAllExtensionNumbers(const string& extendee_type, - vector* output); - - private: - vector sources_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ diff --git a/Resources/NetHook/google/protobuf/descriptor_database_unittest.cc b/Resources/NetHook/google/protobuf/descriptor_database_unittest.cc deleted file mode 100644 index ac72ddcd..00000000 --- a/Resources/NetHook/google/protobuf/descriptor_database_unittest.cc +++ /dev/null @@ -1,748 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file makes extensive use of RFC 3092. :) - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace { - -static void AddToDatabase(SimpleDescriptorDatabase* database, - const char* file_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - database->Add(file_proto); -} - -static void ExpectContainsType(const FileDescriptorProto& proto, - const string& type_name) { - for (int i = 0; i < proto.message_type_size(); i++) { - if (proto.message_type(i).name() == type_name) return; - } - ADD_FAILURE() << "\"" << proto.name() - << "\" did not contain expected type \"" - << type_name << "\"."; -} - -// =================================================================== - -#if GTEST_HAS_PARAM_TEST - -// SimpleDescriptorDatabase, EncodedDescriptorDatabase, and -// DescriptorPoolDatabase call for very similar tests. Instead of writing -// three nearly-identical sets of tests, we use parameterized tests to apply -// the same code to all three. - -// The parameterized test runs against a DescriptarDatabaseTestCase. We have -// implementations for each of the three classes we want to test. -class DescriptorDatabaseTestCase { - public: - virtual ~DescriptorDatabaseTestCase() {} - - virtual DescriptorDatabase* GetDatabase() = 0; - virtual bool AddToDatabase(const FileDescriptorProto& file) = 0; -}; - -// Factory function type. -typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory(); - -// Specialization for SimpleDescriptorDatabase. -class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase { - public: - static DescriptorDatabaseTestCase* New() { - return new SimpleDescriptorDatabaseTestCase; - } - - virtual ~SimpleDescriptorDatabaseTestCase() {} - - virtual DescriptorDatabase* GetDatabase() { - return &database_; - } - virtual bool AddToDatabase(const FileDescriptorProto& file) { - return database_.Add(file); - } - - private: - SimpleDescriptorDatabase database_; -}; - -// Specialization for EncodedDescriptorDatabase. -class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase { - public: - static DescriptorDatabaseTestCase* New() { - return new EncodedDescriptorDatabaseTestCase; - } - - virtual ~EncodedDescriptorDatabaseTestCase() {} - - virtual DescriptorDatabase* GetDatabase() { - return &database_; - } - virtual bool AddToDatabase(const FileDescriptorProto& file) { - string data; - file.SerializeToString(&data); - return database_.AddCopy(data.data(), data.size()); - } - - private: - EncodedDescriptorDatabase database_; -}; - -// Specialization for DescriptorPoolDatabase. -class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase { - public: - static DescriptorDatabaseTestCase* New() { - return new EncodedDescriptorDatabaseTestCase; - } - - DescriptorPoolDatabaseTestCase() : database_(pool_) {} - virtual ~DescriptorPoolDatabaseTestCase() {} - - virtual DescriptorDatabase* GetDatabase() { - return &database_; - } - virtual bool AddToDatabase(const FileDescriptorProto& file) { - return pool_.BuildFile(file); - } - - private: - DescriptorPool pool_; - DescriptorPoolDatabase database_; -}; - -// ------------------------------------------------------------------- - -class DescriptorDatabaseTest - : public testing::TestWithParam { - protected: - virtual void SetUp() { - test_case_.reset(GetParam()()); - database_ = test_case_->GetDatabase(); - } - - void AddToDatabase(const char* file_descriptor_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto)); - EXPECT_TRUE(test_case_->AddToDatabase(file_proto)); - } - - void AddToDatabaseWithError(const char* file_descriptor_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto)); - EXPECT_FALSE(test_case_->AddToDatabase(file_proto)); - } - - scoped_ptr test_case_; - DescriptorDatabase* database_; -}; - -TEST_P(DescriptorDatabaseTest, FindFileByName) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { name:\"Foo\" }"); - AddToDatabase( - "name: \"bar.proto\" " - "message_type { name:\"Bar\" }"); - - { - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileByName("foo.proto", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileByName("bar.proto", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // Fails to find undefined files. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileByName("baz.proto", &file)); - } -} - -TEST_P(DescriptorDatabaseTest, FindFileContainingSymbol) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " field { name:\"qux\" }" - " nested_type { name: \"Grault\" } " - " enum_type { name: \"Garply\" } " - "} " - "enum_type { " - " name: \"Waldo\" " - " value { name:\"FRED\" } " - "} " - "extension { name: \"plugh\" } " - "service { " - " name: \"Xyzzy\" " - " method { name: \"Thud\" } " - "}" - ); - AddToDatabase( - "name: \"bar.proto\" " - "package: \"corge\" " - "message_type { name: \"Bar\" }"); - - { - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Foo", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find fields. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.qux", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find nested types. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Grault", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find nested enums. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Garply", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find enum types. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find enum values. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo.FRED", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find extensions. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("plugh", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find services. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find methods. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy.Thud", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find things in packages. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingSymbol("corge.Bar", &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Fails to find undefined symbols. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileContainingSymbol("Baz", &file)); - } - - { - // Names must be fully-qualified. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileContainingSymbol("Bar", &file)); - } -} - -TEST_P(DescriptorDatabaseTest, FindFileContainingExtension) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " extension_range { start: 1 end: 1000 } " - " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \".Foo\" }" - "}"); - AddToDatabase( - "name: \"bar.proto\" " - "package: \"corge\" " - "dependency: \"foo.proto\" " - "message_type { " - " name: \"Bar\" " - " extension_range { start: 1 end: 1000 } " - "} " - "extension { name:\"grault\" extendee: \".Foo\" number:32 } " - "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } " - "extension { name:\"waldo\" extendee: \"Bar\" number:56 } "); - - { - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 5, &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 32, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can find extensions for qualified type names. - FileDescriptorProto file; - EXPECT_TRUE(database_->FindFileContainingExtension("corge.Bar", 70, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can't find extensions whose extendee was not fully-qualified in the - // FileDescriptorProto. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 56, &file)); - EXPECT_FALSE( - database_->FindFileContainingExtension("corge.Bar", 56, &file)); - } - - { - // Can't find non-existent extension numbers. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileContainingExtension("Foo", 12, &file)); - } - - { - // Can't find extensions for non-existent types. - FileDescriptorProto file; - EXPECT_FALSE( - database_->FindFileContainingExtension("NoSuchType", 5, &file)); - } - - { - // Can't find extensions for unqualified type names. - FileDescriptorProto file; - EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 70, &file)); - } -} - -TEST_P(DescriptorDatabaseTest, FindAllExtensionNumbers) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " extension_range { start: 1 end: 1000 } " - " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \".Foo\" }" - "}"); - AddToDatabase( - "name: \"bar.proto\" " - "package: \"corge\" " - "dependency: \"foo.proto\" " - "message_type { " - " name: \"Bar\" " - " extension_range { start: 1 end: 1000 } " - "} " - "extension { name:\"grault\" extendee: \".Foo\" number:32 } " - "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } " - "extension { name:\"waldo\" extendee: \"Bar\" number:56 } "); - - { - vector numbers; - EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers)); - ASSERT_EQ(2, numbers.size()); - sort(numbers.begin(), numbers.end()); - EXPECT_EQ(5, numbers[0]); - EXPECT_EQ(32, numbers[1]); - } - - { - vector numbers; - EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers)); - // Note: won't find extension 56 due to the name not being fully qualified. - ASSERT_EQ(1, numbers.size()); - EXPECT_EQ(70, numbers[0]); - } - - { - // Can't find extensions for non-existent types. - vector numbers; - EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers)); - } - - { - // Can't find extensions for unqualified types. - vector numbers; - EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers)); - } -} - -TEST_P(DescriptorDatabaseTest, ConflictingFileError) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - "}"); - AddToDatabaseWithError( - "name: \"foo.proto\" " - "message_type { " - " name: \"Bar\" " - "}"); -} - -TEST_P(DescriptorDatabaseTest, ConflictingTypeError) { - AddToDatabase( - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - "}"); - AddToDatabaseWithError( - "name: \"bar.proto\" " - "message_type { " - " name: \"Foo\" " - "}"); -} - -TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) { - AddToDatabase( - "name: \"foo.proto\" " - "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \".Foo\" }"); - AddToDatabaseWithError( - "name: \"bar.proto\" " - "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \".Foo\" }"); -} - -INSTANTIATE_TEST_CASE_P(Simple, DescriptorDatabaseTest, - testing::Values(&SimpleDescriptorDatabaseTestCase::New)); -INSTANTIATE_TEST_CASE_P(MemoryConserving, DescriptorDatabaseTest, - testing::Values(&EncodedDescriptorDatabaseTestCase::New)); -INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest, - testing::Values(&DescriptorPoolDatabaseTestCase::New)); - -#endif // GTEST_HAS_PARAM_TEST - -TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) { - // Create two files, one of which is in two parts. - FileDescriptorProto file1, file2a, file2b; - file1.set_name("foo.proto"); - file1.set_package("foo"); - file1.add_message_type()->set_name("Foo"); - file2a.set_name("bar.proto"); - file2b.set_package("bar"); - file2b.add_message_type()->set_name("Bar"); - - // Normal serialization allows our optimization to kick in. - string data1 = file1.SerializeAsString(); - - // Force out-of-order serialization to test slow path. - string data2 = file2b.SerializeAsString() + file2a.SerializeAsString(); - - // Create EncodedDescriptorDatabase containing both files. - EncodedDescriptorDatabase db; - db.Add(data1.data(), data1.size()); - db.Add(data2.data(), data2.size()); - - // Test! - string filename; - EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename)); - EXPECT_EQ("foo.proto", filename); - EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename)); - EXPECT_EQ("foo.proto", filename); - EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename)); - EXPECT_EQ("bar.proto", filename); - EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename)); - EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename)); - EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename)); -} - -// =================================================================== - -class MergedDescriptorDatabaseTest : public testing::Test { - protected: - MergedDescriptorDatabaseTest() - : forward_merged_(&database1_, &database2_), - reverse_merged_(&database2_, &database1_) {} - - virtual void SetUp() { - AddToDatabase(&database1_, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } " - "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - AddToDatabase(&database2_, - "name: \"bar.proto\" " - "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } " - "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - - // baz.proto exists in both pools, with different definitions. - AddToDatabase(&database1_, - "name: \"baz.proto\" " - "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " - "message_type { name:\"FromPool1\" } " - "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } " - "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - AddToDatabase(&database2_, - "name: \"baz.proto\" " - "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " - "message_type { name:\"FromPool2\" } " - "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - } - - SimpleDescriptorDatabase database1_; - SimpleDescriptorDatabase database2_; - - MergedDescriptorDatabase forward_merged_; - MergedDescriptorDatabase reverse_merged_; -}; - -TEST_F(MergedDescriptorDatabaseTest, FindFileByName) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // Can't find non-existent file. - FileDescriptorProto file; - EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file)); - } -} - -TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // FromPool1 only shows up in forward_merged_ because it is masked by - // database2_'s baz.proto in reverse_merged_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file)); - EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file)); - } - - { - // Can't find non-existent symbol. - FileDescriptorProto file; - EXPECT_FALSE( - forward_merged_.FindFileContainingSymbol("NoSuchType", &file)); - } -} - -TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Foo", 3, &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Bar", 5, &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Baz", 12, &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE( - reverse_merged_.FindFileContainingExtension("Baz", 12, &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // Baz's extension 13 only shows up in forward_merged_ because it is - // masked by database2_'s baz.proto in reverse_merged_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file)); - EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file)); - } - - { - // Can't find non-existent extension. - FileDescriptorProto file; - EXPECT_FALSE( - forward_merged_.FindFileContainingExtension("Foo", 6, &file)); - } -} - -TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) { - { - // Message only has extension in database1_ - vector numbers; - EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers)); - ASSERT_EQ(1, numbers.size()); - EXPECT_EQ(3, numbers[0]); - } - - { - // Message only has extension in database2_ - vector numbers; - EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers)); - ASSERT_EQ(1, numbers.size()); - EXPECT_EQ(5, numbers[0]); - } - - { - // Merge results from the two databases. - vector numbers; - EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers)); - ASSERT_EQ(2, numbers.size()); - sort(numbers.begin(), numbers.end()); - EXPECT_EQ(12, numbers[0]); - EXPECT_EQ(13, numbers[1]); - } - - { - vector numbers; - EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers)); - ASSERT_EQ(2, numbers.size()); - sort(numbers.begin(), numbers.end()); - EXPECT_EQ(12, numbers[0]); - EXPECT_EQ(13, numbers[1]); - } - - { - // Can't find extensions for a non-existent message. - vector numbers; - EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers)); - } -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/descriptor_unittest.cc b/Resources/NetHook/google/protobuf/descriptor_unittest.cc deleted file mode 100644 index ec2c8152..00000000 --- a/Resources/NetHook/google/protobuf/descriptor_unittest.cc +++ /dev/null @@ -1,3956 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file makes extensive use of RFC 3092. :) - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { - -// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. -namespace descriptor_unittest { - -// Some helpers to make assembling descriptors faster. -DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) { - DescriptorProto* result = file->add_message_type(); - result->set_name(name); - return result; -} - -DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) { - DescriptorProto* result = parent->add_nested_type(); - result->set_name(name); - return result; -} - -EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) { - EnumDescriptorProto* result = file->add_enum_type(); - result->set_name(name); - return result; -} - -EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent, - const string& name) { - EnumDescriptorProto* result = parent->add_enum_type(); - result->set_name(name); - return result; -} - -ServiceDescriptorProto* AddService(FileDescriptorProto* file, - const string& name) { - ServiceDescriptorProto* result = file->add_service(); - result->set_name(name); - return result; -} - -FieldDescriptorProto* AddField(DescriptorProto* parent, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = parent->add_field(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - return result; -} - -FieldDescriptorProto* AddExtension(FileDescriptorProto* file, - const string& extendee, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = file->add_extension(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - result->set_extendee(extendee); - return result; -} - -FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent, - const string& extendee, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = parent->add_extension(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - result->set_extendee(extendee); - return result; -} - -DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent, - int start, int end) { - DescriptorProto::ExtensionRange* result = parent->add_extension_range(); - result->set_start(start); - result->set_end(end); - return result; -} - -EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto, - const string& name, int number) { - EnumValueDescriptorProto* result = enum_proto->add_value(); - result->set_name(name); - result->set_number(number); - return result; -} - -MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service, - const string& name, - const string& input_type, - const string& output_type) { - MethodDescriptorProto* result = service->add_method(); - result->set_name(name); - result->set_input_type(input_type); - result->set_output_type(output_type); - return result; -} - -// Empty enums technically aren't allowed. We need to insert a dummy value -// into them. -void AddEmptyEnum(FileDescriptorProto* file, const string& name) { - AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1); -} - -// =================================================================== - -// Test simple files. -class FileDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message FooMessage { extensions 1; } - // enum FooEnum {FOO_ENUM_VALUE = 1;} - // service FooService {} - // extend FooMessage { optional int32 foo_extension = 1; } - // - // // in "bar.proto" - // package bar_package; - // message BarMessage { extensions 1; } - // enum BarEnum {BAR_ENUM_VALUE = 1;} - // service BarService {} - // extend BarMessage { optional int32 bar_extension = 1; } - // - // Also, we have an empty file "baz.proto". This file's purpose is to - // make sure that even though it has the same package as foo.proto, - // searching it for members of foo.proto won't work. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2); - AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1); - AddService(&foo_file, "FooService"); - AddExtension(&foo_file, "FooMessage", "foo_extension", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("bar_package"); - bar_file.add_dependency("foo.proto"); - AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2); - AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1); - AddService(&bar_file, "BarService"); - AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FileDescriptorProto baz_file; - baz_file.set_name("baz.proto"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - baz_file_ = pool_.BuildFile(baz_file); - ASSERT_TRUE(baz_file_ != NULL); - - ASSERT_EQ(1, foo_file_->message_type_count()); - foo_message_ = foo_file_->message_type(0); - ASSERT_EQ(1, foo_file_->enum_type_count()); - foo_enum_ = foo_file_->enum_type(0); - ASSERT_EQ(1, foo_enum_->value_count()); - foo_enum_value_ = foo_enum_->value(0); - ASSERT_EQ(1, foo_file_->service_count()); - foo_service_ = foo_file_->service(0); - ASSERT_EQ(1, foo_file_->extension_count()); - foo_extension_ = foo_file_->extension(0); - - ASSERT_EQ(1, bar_file_->message_type_count()); - bar_message_ = bar_file_->message_type(0); - ASSERT_EQ(1, bar_file_->enum_type_count()); - bar_enum_ = bar_file_->enum_type(0); - ASSERT_EQ(1, bar_enum_->value_count()); - bar_enum_value_ = bar_enum_->value(0); - ASSERT_EQ(1, bar_file_->service_count()); - bar_service_ = bar_file_->service(0); - ASSERT_EQ(1, bar_file_->extension_count()); - bar_extension_ = bar_file_->extension(0); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - const FileDescriptor* baz_file_; - - const Descriptor* foo_message_; - const EnumDescriptor* foo_enum_; - const EnumValueDescriptor* foo_enum_value_; - const ServiceDescriptor* foo_service_; - const FieldDescriptor* foo_extension_; - - const Descriptor* bar_message_; - const EnumDescriptor* bar_enum_; - const EnumValueDescriptor* bar_enum_value_; - const ServiceDescriptor* bar_service_; - const FieldDescriptor* bar_extension_; -}; - -TEST_F(FileDescriptorTest, Name) { - EXPECT_EQ("foo.proto", foo_file_->name()); - EXPECT_EQ("bar.proto", bar_file_->name()); - EXPECT_EQ("baz.proto", baz_file_->name()); -} - -TEST_F(FileDescriptorTest, Package) { - EXPECT_EQ("", foo_file_->package()); - EXPECT_EQ("bar_package", bar_file_->package()); -} - -TEST_F(FileDescriptorTest, Dependencies) { - EXPECT_EQ(0, foo_file_->dependency_count()); - EXPECT_EQ(1, bar_file_->dependency_count()); - EXPECT_EQ(foo_file_, bar_file_->dependency(0)); -} - -TEST_F(FileDescriptorTest, FindMessageTypeByName) { - EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage")); - EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage")); - - EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL); - EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL); - EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL); - - EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL); - EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL); -} - -TEST_F(FileDescriptorTest, FindEnumTypeByName) { - EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum")); - EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum")); - - EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL); - EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL); - EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL); - - EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL); - EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindEnumValueByName) { - EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE")); - EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE")); - - EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL); - EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); - EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); - - EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindServiceByName) { - EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService")); - EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService")); - - EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL); - EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL); - EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL); - - EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL); - EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindExtensionByName) { - EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension")); - EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension")); - - EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL); - EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL); - EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL); - - EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindExtensionByNumber) { - EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1)); - EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1)); - - EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL); -} - -TEST_F(FileDescriptorTest, BuildAgain) { - // Test that if te call BuildFile again on the same input we get the same - // FileDescriptor back. - FileDescriptorProto file; - foo_file_->CopyTo(&file); - EXPECT_EQ(foo_file_, pool_.BuildFile(file)); - - // But if we change the file then it won't work. - file.set_package("some.other.package"); - EXPECT_TRUE(pool_.BuildFile(file) == NULL); -} - -// =================================================================== - -// Test simple flat messages and fields. -class DescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message TestForeign {} - // enum TestEnum {} - // - // message TestMessage { - // required string foo = 1; - // optional TestEnum bar = 6; - // repeated TestForeign baz = 500000000; - // optional group qux = 15 {} - // } - // - // // in "bar.proto" - // package corge.grault; - // message TestMessage2 { - // required string foo = 1; - // required string bar = 2; - // required string quux = 6; - // } - // - // We cheat and use TestForeign as the type for qux rather than create - // an actual nested type. - // - // Since all primitive types (including string) use the same building - // code, there's no need to test each one individually. - // - // TestMessage2 is primarily here to test FindFieldByName and friends. - // All messages created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - AddMessage(&foo_file, "TestForeign"); - AddEmptyEnum(&foo_file, "TestEnum"); - - DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); - AddField(message, "foo", 1, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message, "bar", 6, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_ENUM) - ->set_type_name("TestEnum"); - AddField(message, "baz", 500000000, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_MESSAGE) - ->set_type_name("TestForeign"); - AddField(message, "qux", 15, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_GROUP) - ->set_type_name("TestForeign"); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); - AddField(message2, "foo", 1, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message2, "bar", 2, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message2, "quux", 6, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - enum_ = foo_file_->enum_type(0); - - ASSERT_EQ(2, foo_file_->message_type_count()); - foreign_ = foo_file_->message_type(0); - message_ = foo_file_->message_type(1); - - ASSERT_EQ(4, message_->field_count()); - foo_ = message_->field(0); - bar_ = message_->field(1); - baz_ = message_->field(2); - qux_ = message_->field(3); - - ASSERT_EQ(1, bar_file_->message_type_count()); - message2_ = bar_file_->message_type(0); - - ASSERT_EQ(3, message2_->field_count()); - foo2_ = message2_->field(0); - bar2_ = message2_->field(1); - quux2_ = message2_->field(2); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* message_; - const Descriptor* message2_; - const Descriptor* foreign_; - const EnumDescriptor* enum_; - - const FieldDescriptor* foo_; - const FieldDescriptor* bar_; - const FieldDescriptor* baz_; - const FieldDescriptor* qux_; - - const FieldDescriptor* foo2_; - const FieldDescriptor* bar2_; - const FieldDescriptor* quux2_; -}; - -TEST_F(DescriptorTest, Name) { - EXPECT_EQ("TestMessage", message_->name()); - EXPECT_EQ("TestMessage", message_->full_name()); - EXPECT_EQ(foo_file_, message_->file()); - - EXPECT_EQ("TestMessage2", message2_->name()); - EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name()); - EXPECT_EQ(bar_file_, message2_->file()); -} - -TEST_F(DescriptorTest, ContainingType) { - EXPECT_TRUE(message_->containing_type() == NULL); - EXPECT_TRUE(message2_->containing_type() == NULL); -} - -TEST_F(DescriptorTest, FieldsByIndex) { - ASSERT_EQ(4, message_->field_count()); - EXPECT_EQ(foo_, message_->field(0)); - EXPECT_EQ(bar_, message_->field(1)); - EXPECT_EQ(baz_, message_->field(2)); - EXPECT_EQ(qux_, message_->field(3)); -} - -TEST_F(DescriptorTest, FindFieldByName) { - // All messages in the same DescriptorPool share a single lookup table for - // fields. So, in addition to testing that FindFieldByName finds the fields - // of the message, we need to test that it does *not* find the fields of - // *other* messages. - - EXPECT_EQ(foo_, message_->FindFieldByName("foo")); - EXPECT_EQ(bar_, message_->FindFieldByName("bar")); - EXPECT_EQ(baz_, message_->FindFieldByName("baz")); - EXPECT_EQ(qux_, message_->FindFieldByName("qux")); - EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL); - EXPECT_TRUE(message_->FindFieldByName("quux") == NULL); - - EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" )); - EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" )); - EXPECT_EQ(quux2_, message2_->FindFieldByName("quux")); - EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL); - EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL); -} - -TEST_F(DescriptorTest, FindFieldByNumber) { - EXPECT_EQ(foo_, message_->FindFieldByNumber(1)); - EXPECT_EQ(bar_, message_->FindFieldByNumber(6)); - EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000)); - EXPECT_EQ(qux_, message_->FindFieldByNumber(15)); - EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL); - EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL); - - EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1)); - EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2)); - EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6)); - EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL); - EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL); -} - -TEST_F(DescriptorTest, FieldName) { - EXPECT_EQ("foo", foo_->name()); - EXPECT_EQ("bar", bar_->name()); - EXPECT_EQ("baz", baz_->name()); - EXPECT_EQ("qux", qux_->name()); -} - -TEST_F(DescriptorTest, FieldFullName) { - EXPECT_EQ("TestMessage.foo", foo_->full_name()); - EXPECT_EQ("TestMessage.bar", bar_->full_name()); - EXPECT_EQ("TestMessage.baz", baz_->full_name()); - EXPECT_EQ("TestMessage.qux", qux_->full_name()); - - EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); -} - -TEST_F(DescriptorTest, FieldFile) { - EXPECT_EQ(foo_file_, foo_->file()); - EXPECT_EQ(foo_file_, bar_->file()); - EXPECT_EQ(foo_file_, baz_->file()); - EXPECT_EQ(foo_file_, qux_->file()); - - EXPECT_EQ(bar_file_, foo2_->file()); - EXPECT_EQ(bar_file_, bar2_->file()); - EXPECT_EQ(bar_file_, quux2_->file()); -} - -TEST_F(DescriptorTest, FieldIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); - EXPECT_EQ(2, baz_->index()); - EXPECT_EQ(3, qux_->index()); -} - -TEST_F(DescriptorTest, FieldNumber) { - EXPECT_EQ( 1, foo_->number()); - EXPECT_EQ( 6, bar_->number()); - EXPECT_EQ(500000000, baz_->number()); - EXPECT_EQ( 15, qux_->number()); -} - -TEST_F(DescriptorTest, FieldType) { - EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_ENUM , bar_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_GROUP , qux_->type()); -} - -TEST_F(DescriptorTest, FieldLabel) { - EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label()); - - EXPECT_TRUE (foo_->is_required()); - EXPECT_FALSE(foo_->is_optional()); - EXPECT_FALSE(foo_->is_repeated()); - - EXPECT_FALSE(bar_->is_required()); - EXPECT_TRUE (bar_->is_optional()); - EXPECT_FALSE(bar_->is_repeated()); - - EXPECT_FALSE(baz_->is_required()); - EXPECT_FALSE(baz_->is_optional()); - EXPECT_TRUE (baz_->is_repeated()); -} - -TEST_F(DescriptorTest, FieldHasDefault) { - EXPECT_FALSE(foo_->has_default_value()); - EXPECT_FALSE(bar_->has_default_value()); - EXPECT_FALSE(baz_->has_default_value()); - EXPECT_FALSE(qux_->has_default_value()); -} - -TEST_F(DescriptorTest, FieldContainingType) { - EXPECT_EQ(message_, foo_->containing_type()); - EXPECT_EQ(message_, bar_->containing_type()); - EXPECT_EQ(message_, baz_->containing_type()); - EXPECT_EQ(message_, qux_->containing_type()); - - EXPECT_EQ(message2_, foo2_ ->containing_type()); - EXPECT_EQ(message2_, bar2_ ->containing_type()); - EXPECT_EQ(message2_, quux2_->containing_type()); -} - -TEST_F(DescriptorTest, FieldMessageType) { - EXPECT_TRUE(foo_->message_type() == NULL); - EXPECT_TRUE(bar_->message_type() == NULL); - - EXPECT_EQ(foreign_, baz_->message_type()); - EXPECT_EQ(foreign_, qux_->message_type()); -} - -TEST_F(DescriptorTest, FieldEnumType) { - EXPECT_TRUE(foo_->enum_type() == NULL); - EXPECT_TRUE(baz_->enum_type() == NULL); - EXPECT_TRUE(qux_->enum_type() == NULL); - - EXPECT_EQ(enum_, bar_->enum_type()); -} - -// =================================================================== - -class StylizedFieldNamesTest : public testing::Test { - protected: - void SetUp() { - FileDescriptorProto file; - file.set_name("foo.proto"); - - AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000); - - DescriptorProto* message = AddMessage(&file, "TestMessage"); - AddField(message, "foo_foo", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddField(message, "FooBar", 2, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddField(message, "fooBaz", 3, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo. - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddField(message, "foobar", 5, // Lower-case conflict with FooBar. - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddNestedExtension(message, "ExtendableMessage", "BarBar", 2, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - AddExtension(&file, "ExtendableMessage", "baz_foo", 11, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&file, "ExtendableMessage", "BazBar", 12, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&file, "ExtendableMessage", "BazBaz", 13, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - file_ = pool_.BuildFile(file); - ASSERT_TRUE(file_ != NULL); - ASSERT_EQ(2, file_->message_type_count()); - message_ = file_->message_type(1); - ASSERT_EQ("TestMessage", message_->name()); - ASSERT_EQ(5, message_->field_count()); - ASSERT_EQ(5, message_->extension_count()); - ASSERT_EQ(5, file_->extension_count()); - } - - DescriptorPool pool_; - const FileDescriptor* file_; - const Descriptor* message_; -}; - -TEST_F(StylizedFieldNamesTest, LowercaseName) { - EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name()); - EXPECT_EQ("foobar" , message_->field(1)->lowercase_name()); - EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name()); - EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name()); - EXPECT_EQ("foobar" , message_->field(4)->lowercase_name()); - - EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name()); - EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name()); - EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name()); - EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name()); - EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name()); - - EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name()); - EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name()); - EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name()); - EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name()); - EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name()); -} - -TEST_F(StylizedFieldNamesTest, CamelcaseName) { - EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name()); - EXPECT_EQ("fooBar", message_->field(1)->camelcase_name()); - EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name()); - EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name()); - EXPECT_EQ("foobar", message_->field(4)->camelcase_name()); - - EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name()); - EXPECT_EQ("barBar", message_->extension(1)->camelcase_name()); - EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name()); - EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name()); - EXPECT_EQ("barbar", message_->extension(4)->camelcase_name()); - - EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name()); - EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name()); - EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name()); - EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name()); - EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name()); -} - -TEST_F(StylizedFieldNamesTest, FindByLowercaseName) { - EXPECT_EQ(message_->field(0), - message_->FindFieldByLowercaseName("foo_foo")); - EXPECT_EQ(message_->field(1), - message_->FindFieldByLowercaseName("foobar")); - EXPECT_EQ(message_->field(2), - message_->FindFieldByLowercaseName("foobaz")); - EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL); - EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL); - EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL); - EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL); - - EXPECT_EQ(message_->extension(0), - message_->FindExtensionByLowercaseName("bar_foo")); - EXPECT_EQ(message_->extension(1), - message_->FindExtensionByLowercaseName("barbar")); - EXPECT_EQ(message_->extension(2), - message_->FindExtensionByLowercaseName("barbaz")); - EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL); - EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL); - EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL); - EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL); - - EXPECT_EQ(file_->extension(0), - file_->FindExtensionByLowercaseName("baz_foo")); - EXPECT_EQ(file_->extension(1), - file_->FindExtensionByLowercaseName("bazbar")); - EXPECT_EQ(file_->extension(2), - file_->FindExtensionByLowercaseName("bazbaz")); - EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL); - EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL); - EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL); -} - -TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) { - EXPECT_EQ(message_->field(0), - message_->FindFieldByCamelcaseName("fooFoo")); - EXPECT_EQ(message_->field(1), - message_->FindFieldByCamelcaseName("fooBar")); - EXPECT_EQ(message_->field(2), - message_->FindFieldByCamelcaseName("fooBaz")); - EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL); - EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL); - EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL); - EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL); - - EXPECT_EQ(message_->extension(0), - message_->FindExtensionByCamelcaseName("barFoo")); - EXPECT_EQ(message_->extension(1), - message_->FindExtensionByCamelcaseName("barBar")); - EXPECT_EQ(message_->extension(2), - message_->FindExtensionByCamelcaseName("barBaz")); - EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL); - EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL); - EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL); - EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL); - - EXPECT_EQ(file_->extension(0), - file_->FindExtensionByCamelcaseName("bazFoo")); - EXPECT_EQ(file_->extension(1), - file_->FindExtensionByCamelcaseName("bazBar")); - EXPECT_EQ(file_->extension(2), - file_->FindExtensionByCamelcaseName("bazBaz")); - EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL); - EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL); - EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL); -} - -// =================================================================== - -// Test enum descriptors. -class EnumDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // enum TestEnum { - // FOO = 1; - // BAR = 2; - // } - // - // // in "bar.proto" - // package corge.grault; - // enum TestEnum2 { - // FOO = 1; - // BAZ = 3; - // } - // - // TestEnum2 is primarily here to test FindValueByName and friends. - // All enums created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - - // TestEnum - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum"); - AddEnumValue(enum_proto, "FOO", 1); - AddEnumValue(enum_proto, "BAR", 2); - - // TestEnum2 - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2"); - AddEnumValue(enum2_proto, "FOO", 1); - AddEnumValue(enum2_proto, "BAZ", 3); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - enum_ = foo_file_->enum_type(0); - - ASSERT_EQ(2, enum_->value_count()); - foo_ = enum_->value(0); - bar_ = enum_->value(1); - - ASSERT_EQ(1, bar_file_->enum_type_count()); - enum2_ = bar_file_->enum_type(0); - - ASSERT_EQ(2, enum2_->value_count()); - foo2_ = enum2_->value(0); - baz2_ = enum2_->value(1); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const EnumDescriptor* enum_; - const EnumDescriptor* enum2_; - - const EnumValueDescriptor* foo_; - const EnumValueDescriptor* bar_; - - const EnumValueDescriptor* foo2_; - const EnumValueDescriptor* baz2_; -}; - -TEST_F(EnumDescriptorTest, Name) { - EXPECT_EQ("TestEnum", enum_->name()); - EXPECT_EQ("TestEnum", enum_->full_name()); - EXPECT_EQ(foo_file_, enum_->file()); - - EXPECT_EQ("TestEnum2", enum2_->name()); - EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name()); - EXPECT_EQ(bar_file_, enum2_->file()); -} - -TEST_F(EnumDescriptorTest, ContainingType) { - EXPECT_TRUE(enum_->containing_type() == NULL); - EXPECT_TRUE(enum2_->containing_type() == NULL); -} - -TEST_F(EnumDescriptorTest, ValuesByIndex) { - ASSERT_EQ(2, enum_->value_count()); - EXPECT_EQ(foo_, enum_->value(0)); - EXPECT_EQ(bar_, enum_->value(1)); -} - -TEST_F(EnumDescriptorTest, FindValueByName) { - EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO")); - EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR")); - EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO")); - EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ")); - - EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(enum_ ->FindValueByName("BAZ" ) == NULL); - EXPECT_TRUE(enum2_->FindValueByName("BAR" ) == NULL); -} - -TEST_F(EnumDescriptorTest, FindValueByNumber) { - EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1)); - EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2)); - EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1)); - EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3)); - - EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL); - EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL); - EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL); -} - -TEST_F(EnumDescriptorTest, ValueName) { - EXPECT_EQ("FOO", foo_->name()); - EXPECT_EQ("BAR", bar_->name()); -} - -TEST_F(EnumDescriptorTest, ValueFullName) { - EXPECT_EQ("FOO", foo_->full_name()); - EXPECT_EQ("BAR", bar_->full_name()); - EXPECT_EQ("corge.grault.FOO", foo2_->full_name()); - EXPECT_EQ("corge.grault.BAZ", baz2_->full_name()); -} - -TEST_F(EnumDescriptorTest, ValueIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); -} - -TEST_F(EnumDescriptorTest, ValueNumber) { - EXPECT_EQ(1, foo_->number()); - EXPECT_EQ(2, bar_->number()); -} - -TEST_F(EnumDescriptorTest, ValueType) { - EXPECT_EQ(enum_ , foo_ ->type()); - EXPECT_EQ(enum_ , bar_ ->type()); - EXPECT_EQ(enum2_, foo2_->type()); - EXPECT_EQ(enum2_, baz2_->type()); -} - -// =================================================================== - -// Test service descriptors. -class ServiceDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following messages and service: - // // in "foo.proto" - // message FooRequest {} - // message FooResponse {} - // message BarRequest {} - // message BarResponse {} - // message BazRequest {} - // message BazResponse {} - // - // service TestService { - // rpc Foo(FooRequest) returns (FooResponse); - // rpc Bar(BarRequest) returns (BarResponse); - // } - // - // // in "bar.proto" - // package corge.grault - // service TestService2 { - // rpc Foo(FooRequest) returns (FooResponse); - // rpc Baz(BazRequest) returns (BazResponse); - // } - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - AddMessage(&foo_file, "FooRequest"); - AddMessage(&foo_file, "FooResponse"); - AddMessage(&foo_file, "BarRequest"); - AddMessage(&foo_file, "BarResponse"); - AddMessage(&foo_file, "BazRequest"); - AddMessage(&foo_file, "BazResponse"); - - ServiceDescriptorProto* service = AddService(&foo_file, "TestService"); - AddMethod(service, "Foo", "FooRequest", "FooResponse"); - AddMethod(service, "Bar", "BarRequest", "BarResponse"); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - bar_file.add_dependency("foo.proto"); - - ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2"); - AddMethod(service2, "Foo", "FooRequest", "FooResponse"); - AddMethod(service2, "Baz", "BazRequest", "BazResponse"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(6, foo_file_->message_type_count()); - foo_request_ = foo_file_->message_type(0); - foo_response_ = foo_file_->message_type(1); - bar_request_ = foo_file_->message_type(2); - bar_response_ = foo_file_->message_type(3); - baz_request_ = foo_file_->message_type(4); - baz_response_ = foo_file_->message_type(5); - - ASSERT_EQ(1, foo_file_->service_count()); - service_ = foo_file_->service(0); - - ASSERT_EQ(2, service_->method_count()); - foo_ = service_->method(0); - bar_ = service_->method(1); - - ASSERT_EQ(1, bar_file_->service_count()); - service2_ = bar_file_->service(0); - - ASSERT_EQ(2, service2_->method_count()); - foo2_ = service2_->method(0); - baz2_ = service2_->method(1); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* foo_request_; - const Descriptor* foo_response_; - const Descriptor* bar_request_; - const Descriptor* bar_response_; - const Descriptor* baz_request_; - const Descriptor* baz_response_; - - const ServiceDescriptor* service_; - const ServiceDescriptor* service2_; - - const MethodDescriptor* foo_; - const MethodDescriptor* bar_; - - const MethodDescriptor* foo2_; - const MethodDescriptor* baz2_; -}; - -TEST_F(ServiceDescriptorTest, Name) { - EXPECT_EQ("TestService", service_->name()); - EXPECT_EQ("TestService", service_->full_name()); - EXPECT_EQ(foo_file_, service_->file()); - - EXPECT_EQ("TestService2", service2_->name()); - EXPECT_EQ("corge.grault.TestService2", service2_->full_name()); - EXPECT_EQ(bar_file_, service2_->file()); -} - -TEST_F(ServiceDescriptorTest, MethodsByIndex) { - ASSERT_EQ(2, service_->method_count()); - EXPECT_EQ(foo_, service_->method(0)); - EXPECT_EQ(bar_, service_->method(1)); -} - -TEST_F(ServiceDescriptorTest, FindMethodByName) { - EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo")); - EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar")); - EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo")); - EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz")); - - EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL); - EXPECT_TRUE(service_ ->FindMethodByName("Baz" ) == NULL); - EXPECT_TRUE(service2_->FindMethodByName("Bar" ) == NULL); -} - -TEST_F(ServiceDescriptorTest, MethodName) { - EXPECT_EQ("Foo", foo_->name()); - EXPECT_EQ("Bar", bar_->name()); -} - -TEST_F(ServiceDescriptorTest, MethodFullName) { - EXPECT_EQ("TestService.Foo", foo_->full_name()); - EXPECT_EQ("TestService.Bar", bar_->full_name()); - EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name()); -} - -TEST_F(ServiceDescriptorTest, MethodIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); -} - -TEST_F(ServiceDescriptorTest, MethodParent) { - EXPECT_EQ(service_, foo_->service()); - EXPECT_EQ(service_, bar_->service()); -} - -TEST_F(ServiceDescriptorTest, MethodInputType) { - EXPECT_EQ(foo_request_, foo_->input_type()); - EXPECT_EQ(bar_request_, bar_->input_type()); -} - -TEST_F(ServiceDescriptorTest, MethodOutputType) { - EXPECT_EQ(foo_response_, foo_->output_type()); - EXPECT_EQ(bar_response_, bar_->output_type()); -} - -// =================================================================== - -// Test nested types. -class NestedDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message TestMessage { - // message Foo {} - // message Bar {} - // enum Baz { A = 1; } - // enum Qux { B = 1; } - // } - // - // // in "bar.proto" - // package corge.grault; - // message TestMessage2 { - // message Foo {} - // message Baz {} - // enum Qux { A = 1; } - // enum Quux { C = 1; } - // } - // - // TestMessage2 is primarily here to test FindNestedTypeByName and friends. - // All messages created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - // - // We add enum values to the enums in order to test searching for enum - // values across a message's scope. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); - AddNestedMessage(message, "Foo"); - AddNestedMessage(message, "Bar"); - EnumDescriptorProto* baz = AddNestedEnum(message, "Baz"); - AddEnumValue(baz, "A", 1); - EnumDescriptorProto* qux = AddNestedEnum(message, "Qux"); - AddEnumValue(qux, "B", 1); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); - AddNestedMessage(message2, "Foo"); - AddNestedMessage(message2, "Baz"); - EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux"); - AddEnumValue(qux2, "A", 1); - EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux"); - AddEnumValue(quux2, "C", 1); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->message_type_count()); - message_ = foo_file_->message_type(0); - - ASSERT_EQ(2, message_->nested_type_count()); - foo_ = message_->nested_type(0); - bar_ = message_->nested_type(1); - - ASSERT_EQ(2, message_->enum_type_count()); - baz_ = message_->enum_type(0); - qux_ = message_->enum_type(1); - - ASSERT_EQ(1, baz_->value_count()); - a_ = baz_->value(0); - ASSERT_EQ(1, qux_->value_count()); - b_ = qux_->value(0); - - ASSERT_EQ(1, bar_file_->message_type_count()); - message2_ = bar_file_->message_type(0); - - ASSERT_EQ(2, message2_->nested_type_count()); - foo2_ = message2_->nested_type(0); - baz2_ = message2_->nested_type(1); - - ASSERT_EQ(2, message2_->enum_type_count()); - qux2_ = message2_->enum_type(0); - quux2_ = message2_->enum_type(1); - - ASSERT_EQ(1, qux2_->value_count()); - a2_ = qux2_->value(0); - ASSERT_EQ(1, quux2_->value_count()); - c2_ = quux2_->value(0); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* message_; - const Descriptor* message2_; - - const Descriptor* foo_; - const Descriptor* bar_; - const EnumDescriptor* baz_; - const EnumDescriptor* qux_; - const EnumValueDescriptor* a_; - const EnumValueDescriptor* b_; - - const Descriptor* foo2_; - const Descriptor* baz2_; - const EnumDescriptor* qux2_; - const EnumDescriptor* quux2_; - const EnumValueDescriptor* a2_; - const EnumValueDescriptor* c2_; -}; - -TEST_F(NestedDescriptorTest, MessageName) { - EXPECT_EQ("Foo", foo_ ->name()); - EXPECT_EQ("Bar", bar_ ->name()); - EXPECT_EQ("Foo", foo2_->name()); - EXPECT_EQ("Baz", baz2_->name()); - - EXPECT_EQ("TestMessage.Foo", foo_->full_name()); - EXPECT_EQ("TestMessage.Bar", bar_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name()); -} - -TEST_F(NestedDescriptorTest, MessageContainingType) { - EXPECT_EQ(message_ , foo_ ->containing_type()); - EXPECT_EQ(message_ , bar_ ->containing_type()); - EXPECT_EQ(message2_, foo2_->containing_type()); - EXPECT_EQ(message2_, baz2_->containing_type()); -} - -TEST_F(NestedDescriptorTest, NestedMessagesByIndex) { - ASSERT_EQ(2, message_->nested_type_count()); - EXPECT_EQ(foo_, message_->nested_type(0)); - EXPECT_EQ(bar_, message_->nested_type(1)); -} - -TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) { - EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL); - EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL); - EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL); - EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL); -} - -TEST_F(NestedDescriptorTest, FindNestedTypeByName) { - EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo")); - EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar")); - EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo")); - EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz")); - - EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL); - EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz" ) == NULL); - EXPECT_TRUE(message2_->FindNestedTypeByName("Bar" ) == NULL); - - EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL); -} - -TEST_F(NestedDescriptorTest, EnumName) { - EXPECT_EQ("Baz" , baz_ ->name()); - EXPECT_EQ("Qux" , qux_ ->name()); - EXPECT_EQ("Qux" , qux2_->name()); - EXPECT_EQ("Quux", quux2_->name()); - - EXPECT_EQ("TestMessage.Baz", baz_->full_name()); - EXPECT_EQ("TestMessage.Qux", qux_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name()); -} - -TEST_F(NestedDescriptorTest, EnumContainingType) { - EXPECT_EQ(message_ , baz_ ->containing_type()); - EXPECT_EQ(message_ , qux_ ->containing_type()); - EXPECT_EQ(message2_, qux2_ ->containing_type()); - EXPECT_EQ(message2_, quux2_->containing_type()); -} - -TEST_F(NestedDescriptorTest, NestedEnumsByIndex) { - ASSERT_EQ(2, message_->nested_type_count()); - EXPECT_EQ(foo_, message_->nested_type(0)); - EXPECT_EQ(bar_, message_->nested_type(1)); -} - -TEST_F(NestedDescriptorTest, FindEnumTypeByName) { - EXPECT_EQ(baz_ , message_ ->FindEnumTypeByName("Baz" )); - EXPECT_EQ(qux_ , message_ ->FindEnumTypeByName("Qux" )); - EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" )); - EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux")); - - EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL); - EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux" ) == NULL); - EXPECT_TRUE(message2_->FindEnumTypeByName("Baz" ) == NULL); - - EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL); -} - -TEST_F(NestedDescriptorTest, FindEnumValueByName) { - EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A")); - EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B")); - EXPECT_EQ(a2_, message2_->FindEnumValueByName("A")); - EXPECT_EQ(c2_, message2_->FindEnumValueByName("C")); - - EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(message_ ->FindEnumValueByName("C" ) == NULL); - EXPECT_TRUE(message2_->FindEnumValueByName("B" ) == NULL); - - EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL); -} - -// =================================================================== - -// Test extensions. -class ExtensionDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // enum Baz {} - // message Qux {} - // - // message Foo { - // extensions 10 to 19; - // extensions 30 to 39; - // } - // extends Foo with optional int32 foo_int32 = 10; - // extends Foo with repeated TestEnum foo_enum = 19; - // message Bar { - // extends Foo with optional Qux foo_message = 30; - // // (using Qux as the group type) - // extends Foo with repeated group foo_group = 39; - // } - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - AddEmptyEnum(&foo_file, "Baz"); - AddMessage(&foo_file, "Qux"); - - DescriptorProto* foo = AddMessage(&foo_file, "Foo"); - AddExtensionRange(foo, 10, 20); - AddExtensionRange(foo, 30, 40); - - AddExtension(&foo_file, "Foo", "foo_int32", 10, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&foo_file, "Foo", "foo_enum", 19, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_ENUM) - ->set_type_name("Baz"); - - DescriptorProto* bar = AddMessage(&foo_file, "Bar"); - AddNestedExtension(bar, "Foo", "foo_message", 30, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_MESSAGE) - ->set_type_name("Qux"); - AddNestedExtension(bar, "Foo", "foo_group", 39, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_GROUP) - ->set_type_name("Qux"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - baz_ = foo_file_->enum_type(0); - - ASSERT_EQ(3, foo_file_->message_type_count()); - qux_ = foo_file_->message_type(0); - foo_ = foo_file_->message_type(1); - bar_ = foo_file_->message_type(2); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - - const Descriptor* foo_; - const Descriptor* bar_; - const EnumDescriptor* baz_; - const Descriptor* qux_; -}; - -TEST_F(ExtensionDescriptorTest, ExtensionRanges) { - EXPECT_EQ(0, bar_->extension_range_count()); - ASSERT_EQ(2, foo_->extension_range_count()); - - EXPECT_EQ(10, foo_->extension_range(0)->start); - EXPECT_EQ(30, foo_->extension_range(1)->start); - - EXPECT_EQ(20, foo_->extension_range(0)->end); - EXPECT_EQ(40, foo_->extension_range(1)->end); -}; - -TEST_F(ExtensionDescriptorTest, Extensions) { - EXPECT_EQ(0, foo_->extension_count()); - ASSERT_EQ(2, foo_file_->extension_count()); - ASSERT_EQ(2, bar_->extension_count()); - - EXPECT_TRUE(foo_file_->extension(0)->is_extension()); - EXPECT_TRUE(foo_file_->extension(1)->is_extension()); - EXPECT_TRUE(bar_->extension(0)->is_extension()); - EXPECT_TRUE(bar_->extension(1)->is_extension()); - - EXPECT_EQ("foo_int32" , foo_file_->extension(0)->name()); - EXPECT_EQ("foo_enum" , foo_file_->extension(1)->name()); - EXPECT_EQ("foo_message", bar_->extension(0)->name()); - EXPECT_EQ("foo_group" , bar_->extension(1)->name()); - - EXPECT_EQ(10, foo_file_->extension(0)->number()); - EXPECT_EQ(19, foo_file_->extension(1)->number()); - EXPECT_EQ(30, bar_->extension(0)->number()); - EXPECT_EQ(39, bar_->extension(1)->number()); - - EXPECT_EQ(FieldDescriptor::TYPE_INT32 , foo_file_->extension(0)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_ENUM , foo_file_->extension(1)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_GROUP , bar_->extension(1)->type()); - - EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type()); - EXPECT_EQ(qux_, bar_->extension(0)->message_type()); - EXPECT_EQ(qux_, bar_->extension(1)->message_type()); - - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label()); - - EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type()); - EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type()); - EXPECT_EQ(foo_, bar_->extension(0)->containing_type()); - EXPECT_EQ(foo_, bar_->extension(1)->containing_type()); - - EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL); - EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL); - EXPECT_EQ(bar_, bar_->extension(0)->extension_scope()); - EXPECT_EQ(bar_, bar_->extension(1)->extension_scope()); -}; - -TEST_F(ExtensionDescriptorTest, IsExtensionNumber) { - EXPECT_FALSE(foo_->IsExtensionNumber( 9)); - EXPECT_TRUE (foo_->IsExtensionNumber(10)); - EXPECT_TRUE (foo_->IsExtensionNumber(19)); - EXPECT_FALSE(foo_->IsExtensionNumber(20)); - EXPECT_FALSE(foo_->IsExtensionNumber(29)); - EXPECT_TRUE (foo_->IsExtensionNumber(30)); - EXPECT_TRUE (foo_->IsExtensionNumber(39)); - EXPECT_FALSE(foo_->IsExtensionNumber(40)); -} - -TEST_F(ExtensionDescriptorTest, FindExtensionByName) { - // Note that FileDescriptor::FindExtensionByName() is tested by - // FileDescriptorTest. - ASSERT_EQ(2, bar_->extension_count()); - - EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); - EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); - - EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); - EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); -} - -TEST_F(ExtensionDescriptorTest, FindAllExtensions) { - vector extensions; - pool_.FindAllExtensions(foo_, &extensions); - ASSERT_EQ(4, extensions.size()); - EXPECT_EQ(10, extensions[0]->number()); - EXPECT_EQ(19, extensions[1]->number()); - EXPECT_EQ(30, extensions[2]->number()); - EXPECT_EQ(39, extensions[3]->number()); -} - -// =================================================================== - -class MiscTest : public testing::Test { - protected: - // Function which makes a field of the given type just to find out what its - // cpp_type is. - FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) { - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - AddEmptyEnum(&file_proto, "DummyEnum"); - - DescriptorProto* message = AddMessage(&file_proto, "TestMessage"); - FieldDescriptorProto* field = - AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL, - static_cast(static_cast(type))); - - if (type == FieldDescriptor::TYPE_MESSAGE || - type == FieldDescriptor::TYPE_GROUP) { - field->set_type_name("TestMessage"); - } else if (type == FieldDescriptor::TYPE_ENUM) { - field->set_type_name("DummyEnum"); - } - - // Build the descriptors and get the pointers. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - - if (file != NULL && - file->message_type_count() == 1 && - file->message_type(0)->field_count() == 1) { - return file->message_type(0)->field(0)->cpp_type(); - } else { - return static_cast(0); - } - } -}; - -TEST_F(MiscTest, CppTypes) { - // Test that CPP types are assigned correctly. - - typedef FieldDescriptor FD; // avoid ugly line wrapping - - EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE )); - EXPECT_EQ(FD::CPPTYPE_FLOAT , GetCppTypeForFieldType(FD::TYPE_FLOAT )); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_INT64 )); - EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64 )); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_INT32 )); - EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 )); - EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 )); - EXPECT_EQ(FD::CPPTYPE_BOOL , GetCppTypeForFieldType(FD::TYPE_BOOL )); - EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING )); - EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP )); - EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE )); - EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES )); - EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32 )); - EXPECT_EQ(FD::CPPTYPE_ENUM , GetCppTypeForFieldType(FD::TYPE_ENUM )); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SFIXED32)); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SFIXED64)); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SINT32 )); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 )); -} - -TEST_F(MiscTest, DefaultValues) { - // Test that setting default values works. - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - - EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum"); - AddEnumValue(enum_type_proto, "A", 1); - AddEnumValue(enum_type_proto, "B", 2); - - DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); - - typedef FieldDescriptorProto FD; // avoid ugly line wrapping - const FD::Label label = FD::LABEL_OPTIONAL; - - // Create fields of every CPP type with default values. - AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 ) - ->set_default_value("-1"); - AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 ) - ->set_default_value("-1000000000000"); - AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32) - ->set_default_value("42"); - AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64) - ->set_default_value("2000000000000"); - AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT ) - ->set_default_value("4.5"); - AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE) - ->set_default_value("10e100"); - AddField(message_proto, "bool" , 7, label, FD::TYPE_BOOL ) - ->set_default_value("true"); - AddField(message_proto, "string", 8, label, FD::TYPE_STRING) - ->set_default_value("hello"); - AddField(message_proto, "data" , 9, label, FD::TYPE_BYTES ) - ->set_default_value("\\001\\002\\003"); - - FieldDescriptorProto* enum_field = - AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM); - enum_field->set_type_name("DummyEnum"); - enum_field->set_default_value("B"); - - // Strings are allowed to have empty defaults. (At one point, due to - // a bug, empty defaults for strings were rejected. Oops.) - AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING) - ->set_default_value(""); - - // Add a second set of fields with implicit defalut values. - AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 ); - AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 ); - AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32); - AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64); - AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT ); - AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE); - AddField(message_proto, "implicit_bool" , 27, label, FD::TYPE_BOOL ); - AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING); - AddField(message_proto, "implicit_data" , 29, label, FD::TYPE_BYTES ); - AddField(message_proto, "implicit_enum" , 30, label, FD::TYPE_ENUM) - ->set_type_name("DummyEnum"); - - // Build it. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->enum_type_count()); - const EnumDescriptor* enum_type = file->enum_type(0); - ASSERT_EQ(2, enum_type->value_count()); - const EnumValueDescriptor* enum_value_a = enum_type->value(0); - const EnumValueDescriptor* enum_value_b = enum_type->value(1); - - ASSERT_EQ(1, file->message_type_count()); - const Descriptor* message = file->message_type(0); - - ASSERT_EQ(21, message->field_count()); - - // Check the default values. - ASSERT_TRUE(message->field(0)->has_default_value()); - ASSERT_TRUE(message->field(1)->has_default_value()); - ASSERT_TRUE(message->field(2)->has_default_value()); - ASSERT_TRUE(message->field(3)->has_default_value()); - ASSERT_TRUE(message->field(4)->has_default_value()); - ASSERT_TRUE(message->field(5)->has_default_value()); - ASSERT_TRUE(message->field(6)->has_default_value()); - ASSERT_TRUE(message->field(7)->has_default_value()); - ASSERT_TRUE(message->field(8)->has_default_value()); - ASSERT_TRUE(message->field(9)->has_default_value()); - ASSERT_TRUE(message->field(10)->has_default_value()); - - EXPECT_EQ(-1 , message->field(0)->default_value_int32 ()); - EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000), - message->field(1)->default_value_int64 ()); - EXPECT_EQ(42 , message->field(2)->default_value_uint32()); - EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000), - message->field(3)->default_value_uint64()); - EXPECT_EQ(4.5 , message->field(4)->default_value_float ()); - EXPECT_EQ(10e100 , message->field(5)->default_value_double()); - EXPECT_EQ(true , message->field(6)->default_value_bool ()); - EXPECT_EQ("hello" , message->field(7)->default_value_string()); - EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string()); - EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ()); - EXPECT_EQ("" , message->field(10)->default_value_string()); - - ASSERT_FALSE(message->field(11)->has_default_value()); - ASSERT_FALSE(message->field(12)->has_default_value()); - ASSERT_FALSE(message->field(13)->has_default_value()); - ASSERT_FALSE(message->field(14)->has_default_value()); - ASSERT_FALSE(message->field(15)->has_default_value()); - ASSERT_FALSE(message->field(16)->has_default_value()); - ASSERT_FALSE(message->field(17)->has_default_value()); - ASSERT_FALSE(message->field(18)->has_default_value()); - ASSERT_FALSE(message->field(19)->has_default_value()); - ASSERT_FALSE(message->field(20)->has_default_value()); - - EXPECT_EQ(0 , message->field(11)->default_value_int32 ()); - EXPECT_EQ(0 , message->field(12)->default_value_int64 ()); - EXPECT_EQ(0 , message->field(13)->default_value_uint32()); - EXPECT_EQ(0 , message->field(14)->default_value_uint64()); - EXPECT_EQ(0.0f , message->field(15)->default_value_float ()); - EXPECT_EQ(0.0 , message->field(16)->default_value_double()); - EXPECT_EQ(false, message->field(17)->default_value_bool ()); - EXPECT_EQ("" , message->field(18)->default_value_string()); - EXPECT_EQ("" , message->field(19)->default_value_string()); - EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum()); -} - -TEST_F(MiscTest, FieldOptions) { - // Try setting field options. - - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - - DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); - AddField(message_proto, "foo", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - FieldDescriptorProto* bar_proto = - AddField(message_proto, "bar", 2, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FieldOptions* options = bar_proto->mutable_options(); - options->set_ctype(FieldOptions::CORD); - - // Build the descriptors and get the pointers. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->message_type_count()); - const Descriptor* message = file->message_type(0); - - ASSERT_EQ(2, message->field_count()); - const FieldDescriptor* foo = message->field(0); - const FieldDescriptor* bar = message->field(1); - - // "foo" had no options set, so it should return the default options. - EXPECT_EQ(&FieldOptions::default_instance(), &foo->options()); - - // "bar" had options set. - EXPECT_NE(&FieldOptions::default_instance(), options); - EXPECT_TRUE(bar->options().has_ctype()); - EXPECT_EQ(FieldOptions::CORD, bar->options().ctype()); -} - -// =================================================================== - -class AllowUnknownDependenciesTest : public testing::Test { - protected: - virtual void SetUp() { - FileDescriptorProto foo_proto, bar_proto; - - pool_.AllowUnknownDependencies(); - - ASSERT_TRUE(TextFormat::ParseFromString( - "name: 'foo.proto'" - "dependency: 'bar.proto'" - "dependency: 'baz.proto'" - "message_type {" - " name: 'Foo'" - " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }" - " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }" - " field { name:'qux' number:3 label:LABEL_OPTIONAL" - " type_name: '.corge.Qux'" - " type: TYPE_ENUM" - " options {" - " uninterpreted_option {" - " name {" - " name_part: 'grault'" - " is_extension: true" - " }" - " positive_int_value: 1234" - " }" - " }" - " }" - "}", - &foo_proto)); - ASSERT_TRUE(TextFormat::ParseFromString( - "name: 'bar.proto'" - "message_type { name: 'Bar' }", - &bar_proto)); - - // Collect pointers to stuff. - bar_file_ = pool_.BuildFile(bar_proto); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, bar_file_->message_type_count()); - bar_type_ = bar_file_->message_type(0); - - foo_file_ = pool_.BuildFile(foo_proto); - ASSERT_TRUE(foo_file_ != NULL); - - ASSERT_EQ(1, foo_file_->message_type_count()); - foo_type_ = foo_file_->message_type(0); - - ASSERT_EQ(3, foo_type_->field_count()); - bar_field_ = foo_type_->field(0); - baz_field_ = foo_type_->field(1); - qux_field_ = foo_type_->field(2); - } - - const FileDescriptor* bar_file_; - const Descriptor* bar_type_; - const FileDescriptor* foo_file_; - const Descriptor* foo_type_; - const FieldDescriptor* bar_field_; - const FieldDescriptor* baz_field_; - const FieldDescriptor* qux_field_; - - DescriptorPool pool_; -}; - -TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) { - ASSERT_EQ(2, foo_file_->dependency_count()); - EXPECT_EQ(bar_file_, foo_file_->dependency(0)); - - const FileDescriptor* baz_file = foo_file_->dependency(1); - EXPECT_EQ("baz.proto", baz_file->name()); - EXPECT_EQ(0, baz_file->message_type_count()); - - // Placeholder files should not be findable. - EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name())); - EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL); -} - -TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) { - ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type()); - EXPECT_EQ(bar_type_, bar_field_->message_type()); - - ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type()); - const Descriptor* baz_type = baz_field_->message_type(); - EXPECT_EQ("Baz", baz_type->name()); - EXPECT_EQ("Baz", baz_type->full_name()); - EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name()); - EXPECT_EQ(0, baz_type->extension_range_count()); - - ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type()); - const EnumDescriptor* qux_type = qux_field_->enum_type(); - EXPECT_EQ("Qux", qux_type->name()); - EXPECT_EQ("corge.Qux", qux_type->full_name()); - EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name()); - - // Placeholder types should not be findable. - EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name())); - EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL); - EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL); -} - -TEST_F(AllowUnknownDependenciesTest, CopyTo) { - // FieldDescriptor::CopyTo() should write non-fully-qualified type names - // for placeholder types which were not originally fully-qualified. - FieldDescriptorProto proto; - - // Bar is not a placeholder, so it is fully-qualified. - bar_field_->CopyTo(&proto); - EXPECT_EQ(".Bar", proto.type_name()); - EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type()); - - // Baz is an unqualified placeholder. - proto.Clear(); - baz_field_->CopyTo(&proto); - EXPECT_EQ("Baz", proto.type_name()); - EXPECT_FALSE(proto.has_type()); - - // Qux is a fully-qualified placeholder. - proto.Clear(); - qux_field_->CopyTo(&proto); - EXPECT_EQ(".corge.Qux", proto.type_name()); - EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type()); -} - -TEST_F(AllowUnknownDependenciesTest, CustomOptions) { - // Qux should still have the uninterpreted option attached. - ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size()); - const UninterpretedOption& option = - qux_field_->options().uninterpreted_option(0); - ASSERT_EQ(1, option.name_size()); - EXPECT_EQ("grault", option.name(0).name_part()); -} - -TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) { - // Test that we can extend an unknown type. This is slightly tricky because - // it means that the placeholder type must have an extension range. - - FileDescriptorProto extension_proto; - - ASSERT_TRUE(TextFormat::ParseFromString( - "name: 'extension.proto'" - "extension { extendee: 'UnknownType' name:'some_extension' number:123" - " label:LABEL_OPTIONAL type:TYPE_INT32 }", - &extension_proto)); - const FileDescriptor* file = pool_.BuildFile(extension_proto); - - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->extension_count()); - const Descriptor* extendee = file->extension(0)->containing_type(); - EXPECT_EQ("UnknownType", extendee->name()); - ASSERT_EQ(1, extendee->extension_range_count()); - EXPECT_EQ(1, extendee->extension_range(0)->start); - EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end); -} - -TEST_F(AllowUnknownDependenciesTest, CustomOption) { - // Test that we can use a custom option without having parsed - // descriptor.proto. - - FileDescriptorProto option_proto; - - ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"unknown_custom_options.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { " - " extendee: \"google.protobuf.FileOptions\" " - " name: \"some_option\" " - " number: 123456 " - " label: LABEL_OPTIONAL " - " type: TYPE_INT32 " - "} " - "options { " - " uninterpreted_option { " - " name { " - " name_part: \"some_option\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"unknown_option\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"optimize_for\" " - " is_extension: false " - " } " - " identifier_value: \"SPEED\" " - " } " - "}", - &option_proto)); - - const FileDescriptor* file = pool_.BuildFile(option_proto); - ASSERT_TRUE(file != NULL); - - // Verify that no extension options were set, but they were left as - // uninterpreted_options. - vector fields; - file->options().GetReflection()->ListFields(file->options(), &fields); - ASSERT_EQ(2, fields.size()); - EXPECT_TRUE(file->options().has_optimize_for()); - EXPECT_EQ(2, file->options().uninterpreted_option_size()); -} - -// =================================================================== - -TEST(CustomOptions, OptionLocations) { - const Descriptor* message = - protobuf_unittest::TestMessageWithCustomOptions::descriptor(); - const FileDescriptor* file = message->file(); - const FieldDescriptor* field = message->FindFieldByName("field1"); - const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); - // TODO(benjy): Support EnumValue options, once the compiler does. - const ServiceDescriptor* service = - file->FindServiceByName("TestServiceWithCustomOptions"); - const MethodDescriptor* method = service->FindMethodByName("Foo"); - - EXPECT_EQ(GOOGLE_LONGLONG(9876543210), - file->options().GetExtension(protobuf_unittest::file_opt1)); - EXPECT_EQ(-56, - message->options().GetExtension(protobuf_unittest::message_opt1)); - EXPECT_EQ(GOOGLE_LONGLONG(8765432109), - field->options().GetExtension(protobuf_unittest::field_opt1)); - EXPECT_EQ(42, // Check that we get the default for an option we don't set. - field->options().GetExtension(protobuf_unittest::field_opt2)); - EXPECT_EQ(-789, - enm->options().GetExtension(protobuf_unittest::enum_opt1)); - EXPECT_EQ(123, - enm->value(1)->options().GetExtension( - protobuf_unittest::enum_value_opt1)); - EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), - service->options().GetExtension(protobuf_unittest::service_opt1)); - EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, - method->options().GetExtension(protobuf_unittest::method_opt1)); - - // See that the regular options went through unscathed. - EXPECT_TRUE(message->options().has_message_set_wire_format()); - EXPECT_EQ(FieldOptions::CORD, field->options().ctype()); -} - -TEST(CustomOptions, OptionTypes) { - const MessageOptions* options = NULL; - - options = - &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options(); - EXPECT_EQ(false , options->GetExtension(protobuf_unittest::bool_opt)); - EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt)); - EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt)); - EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint32_opt)); - EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint64_opt)); - EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt)); - EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt)); - EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed32_opt)); - EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed64_opt)); - EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt)); - EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt)); - - options = - &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options(); - EXPECT_EQ(true , options->GetExtension(protobuf_unittest::bool_opt)); - EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt)); - EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt)); - EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt)); - EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt)); - EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt)); - EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt)); - EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt)); - EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt)); - EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt)); - EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt)); - - options = - &protobuf_unittest::CustomOptionOtherValues::descriptor()->options(); - EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt)); - EXPECT_FLOAT_EQ(12.3456789, - options->GetExtension(protobuf_unittest::float_opt)); - EXPECT_DOUBLE_EQ(1.234567890123456789, - options->GetExtension(protobuf_unittest::double_opt)); - EXPECT_EQ("Hello, \"World\"", - options->GetExtension(protobuf_unittest::string_opt)); - - EXPECT_EQ(string("Hello\0World", 11), - options->GetExtension(protobuf_unittest::bytes_opt)); - - EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2, - options->GetExtension(protobuf_unittest::enum_opt)); - - options = - &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options(); - EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt)); - EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt)); - - options = - &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options(); - EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt)); - EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt)); -} - -TEST(CustomOptions, ComplexExtensionOptions) { - const MessageOptions* options = - &protobuf_unittest::VariousComplexOptions::descriptor()->options(); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1). - GetExtension(protobuf_unittest::quux), 324); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1). - GetExtension(protobuf_unittest::corge).qux(), 876); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). - GetExtension(protobuf_unittest::grault), 654); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(), - 743); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar(). - GetExtension(protobuf_unittest::quux), 1999); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar(). - GetExtension(protobuf_unittest::corge).qux(), 2008); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). - GetExtension(protobuf_unittest::garply).foo(), 741); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). - GetExtension(protobuf_unittest::garply). - GetExtension(protobuf_unittest::quux), 1998); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). - GetExtension(protobuf_unittest::garply). - GetExtension(protobuf_unittest::corge).qux(), 2121); - EXPECT_EQ(options->GetExtension( - protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4). - waldo(), 1971); - EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). - fred().waldo(), 321); - EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux()); - EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3). - complexoptiontype5().plugh()); - EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy()); -} - -TEST(CustomOptions, OptionsFromOtherFile) { - // Test that to use a custom option, we only need to import the file - // defining the option; we do not also have to import descriptor.proto. - DescriptorPool pool; - - FileDescriptorProto file_proto; - FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); - ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); - - protobuf_unittest::TestMessageWithCustomOptions::descriptor() - ->file()->CopyTo(&file_proto); - ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); - - ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "package: \"protobuf_unittest\" " - "dependency: \"google/protobuf/unittest_custom_options.proto\" " - "options { " - " uninterpreted_option { " - " name { " - " name_part: \"file_opt1\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - // Test a non-extension option too. (At one point this failed due to a - // bug.) - " uninterpreted_option { " - " name { " - " name_part: \"java_package\" " - " is_extension: false " - " } " - " string_value: \"foo\" " - " } " - // Test that enum-typed options still work too. (At one point this also - // failed due to a bug.) - " uninterpreted_option { " - " name { " - " name_part: \"optimize_for\" " - " is_extension: false " - " } " - " identifier_value: \"SPEED\" " - " } " - "}" - , - &file_proto)); - - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1)); - EXPECT_TRUE(file->options().has_java_package()); - EXPECT_EQ("foo", file->options().java_package()); - EXPECT_TRUE(file->options().has_optimize_for()); - EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for()); -} - -TEST(CustomOptions, MessageOptionThreeFieldsSet) { - // This tests a bug which previously existed in custom options parsing. The - // bug occurred when you defined a custom option with message type and then - // set three fields of that option on a single definition (see the example - // below). The bug is a bit hard to explain, so check the change history if - // you want to know more. - DescriptorPool pool; - - FileDescriptorProto file_proto; - FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); - ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); - - protobuf_unittest::TestMessageWithCustomOptions::descriptor() - ->file()->CopyTo(&file_proto); - ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); - - // The following represents the definition: - // - // import "google/protobuf/unittest_custom_options.proto" - // package protobuf_unittest; - // message Foo { - // option (complex_opt1).foo = 1234; - // option (complex_opt1).foo2 = 1234; - // option (complex_opt1).foo3 = 1234; - // } - ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "package: \"protobuf_unittest\" " - "dependency: \"google/protobuf/unittest_custom_options.proto\" " - "message_type { " - " name: \"Foo\" " - " options { " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo2\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo3\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " } " - "}", - &file_proto)); - - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - ASSERT_EQ(1, file->message_type_count()); - - const MessageOptions& options = file->message_type(0)->options(); - EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo()); -} - - -// =================================================================== - -// The tests below trigger every unique call to AddError() in descriptor.cc, -// in the order in which they appear in that file. I'm using TextFormat here -// to specify the input descriptors because building them using code would -// be too bulky. - -class MockErrorCollector : public DescriptorPool::ErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, - const string& element_name, const Message* descriptor, - ErrorLocation location, const string& message) { - const char* location_name = NULL; - switch (location) { - case NAME : location_name = "NAME" ; break; - case NUMBER : location_name = "NUMBER" ; break; - case TYPE : location_name = "TYPE" ; break; - case EXTENDEE : location_name = "EXTENDEE" ; break; - case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break; - case OPTION_NAME : location_name = "OPTION_NAME" ; break; - case OPTION_VALUE : location_name = "OPTION_VALUE" ; break; - case INPUT_TYPE : location_name = "INPUT_TYPE" ; break; - case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break; - case OTHER : location_name = "OTHER" ; break; - } - - strings::SubstituteAndAppend( - &text_, "$0: $1: $2: $3\n", - filename, element_name, location_name, message); - } -}; - -class ValidationErrorTest : public testing::Test { - protected: - // Parse file_text as a FileDescriptorProto in text format and add it - // to the DescriptorPool. Expect no errors. - void BuildFile(const string& file_text) { - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); - } - - // Parse file_text as a FileDescriptorProto in text format and add it - // to the DescriptorPool. Expect errors to be produced which match the - // given error text. - void BuildFileWithErrors(const string& file_text, - const string& expected_errors) { - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - - MockErrorCollector error_collector; - EXPECT_TRUE( - pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL); - EXPECT_EQ(expected_errors, error_collector.text_); - } - - // Builds some already-parsed file in our test pool. - void BuildFileInTestPool(const FileDescriptor* file) { - FileDescriptorProto file_proto; - file->CopyTo(&file_proto); - ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); - } - - // Build descriptor.proto in our test pool. This allows us to extend it in - // the test pool, so we can test custom options. - void BuildDescriptorMessagesInTestPool() { - BuildFileInTestPool(DescriptorProto::descriptor()->file()); - } - - DescriptorPool pool_; -}; - -TEST_F(ValidationErrorTest, AlreadyDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", - - "foo.proto: Foo: NAME: \"Foo\" is already defined.\n"); -} - -TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.bar\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", - - "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in " - "\"foo.bar\".\n"); -} - -TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); - - BuildFileWithErrors( - "name: \"bar.proto\" " - "message_type { name: \"Foo\" }", - - "bar.proto: Foo: NAME: \"Foo\" is already defined in file " - "\"foo.proto\".\n"); -} - -TEST_F(ValidationErrorTest, PackageAlreadyDefined) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"foo\" }"); - BuildFileWithErrors( - "name: \"bar.proto\" " - "package: \"foo.bar\"", - - "bar.proto: foo: NAME: \"foo\" is already defined (as something other " - "than a package) in file \"foo.proto\".\n"); -} - -TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", - - "foo.proto: FOO: NAME: \"FOO\" is already defined.\n" - "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, " - "meaning that enum values are siblings of their type, not children of " - "it. Therefore, \"FOO\" must be unique within the global scope, not " - "just within \"Bar\".\n"); -} - -TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", - - "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n" - "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, " - "meaning that enum values are siblings of their type, not children of " - "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within " - "\"Bar\".\n"); -} - -TEST_F(ValidationErrorTest, MissingName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { }", - - "foo.proto: : NAME: Missing name.\n"); -} - -TEST_F(ValidationErrorTest, InvalidName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"$\" }", - - "foo.proto: $: NAME: \"$\" is not a valid identifier.\n"); -} - -TEST_F(ValidationErrorTest, InvalidPackageName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.$\"", - - "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n"); -} - -TEST_F(ValidationErrorTest, MissingFileName) { - BuildFileWithErrors( - "", - - ": : OTHER: Missing field: FileDescriptorProto.name.\n"); -} - -TEST_F(ValidationErrorTest, DupeDependency) { - BuildFile("name: \"foo.proto\""); - BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "dependency: \"foo.proto\" ", - - "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n"); -} - -TEST_F(ValidationErrorTest, UnknownDependency) { - BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" ", - - "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n"); -} - -TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) { - // Used to crash: If we depend on a non-existent file and then refer to a - // package defined in a file that we didn't import, and that package is - // nested within a parent package which this file is also in, and we don't - // include that parent package in the name (i.e. we do a relative lookup)... - // Yes, really. - BuildFile( - "name: 'foo.proto' " - "package: 'outer.foo' "); - BuildFileWithErrors( - "name: 'bar.proto' " - "dependency: 'baz.proto' " - "package: 'outer.bar' " - "message_type { " - " name: 'Bar' " - " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }" - "}", - - "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n" - "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in " - "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, " - "please add the necessary import.\n"); -} - -TEST_F(ValidationErrorTest, DupeFile) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); - // Note: We should *not* get redundant errors about "Foo" already being - // defined. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - // Add another type so that the files aren't identical (in which case there - // would be no error). - "enum_type { name: \"Bar\" }", - - "foo.proto: foo.proto: OTHER: A file with this name is already in the " - "pool.\n"); -} - -TEST_F(ValidationErrorTest, FieldInExtensionRange) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " extension_range { start: 10 end: 20 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field " - "\"bar\" (10).\n" - "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field " - "\"baz\" (19).\n"); -} - -TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - " extension_range { start: 20 end: 30 }" - " extension_range { start: 19 end: 21 }" - "}", - - "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " - "already-defined range 10 to 19.\n" - "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " - "already-defined range 20 to 29.\n"); -} - -TEST_F(ValidationErrorTest, InvalidDefaults) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - - // Invalid number. - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"abc\" }" - - // Empty default value. - " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"\" }" - - // Invalid boolean. - " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL" - " default_value: \"abc\" }" - - // Messages can't have defaults. - " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE" - " default_value: \"abc\" type_name: \"Foo\" }" - - // Same thing, but we don't know that this field has message type until - // we look up the type name. - " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL" - " default_value: \"abc\" type_name: \"Foo\" }" - - // Repeateds can't have defaults. - " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32" - " default_value: \"1\" }" - "}", - - "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n" - "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n" - "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or " - "false.\n" - "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n" - "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default " - "values.\n" - // This ends up being reported later because the error is detected at - // cross-linking time. - "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default " - "values.\n"); -} - -TEST_F(ValidationErrorTest, NegativeFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n"); -} - -TEST_F(ValidationErrorTest, HugeFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 0x70000000 " - " label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than " - "536870911.\n"); -} - -TEST_F(ValidationErrorTest, ReservedFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are " - "reserved for the protocol buffer library implementation.\n" - "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are " - "reserved for the protocol buffer library implementation.\n"); -} - -TEST_F(ValidationErrorTest, ExtensionMissingExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for " - "extension field.\n"); -} - -TEST_F(ValidationErrorTest, NonExtensionWithExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " extension_range { start: 1 end: 2 }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for " - "non-extension field.\n"); -} - -TEST_F(ValidationErrorTest, FieldNumberConflict) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in " - "\"Foo\" by field \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, BadMessageSetExtensionType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"MessageSet\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " - "messages.\n"); -} - -TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE" - " type_name: \"Foo\" extendee: \"MessageSet\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " - "messages.\n"); -} - -TEST_F(ValidationErrorTest, FieldInMessageSet) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " options { message_set_wire_format: true }" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only " - "extensions.\n"); -} - -TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: -10 end: -1 }" - "}", - - "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n"); -} - -TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 1 end: 0x70000000 }" - "}", - - "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than " - "536870911.\n"); -} - -TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 10 }" - " extension_range { start: 10 end: 5 }" - "}", - - "foo.proto: Foo: NUMBER: Extension range end number must be greater than " - "start number.\n" - "foo.proto: Foo: NUMBER: Extension range end number must be greater than " - "start number.\n"); -} - -TEST_F(ValidationErrorTest, EmptyEnum) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" }" - // Also use the empty enum in a message to make sure there are no crashes - // during validation (possible if the code attempts to derive a default - // value for the field). - "message_type {" - " name: \"Bar\"" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }" - " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" " - " default_value: \"NO_SUCH_VALUE\" }" - "}", - - "foo.proto: Foo: NAME: Enums must contain at least one value.\n" - "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named " - "\"NO_SUCH_VALUE\".\n"); -} - -TEST_F(ValidationErrorTest, UndefinedExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, NonMessageExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, NotAnExtensionNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension " - "number.\n"); -} - -TEST_F(ValidationErrorTest, UndefinedFieldType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) { - BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" } "); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", - "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " - "which is not imported by \"foo.proto\". To use it here, please add the " - "necessary import.\n"); -} - -TEST_F(ValidationErrorTest, SearchMostLocalFirst) { - // The following should produce an error that Bar.Baz is not defined: - // message Bar { message Baz {} } - // message Foo { - // message Bar { - // // Placing "message Baz{}" here, or removing Foo.Bar altogether, - // // would fix the error. - // } - // optional Bar.Baz baz = 1; - // } - // An one point the lookup code incorrectly did not produce an error in this - // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first, - // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually - // refer to the inner Bar, not the outer one. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " nested_type { name: \"Baz\" }" - "}" - "message_type {" - " name: \"Foo\"" - " nested_type { name: \"Bar\" }" - " field { name:\"baz\" number:1 label:LABEL_OPTIONAL" - " type_name:\"Bar.Baz\" }" - "}", - - "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, SearchMostLocalFirst2) { - // This test would find the most local "Bar" first, and does, but - // proceeds to find the outer one because the inner one's not an - // aggregate. - BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " nested_type { name: \"Baz\" }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"Bar\" number:1 type:TYPE_BYTES } " - " field { name:\"baz\" number:2 label:LABEL_OPTIONAL" - " type_name:\"Bar.Baz\" }" - "}"); -} - -TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) { - // Imagine we have the following: - // - // foo.proto: - // package foo.bar; - // bar.proto: - // package foo.bar; - // import "foo.proto"; - // message Bar {} - // baz.proto: - // package foo; - // import "bar.proto" - // message Baz { optional bar.Bar qux = 1; } - // - // When validating baz.proto, we will look up "bar.Bar". As part of this - // lookup, we first lookup "bar" then try to find "Bar" within it. "bar" - // should resolve to "foo.bar". Note, though, that "foo.bar" was originally - // defined in foo.proto, which is not a direct dependency of baz.proto. The - // implementation of FindSymbol() normally only returns symbols in direct - // dependencies, not indirect ones. This test insures that this does not - // prevent it from finding "foo.bar". - - BuildFile( - "name: \"foo.proto\" " - "package: \"foo.bar\" "); - BuildFile( - "name: \"bar.proto\" " - "package: \"foo.bar\" " - "dependency: \"foo.proto\" " - "message_type { name: \"Bar\" }"); - BuildFile( - "name: \"baz.proto\" " - "package: \"foo\" " - "dependency: \"bar.proto\" " - "message_type { " - " name: \"Baz\" " - " field { name:\"qux\" number:1 label:LABEL_OPTIONAL " - " type_name:\"bar.Bar\" }" - "}"); -} - -TEST_F(ValidationErrorTest, FieldTypeNotAType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " - " type_name:\".Foo.bar\" }" - " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n"); -} - -TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " nested_type {" - " name: \"Bar\"" - " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " }" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " - " type_name:\"Bar.Baz\" }" - "}", - "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n"); -} - -TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) { - BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - "}" - "message_type {" - " name: \"Foo\"" - " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}"); -} - -TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Bar\" } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM" - " type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n"); -} - -TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE" - " type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, BadEnumDefaultValue) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\"" - " default_value:\"NO_SUCH_VALUE\" }" - "}", - - "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named " - "\"NO_SUCH_VALUE\".\n"); -} - -TEST_F(ValidationErrorTest, PrimitiveWithTypeName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " type_name:\"Foo\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n"); -} - -TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }" - "}", - - "foo.proto: Foo.foo: TYPE: Field with message or enum type missing " - "type_name.\n"); -} - -TEST_F(ValidationErrorTest, InputTypeNotDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", - - "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, InputTypeNotAMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", - - "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, OutputTypeNotDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", - - "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, OutputTypeNotAMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", - - "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, IllegalPackedField) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {\n" - " name: \"Foo\"" - " field { name:\"packed_string\" number:1 label:LABEL_REPEATED " - " type:TYPE_STRING " - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - " field { name:\"packed_message\" number:3 label:LABEL_REPEATED " - " type_name: \"Foo\"" - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL " - " type:TYPE_INT32 " - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - "}", - - "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be " - "specified for repeated primitive fields.\n" - "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be " - "specified for repeated primitive fields.\n" - "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be " - "specified for repeated primitive fields.\n" - ); -} - -TEST_F(ValidationErrorTest, OptionWrongType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " positive_int_value: 1 }" - " }" - " }" - "}\n", - - "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for " - "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n"); -} - -TEST_F(ValidationErrorTest, OptionExtendsAtomicType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " name { name_part: \"foo\" " - " is_extension: true }" - " positive_int_value: 1 }" - " }" - " }" - "}\n", - - "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an " - "atomic type, not a message.\n"); -} - -TEST_F(ValidationErrorTest, DupOption) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " identifier_value: \"CORD\" }" - " uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " identifier_value: \"CORD\" }" - " }" - " }" - "}\n", - - "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was " - "already set.\n"); -} - -TEST_F(ValidationErrorTest, InvalidOptionName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL " - " options { uninterpreted_option { " - " name { name_part: \"uninterpreted_option\" " - " is_extension: false }" - " positive_int_value: 1 " - " }" - " }" - " }" - "}\n", - - "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use " - "reserved name \"uninterpreted_option\".\n"); -} - -TEST_F(ValidationErrorTest, RepeatedOption) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED " - " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " double_value: 1.2 } }", - - "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. " - "Repeated options are not supported.\n"); -} - -TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }" - "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }", - - "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used " - "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n"); -} - -TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x80000000 } " - "}", - - "foo.proto: foo.proto: OPTION_VALUE: Value out of range " - "for int32 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " negative_int_value: -0x80000001 } " - "}", - - "foo.proto: foo.proto: OPTION_VALUE: Value out of range " - "for int32 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"5\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be integer " - "for int32 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x8000000000000000 } " - "}", - - "foo.proto: foo.proto: OPTION_VALUE: Value out of range " - "for int64 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"5\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be integer " - "for int64 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x100000000 } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value out of range " - "for uint32 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " double_value: -5.6 } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer " - "for uint32 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " negative_int_value: -5 } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer " - "for uint64 option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"bar\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be number " - "for float option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"bar\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be number " - "for double option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"bar\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" " - "for boolean option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"QUUX\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for " - "enum-valued option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"QUUX\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value " - "named \"QUUX\" for option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } " - " value { name: \"QUUX\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum1\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"QUUX\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value " - "named \"QUUX\" for option \"foo\". This appears to be a value from a " - "sibling type.\n"); -} - -TEST_F(ValidationErrorTest, StringOptionValueIsNotString) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"QUUX\" } }", - - "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for " - "string option \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) { - BuildDescriptorMessagesInTestPool(); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }" - "}" - "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_MESSAGE type_name: \"TestMessage\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"bar\" " - " is_extension: true } " - " identifier_value: \"QUUX\" } }", - - "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of " - "message type.\n"); -} - -TEST_F(ValidationErrorTest, NotLiteImportsLite) { - BuildFile( - "name: \"bar.proto\" " - "options { optimize_for: LITE_RUNTIME } "); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"bar.proto\" ", - - "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = " - "LITE_RUNTIME cannot import files which do use this option. This file " - "is not lite, but it imports \"bar.proto\" which is.\n"); -} - -TEST_F(ValidationErrorTest, LiteExtendsNotLite) { - BuildFile( - "name: \"bar.proto\" " - "message_type: {" - " name: \"Bar\"" - " extension_range { start: 1 end: 1000 }" - "}"); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"bar.proto\" " - "options { optimize_for: LITE_RUNTIME } " - "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"Bar\" }", - - "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be " - "declared in non-lite files. Note that you cannot extend a non-lite " - "type to contain a lite type, but the reverse is allowed.\n"); -} - -TEST_F(ValidationErrorTest, NoLiteServices) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "options { optimize_for: LITE_RUNTIME } " - "service { name: \"Foo\" }", - - "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot " - "define services.\n"); -} - -TEST_F(ValidationErrorTest, RollbackAfterError) { - // Build a file which contains every kind of construct but references an - // undefined type. All these constructs will be added to the symbol table - // before the undefined type error is noticed. The DescriptorPool will then - // have to roll everything back. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method {" - " name: \"Baz\"" - " input_type: \"NoSuchType\"" // error - " output_type: \"TestMessage\"" - " }" - "}", - - "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"); - - // Make sure that if we build the same file again with the error fixed, - // it works. If the above rollback was incomplete, then some symbols will - // be left defined, and this second attempt will fail since it tries to - // re-define the same symbols. - BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method { name:\"Baz\"" - " input_type:\"TestMessage\"" - " output_type:\"TestMessage\" }" - "}"); -} - -TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { - // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is - // provided. - - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "message_type { name: \"Foo\" } ", - &file_proto)); - - vector errors; - - { - ScopedMemoryLog log; - EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(2, errors.size()); - - EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); - EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]); -} - -// =================================================================== -// DescriptorDatabase - -static void AddToDatabase(SimpleDescriptorDatabase* database, - const char* file_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - database->Add(file_proto); -} - -class DatabaseBackedPoolTest : public testing::Test { - protected: - DatabaseBackedPoolTest() {} - - SimpleDescriptorDatabase database_; - - virtual void SetUp() { - AddToDatabase(&database_, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } " - "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } " - "service { name:\"TestService\" } "); - AddToDatabase(&database_, - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "message_type { name:\"Bar\" } " - "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - } - - // We can't inject a file containing errors into a DescriptorPool, so we - // need an actual mock DescriptorDatabase to test errors. - class ErrorDescriptorDatabase : public DescriptorDatabase { - public: - ErrorDescriptorDatabase() {} - ~ErrorDescriptorDatabase() {} - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - // error.proto and error2.proto cyclically import each other. - if (filename == "error.proto") { - output->Clear(); - output->set_name("error.proto"); - output->add_dependency("error2.proto"); - return true; - } else if (filename == "error2.proto") { - output->Clear(); - output->set_name("error2.proto"); - output->add_dependency("error.proto"); - return true; - } else { - return false; - } - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - return false; - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return false; - } - }; - - // A DescriptorDatabase that counts how many times each method has been - // called and forwards to some other DescriptorDatabase. - class CallCountingDatabase : public DescriptorDatabase { - public: - CallCountingDatabase(DescriptorDatabase* wrapped_db) - : wrapped_db_(wrapped_db) { - Clear(); - } - ~CallCountingDatabase() {} - - DescriptorDatabase* wrapped_db_; - - int call_count_; - - void Clear() { - call_count_ = 0; - } - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileByName(filename, output); - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileContainingSymbol(symbol_name, output); - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileContainingExtension( - containing_type, field_number, output); - } - }; - - // A DescriptorDatabase which falsely always returns foo.proto when searching - // for any symbol or extension number. This shouldn't cause the - // DescriptorPool to reload foo.proto if it is already loaded. - class FalsePositiveDatabase : public DescriptorDatabase { - public: - FalsePositiveDatabase(DescriptorDatabase* wrapped_db) - : wrapped_db_(wrapped_db) {} - ~FalsePositiveDatabase() {} - - DescriptorDatabase* wrapped_db_; - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - return wrapped_db_->FindFileByName(filename, output); - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - return FindFileByName("foo.proto", output); - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return FindFileByName("foo.proto", output); - } - }; -}; - -TEST_F(DatabaseBackedPoolTest, FindFileByName) { - DescriptorPool pool(&database_); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - EXPECT_EQ("Foo", foo->message_type(0)->name()); - - EXPECT_EQ(foo, pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) { - DescriptorPool pool(&database_); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - EXPECT_EQ("Foo", foo->message_type(0)->name()); - - const FileDescriptor* bar = pool.FindFileByName("bar.proto"); - ASSERT_TRUE(bar != NULL); - EXPECT_EQ("bar.proto", bar->name()); - ASSERT_EQ(1, bar->message_type_count()); - EXPECT_EQ("Bar", bar->message_type(0)->name()); - - ASSERT_EQ(1, bar->dependency_count()); - EXPECT_EQ(foo, bar->dependency(0)); -} - -TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) { - DescriptorPool pool(&database_); - - const FileDescriptor* bar = pool.FindFileByName("bar.proto"); - ASSERT_TRUE(bar != NULL); - EXPECT_EQ("bar.proto", bar->name()); - ASSERT_EQ(1, bar->message_type_count()); - ASSERT_EQ("Bar", bar->message_type(0)->name()); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - ASSERT_EQ("Foo", foo->message_type(0)->name()); - - ASSERT_EQ(1, bar->dependency_count()); - EXPECT_EQ(foo, bar->dependency(0)); -} - -TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) { - DescriptorPool pool(&database_); - - const FileDescriptor* file = pool.FindFileContainingSymbol("Foo"); - ASSERT_TRUE(file != NULL); - EXPECT_EQ("foo.proto", file->name()); - EXPECT_EQ(file, pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) { - DescriptorPool pool(&database_); - - const Descriptor* type = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(type != NULL); - EXPECT_EQ("Foo", type->name()); - EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) { - DescriptorPool pool(&database_); - - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - - const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5); - ASSERT_TRUE(extension != NULL); - EXPECT_EQ("foo_ext", extension->name()); - EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto")); - - EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { - DescriptorPool pool(&database_); - - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - - for (int i = 0; i < 2; ++i) { - // Repeat the lookup twice, to check that we get consistent - // results despite the fallback database lookup mutating the pool. - vector extensions; - pool.FindAllExtensions(foo, &extensions); - ASSERT_EQ(1, extensions.size()); - EXPECT_EQ(5, extensions[0]->number()); - } -} - -TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { - ErrorDescriptorDatabase error_database; - DescriptorPool pool(&error_database); - - vector errors; - - { - ScopedMemoryLog log; - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - errors = log.GetMessages(ERROR); - } - - EXPECT_FALSE(errors.empty()); -} - -TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) { - ErrorDescriptorDatabase error_database; - MockErrorCollector error_collector; - DescriptorPool pool(&error_database, &error_collector); - - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - EXPECT_EQ( - "error.proto: error.proto: OTHER: File recursively imports itself: " - "error.proto -> error2.proto -> error.proto\n" - "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not " - "found or had errors.\n" - "error.proto: error.proto: OTHER: Import \"error2.proto\" was not " - "found or had errors.\n", - error_collector.text_); -} - -TEST_F(DatabaseBackedPoolTest, UnittestProto) { - // Try to load all of unittest.proto from a DescriptorDatabase. This should - // thoroughly test all paths through DescriptorBuilder to insure that there - // are no deadlocking problems when pool_->mutex_ is non-NULL. - const FileDescriptor* original_file = - protobuf_unittest::TestAllTypes::descriptor()->file(); - - DescriptorPoolDatabase database(*DescriptorPool::generated_pool()); - DescriptorPool pool(&database); - const FileDescriptor* file_from_database = - pool.FindFileByName(original_file->name()); - - ASSERT_TRUE(file_from_database != NULL); - - FileDescriptorProto original_file_proto; - original_file->CopyTo(&original_file_proto); - - FileDescriptorProto file_from_database_proto; - file_from_database->CopyTo(&file_from_database_proto); - - EXPECT_EQ(original_file_proto.DebugString(), - file_from_database_proto.DebugString()); -} - -TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) { - // Searching for a child of an existing descriptor should never fall back - // to the DescriptorDatabase even if it isn't found, because we know all - // children are already loaded. - CallCountingDatabase call_counter(&database_); - DescriptorPool pool(&call_counter); - - const FileDescriptor* file = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(file != NULL); - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum"); - ASSERT_TRUE(test_enum != NULL); - const ServiceDescriptor* test_service = pool.FindServiceByName("TestService"); - ASSERT_TRUE(test_service != NULL); - - EXPECT_NE(0, call_counter.call_count_); - call_counter.Clear(); - - EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL); - EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL); - EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL); - EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL); - - EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL); - EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL); - EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL); - EXPECT_EQ(0, call_counter.call_count_); -} - -TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) { - // If FindFileContainingSymbol() or FindFileContainingExtension() return a - // file that is already in the DescriptorPool, it should not attempt to - // reload the file. - FalsePositiveDatabase false_positive_database(&database_); - MockErrorCollector error_collector; - DescriptorPool pool(&false_positive_database, &error_collector); - - // First make sure foo.proto is loaded. - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - - // Try inducing false positives. - EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL); - EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL); - - // No errors should have been reported. (If foo.proto was incorrectly - // loaded multiple times, errors would have been reported.) - EXPECT_EQ("", error_collector.text_); -} - -TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) { - ErrorDescriptorDatabase error_database; - MockErrorCollector error_collector; - DescriptorPool pool(&error_database, &error_collector); - - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - error_collector.text_.clear(); - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - EXPECT_EQ("", error_collector.text_); -} - -TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) { - // If a lookup finds a symbol of the wrong type (e.g. we pass a type name - // to FindFieldByName()), we should fail fast, without checking the fallback - // database. - CallCountingDatabase call_counter(&database_); - DescriptorPool pool(&call_counter); - - const FileDescriptor* file = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(file != NULL); - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum"); - ASSERT_TRUE(test_enum != NULL); - - EXPECT_NE(0, call_counter.call_count_); - call_counter.Clear(); - - EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL); - EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL); - EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL); - EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL); - EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL); - EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL); - EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL); - - EXPECT_EQ(0, call_counter.call_count_); -} - -// =================================================================== - - -} // namespace descriptor_unittest -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/dynamic_message.cc b/Resources/NetHook/google/protobuf/dynamic_message.cc deleted file mode 100644 index c711a2da..00000000 --- a/Resources/NetHook/google/protobuf/dynamic_message.cc +++ /dev/null @@ -1,558 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// DynamicMessage is implemented by constructing a data structure which -// has roughly the same memory layout as a generated message would have. -// Then, we use GeneratedMessageReflection to implement our reflection -// interface. All the other operations we need to implement (e.g. -// parsing, copying, etc.) are already implemented in terms of -// Reflection, so the rest is easy. -// -// The up side of this strategy is that it's very efficient. We don't -// need to use hash_maps or generic representations of fields. The -// down side is that this is a low-level memory management hack which -// can be tricky to get right. -// -// As mentioned in the header, we only expose a DynamicMessageFactory -// publicly, not the DynamicMessage class itself. This is because -// GenericMessageReflection wants to have a pointer to a "default" -// copy of the class, with all fields initialized to their default -// values. We only want to construct one of these per message type, -// so DynamicMessageFactory stores a cache of default messages for -// each type it sees (each unique Descriptor pointer). The code -// refers to the "default" copy of the class as the "prototype". -// -// Note on memory allocation: This module often calls "operator new()" -// to allocate untyped memory, rather than calling something like -// "new uint8[]". This is because "operator new()" means "Give me some -// space which I can use as I please." while "new uint8[]" means "Give -// me an array of 8-bit integers.". In practice, the later may return -// a pointer that is not aligned correctly for general use. I believe -// Item 8 of "More Effective C++" discusses this in more detail, though -// I don't have the book on me right now so I'm not sure. - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -using internal::WireFormat; -using internal::ExtensionSet; -using internal::GeneratedMessageReflection; - - -// =================================================================== -// Some helper tables and functions... - -namespace { - -// Compute the byte size of the in-memory representation of the field. -int FieldSpaceUsed(const FieldDescriptor* field) { - typedef FieldDescriptor FD; // avoid line wrapping - if (field->label() == FD::LABEL_REPEATED) { - switch (field->cpp_type()) { - case FD::CPPTYPE_INT32 : return sizeof(RepeatedField); - case FD::CPPTYPE_INT64 : return sizeof(RepeatedField); - case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField); - case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField); - case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField); - case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField); - case FD::CPPTYPE_BOOL : return sizeof(RepeatedField); - case FD::CPPTYPE_ENUM : return sizeof(RepeatedField); - case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField); - - case FD::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return sizeof(RepeatedPtrField); - } - break; - } - } else { - switch (field->cpp_type()) { - case FD::CPPTYPE_INT32 : return sizeof(int32 ); - case FD::CPPTYPE_INT64 : return sizeof(int64 ); - case FD::CPPTYPE_UINT32 : return sizeof(uint32 ); - case FD::CPPTYPE_UINT64 : return sizeof(uint64 ); - case FD::CPPTYPE_DOUBLE : return sizeof(double ); - case FD::CPPTYPE_FLOAT : return sizeof(float ); - case FD::CPPTYPE_BOOL : return sizeof(bool ); - case FD::CPPTYPE_ENUM : return sizeof(int ); - case FD::CPPTYPE_MESSAGE: return sizeof(Message*); - - case FD::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return sizeof(string*); - } - break; - } - } - - GOOGLE_LOG(DFATAL) << "Can't get here."; - return 0; -} - -inline int DivideRoundingUp(int i, int j) { - return (i + (j - 1)) / j; -} - -static const int kSafeAlignment = sizeof(uint64); - -inline int AlignTo(int offset, int alignment) { - return DivideRoundingUp(offset, alignment) * alignment; -} - -// Rounds the given byte offset up to the next offset aligned such that any -// type may be stored at it. -inline int AlignOffset(int offset) { - return AlignTo(offset, kSafeAlignment); -} - -#define bitsizeof(T) (sizeof(T) * 8) - -} // namespace - -// =================================================================== - -class DynamicMessage : public Message { - public: - struct TypeInfo { - int size; - int has_bits_offset; - int unknown_fields_offset; - int extensions_offset; - - // Not owned by the TypeInfo. - DynamicMessageFactory* factory; // The factory that created this object. - const DescriptorPool* pool; // The factory's DescriptorPool. - const Descriptor* type; // Type of this DynamicMessage. - - // Warning: The order in which the following pointers are defined is - // important (the prototype must be deleted *before* the offsets). - scoped_array offsets; - scoped_ptr reflection; - scoped_ptr prototype; - }; - - DynamicMessage(const TypeInfo* type_info); - ~DynamicMessage(); - - // Called on the prototype after construction to initialize message fields. - void CrossLinkPrototypes(); - - // implements Message ---------------------------------------------- - - Message* New() const; - - int GetCachedSize() const; - void SetCachedSize(int size) const; - - Metadata GetMetadata() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); - - inline bool is_prototype() const { - return type_info_->prototype == this || - // If type_info_->prototype is NULL, then we must be constructing - // the prototype now, which means we must be the prototype. - type_info_->prototype == NULL; - } - - inline void* OffsetToPointer(int offset) { - return reinterpret_cast(this) + offset; - } - inline const void* OffsetToPointer(int offset) const { - return reinterpret_cast(this) + offset; - } - - const TypeInfo* type_info_; - - // TODO(kenton): Make this an atomic when C++ supports it. - mutable int cached_byte_size_; -}; - -DynamicMessage::DynamicMessage(const TypeInfo* type_info) - : type_info_(type_info), - cached_byte_size_(0) { - // We need to call constructors for various fields manually and set - // default values where appropriate. We use placement new to call - // constructors. If you haven't heard of placement new, I suggest Googling - // it now. We use placement new even for primitive types that don't have - // constructors for consistency. (In theory, placement new should be used - // any time you are trying to convert untyped memory to typed memory, though - // in practice that's not strictly necessary for types that don't have a - // constructor.) - - const Descriptor* descriptor = type_info_->type; - - new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; - - if (type_info_->extensions_offset != -1) { - new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; - } - - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - if (!field->is_repeated()) { \ - new(field_ptr) TYPE(field->default_value_##TYPE()); \ - } else { \ - new(field_ptr) RepeatedField(); \ - } \ - break; - - HANDLE_TYPE(INT32 , int32 ); - HANDLE_TYPE(INT64 , int64 ); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE(FLOAT , float ); - HANDLE_TYPE(BOOL , bool ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_ENUM: - if (!field->is_repeated()) { - new(field_ptr) int(field->default_value_enum()->number()); - } else { - new(field_ptr) RepeatedField(); - } - break; - - case FieldDescriptor::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - if (!field->is_repeated()) { - if (is_prototype()) { - new(field_ptr) const string*(&field->default_value_string()); - } else { - string* default_value = - *reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])); - new(field_ptr) string*(default_value); - } - } else { - new(field_ptr) RepeatedPtrField(); - } - break; - } - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: { - if (!field->is_repeated()) { - new(field_ptr) Message*(NULL); - } else { - new(field_ptr) RepeatedPtrField(); - } - break; - } - } - } -} - -DynamicMessage::~DynamicMessage() { - const Descriptor* descriptor = type_info_->type; - - reinterpret_cast( - OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); - - if (type_info_->extensions_offset != -1) { - reinterpret_cast( - OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); - } - - // We need to manually run the destructors for repeated fields and strings, - // just as we ran their constructors in the the DynamicMessage constructor. - // Additionally, if any singular embedded messages have been allocated, we - // need to delete them, UNLESS we are the prototype message of this type, - // in which case any embedded messages are other prototypes and shouldn't - // be touched. - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - - if (field->is_repeated()) { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - reinterpret_cast*>(field_ptr) \ - ->~RepeatedField(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - reinterpret_cast*>(field_ptr) - ->~RepeatedPtrField(); - break; - } - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - reinterpret_cast*>(field_ptr) - ->~RepeatedPtrField(); - break; - } - - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: { - string* ptr = *reinterpret_cast(field_ptr); - if (ptr != &field->default_value_string()) { - delete ptr; - } - break; - } - } - } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) && - !is_prototype()) { - Message* message = *reinterpret_cast(field_ptr); - if (message != NULL) { - delete message; - } - } - } -} - -void DynamicMessage::CrossLinkPrototypes() { - // This should only be called on the prototype message. - GOOGLE_CHECK(is_prototype()); - - DynamicMessageFactory* factory = type_info_->factory; - const Descriptor* descriptor = type_info_->type; - - // Cross-link default messages. - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_repeated()) { - // For fields with message types, we need to cross-link with the - // prototype for the field's type. - // For singular fields, the field is just a pointer which should - // point to the prototype. - *reinterpret_cast(field_ptr) = - factory->GetPrototypeNoLock(field->message_type()); - } - } -} - -Message* DynamicMessage::New() const { - void* new_base = reinterpret_cast(operator new(type_info_->size)); - memset(new_base, 0, type_info_->size); - return new(new_base) DynamicMessage(type_info_); -} - -int DynamicMessage::GetCachedSize() const { - return cached_byte_size_; -} - -void DynamicMessage::SetCachedSize(int size) const { - // This is theoretically not thread-compatible, but in practice it works - // because if multiple threads write this simultaneously, they will be - // writing the exact same value. - cached_byte_size_ = size; -} - -Metadata DynamicMessage::GetMetadata() const { - Metadata metadata; - metadata.descriptor = type_info_->type; - metadata.reflection = type_info_->reflection.get(); - return metadata; -} - -// =================================================================== - -struct DynamicMessageFactory::PrototypeMap { - typedef hash_map Map; - Map map_; -}; - -DynamicMessageFactory::DynamicMessageFactory() - : pool_(NULL), delegate_to_generated_factory_(false), - prototypes_(new PrototypeMap) { -} - -DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) - : pool_(pool), delegate_to_generated_factory_(false), - prototypes_(new PrototypeMap) { -} - -DynamicMessageFactory::~DynamicMessageFactory() { - for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin(); - iter != prototypes_->map_.end(); ++iter) { - delete iter->second; - } -} - -const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) { - MutexLock lock(&prototypes_mutex_); - return GetPrototypeNoLock(type); -} - -const Message* DynamicMessageFactory::GetPrototypeNoLock( - const Descriptor* type) { - if (delegate_to_generated_factory_ && - type->file()->pool() == DescriptorPool::generated_pool()) { - return MessageFactory::generated_factory()->GetPrototype(type); - } - - const DynamicMessage::TypeInfo** target = &prototypes_->map_[type]; - if (*target != NULL) { - // Already exists. - return (*target)->prototype.get(); - } - - DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo; - *target = type_info; - - type_info->type = type; - type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_; - type_info->factory = this; - - // We need to construct all the structures passed to - // GeneratedMessageReflection's constructor. This includes: - // - A block of memory that contains space for all the message's fields. - // - An array of integers indicating the byte offset of each field within - // this block. - // - A big bitfield containing a bit for each field indicating whether - // or not that field is set. - - // Compute size and offsets. - int* offsets = new int[type->field_count()]; - type_info->offsets.reset(offsets); - - // Decide all field offsets by packing in order. - // We place the DynamicMessage object itself at the beginning of the allocated - // space. - int size = sizeof(DynamicMessage); - size = AlignOffset(size); - - // Next the has_bits, which is an array of uint32s. - type_info->has_bits_offset = size; - int has_bits_array_size = - DivideRoundingUp(type->field_count(), bitsizeof(uint32)); - size += has_bits_array_size * sizeof(uint32); - size = AlignOffset(size); - - // The ExtensionSet, if any. - if (type->extension_range_count() > 0) { - type_info->extensions_offset = size; - size += sizeof(ExtensionSet); - size = AlignOffset(size); - } else { - // No extensions. - type_info->extensions_offset = -1; - } - - // All the fields. - for (int i = 0; i < type->field_count(); i++) { - // Make sure field is aligned to avoid bus errors. - int field_size = FieldSpaceUsed(type->field(i)); - size = AlignTo(size, min(kSafeAlignment, field_size)); - offsets[i] = size; - size += field_size; - } - - // Add the UnknownFieldSet to the end. - size = AlignOffset(size); - type_info->unknown_fields_offset = size; - size += sizeof(UnknownFieldSet); - - // Align the final size to make sure no clever allocators think that - // alignment is not necessary. - size = AlignOffset(size); - type_info->size = size; - - // Allocate the prototype. - void* base = operator new(size); - memset(base, 0, size); - DynamicMessage* prototype = new(base) DynamicMessage(type_info); - type_info->prototype.reset(prototype); - - // Construct the reflection object. - type_info->reflection.reset( - new GeneratedMessageReflection( - type_info->type, - type_info->prototype.get(), - type_info->offsets.get(), - type_info->has_bits_offset, - type_info->unknown_fields_offset, - type_info->extensions_offset, - type_info->pool, - this, - type_info->size)); - - // Cross link prototypes. - prototype->CrossLinkPrototypes(); - - return prototype; -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/dynamic_message.h b/Resources/NetHook/google/protobuf/dynamic_message.h deleted file mode 100644 index 81dd2c63..00000000 --- a/Resources/NetHook/google/protobuf/dynamic_message.h +++ /dev/null @@ -1,136 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Defines an implementation of Message which can emulate types which are not -// known at compile-time. - -#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ -#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ - -#include -#include - -namespace google { -namespace protobuf { - -// Defined in other files. -class Descriptor; // descriptor.h -class DescriptorPool; // descriptor.h - -// Constructs implementations of Message which can emulate types which are not -// known at compile-time. -// -// Sometimes you want to be able to manipulate protocol types that you don't -// know about at compile time. It would be nice to be able to construct -// a Message object which implements the message type given by any arbitrary -// Descriptor. DynamicMessage provides this. -// -// As it turns out, a DynamicMessage needs to construct extra -// information about its type in order to operate. Most of this information -// can be shared between all DynamicMessages of the same type. But, caching -// this information in some sort of global map would be a bad idea, since -// the cached information for a particular descriptor could outlive the -// descriptor itself. To avoid this problem, DynamicMessageFactory -// encapsulates this "cache". All DynamicMessages of the same type created -// from the same factory will share the same support data. Any Descriptors -// used with a particular factory must outlive the factory. -class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { - public: - // Construct a DynamicMessageFactory that will search for extensions in - // the DescriptorPool in which the exendee is defined. - DynamicMessageFactory(); - - // Construct a DynamicMessageFactory that will search for extensions in - // the given DescriptorPool. - // - // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the - // parser to look for extensions in an alternate pool. However, note that - // this is almost never what you want to do. Almost all users should use - // the zero-arg constructor. - DynamicMessageFactory(const DescriptorPool* pool); - - ~DynamicMessageFactory(); - - // Call this to tell the DynamicMessageFactory that if it is given a - // Descriptor d for which: - // d->file()->pool() == DescriptorPool::generated_pool(), - // then it should delegate to MessageFactory::generated_factory() instead - // of constructing a dynamic implementation of the message. In theory there - // is no down side to doing this, so it may become the default in the future. - void SetDelegateToGeneratedFactory(bool enable) { - delegate_to_generated_factory_ = enable; - } - - // implements MessageFactory --------------------------------------- - - // Given a Descriptor, constructs the default (prototype) Message of that - // type. You can then call that message's New() method to construct a - // mutable message of that type. - // - // Calling this method twice with the same Descriptor returns the same - // object. The returned object remains property of the factory and will - // be destroyed when the factory is destroyed. Also, any objects created - // by calling the prototype's New() method share some data with the - // prototype, so these must be destoyed before the DynamicMessageFactory - // is destroyed. - // - // The given descriptor must outlive the returned message, and hence must - // outlive the DynamicMessageFactory. - // - // The method is thread-safe. - const Message* GetPrototype(const Descriptor* type); - - private: - const DescriptorPool* pool_; - bool delegate_to_generated_factory_; - - // This struct just contains a hash_map. We can't #include from - // this header due to hacks needed for hash_map portability in the open source - // release. Namely, stubs/hash.h, which defines hash_map portably, is not a - // public header (for good reason), but dynamic_message.h is, and public - // headers may only #include other public headers. - struct PrototypeMap; - scoped_ptr prototypes_; - mutable Mutex prototypes_mutex_; - - friend class DynamicMessage; - const Message* GetPrototypeNoLock(const Descriptor* type); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ diff --git a/Resources/NetHook/google/protobuf/dynamic_message_unittest.cc b/Resources/NetHook/google/protobuf/dynamic_message_unittest.cc deleted file mode 100644 index 41b89ab5..00000000 --- a/Resources/NetHook/google/protobuf/dynamic_message_unittest.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Since the reflection interface for DynamicMessage is implemented by -// GenericMessageReflection, the only thing we really have to test is -// that DynamicMessage correctly sets up the information that -// GenericMessageReflection needs to use. So, we focus on that in this -// test. Other tests, such as generic_message_reflection_unittest and -// reflection_ops_unittest, cover the rest of the functionality used by -// DynamicMessage. - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace google { -namespace protobuf { - -class DynamicMessageTest : public testing::Test { - protected: - DescriptorPool pool_; - DynamicMessageFactory factory_; - const Descriptor* descriptor_; - const Message* prototype_; - const Descriptor* extensions_descriptor_; - const Message* extensions_prototype_; - const Descriptor* packed_descriptor_; - const Message* packed_prototype_; - - DynamicMessageTest(): factory_(&pool_) {} - - virtual void SetUp() { - // We want to make sure that DynamicMessage works (particularly with - // extensions) even if we use descriptors that are *not* from compiled-in - // types, so we make copies of the descriptors for unittest.proto and - // unittest_import.proto. - FileDescriptorProto unittest_file; - FileDescriptorProto unittest_import_file; - - unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file); - unittest_import::ImportMessage::descriptor()->file()->CopyTo( - &unittest_import_file); - - ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL); - ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL); - - descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes"); - ASSERT_TRUE(descriptor_ != NULL); - prototype_ = factory_.GetPrototype(descriptor_); - - extensions_descriptor_ = - pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions"); - ASSERT_TRUE(extensions_descriptor_ != NULL); - extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_); - - packed_descriptor_ = - pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes"); - ASSERT_TRUE(packed_descriptor_ != NULL); - packed_prototype_ = factory_.GetPrototype(packed_descriptor_); - } -}; - -TEST_F(DynamicMessageTest, Descriptor) { - // Check that the descriptor on the DynamicMessage matches the descriptor - // passed to GetPrototype(). - EXPECT_EQ(prototype_->GetDescriptor(), descriptor_); -} - -TEST_F(DynamicMessageTest, OnePrototype) { - // Check that requesting the same prototype twice produces the same object. - EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_)); -} - -TEST_F(DynamicMessageTest, Defaults) { - // Check that all default values are set correctly in the initial message. - TestUtil::ReflectionTester reflection_tester(descriptor_); - reflection_tester.ExpectClearViaReflection(*prototype_); -} - -TEST_F(DynamicMessageTest, IndependentOffsets) { - // Check that all fields have independent offsets by setting each - // one to a unique value then checking that they all still have those - // unique values (i.e. they don't stomp each other). - scoped_ptr message(prototype_->New()); - TestUtil::ReflectionTester reflection_tester(descriptor_); - - reflection_tester.SetAllFieldsViaReflection(message.get()); - reflection_tester.ExpectAllFieldsSetViaReflection(*message); -} - -TEST_F(DynamicMessageTest, Extensions) { - // Check that extensions work. - scoped_ptr message(extensions_prototype_->New()); - TestUtil::ReflectionTester reflection_tester(extensions_descriptor_); - - reflection_tester.SetAllFieldsViaReflection(message.get()); - reflection_tester.ExpectAllFieldsSetViaReflection(*message); -} - -TEST_F(DynamicMessageTest, PackedFields) { - // Check that packed fields work properly. - scoped_ptr message(packed_prototype_->New()); - TestUtil::ReflectionTester reflection_tester(packed_descriptor_); - - reflection_tester.SetPackedFieldsViaReflection(message.get()); - reflection_tester.ExpectPackedFieldsSetViaReflection(*message); -} - -TEST_F(DynamicMessageTest, SpaceUsed) { - // Test that SpaceUsed() works properly - - // Since we share the implementation with generated messages, we don't need - // to test very much here. Just make sure it appears to be working. - - scoped_ptr message(prototype_->New()); - TestUtil::ReflectionTester reflection_tester(descriptor_); - - int initial_space_used = message->SpaceUsed(); - - reflection_tester.SetAllFieldsViaReflection(message.get()); - EXPECT_LT(initial_space_used, message->SpaceUsed()); -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/extension_set.cc b/Resources/NetHook/google/protobuf/extension_set.cc deleted file mode 100644 index 6084885b..00000000 --- a/Resources/NetHook/google/protobuf/extension_set.cc +++ /dev/null @@ -1,1452 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -namespace { - -inline WireFormatLite::FieldType real_type(FieldType type) { - GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); - return static_cast(type); -} - -inline WireFormatLite::CppType cpp_type(FieldType type) { - return WireFormatLite::FieldTypeToCppType(real_type(type)); -} - -// Registry stuff. -typedef hash_map, - ExtensionInfo> ExtensionRegistry; -ExtensionRegistry* registry_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); - -void DeleteRegistry() { - delete registry_; - registry_ = NULL; -} - -void InitRegistry() { - registry_ = new ExtensionRegistry; - internal::OnShutdown(&DeleteRegistry); -} - -// This function is only called at startup, so there is no need for thread- -// safety. -void Register(const MessageLite* containing_type, - int number, ExtensionInfo info) { - ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); - - if (!InsertIfNotPresent(registry_, make_pair(containing_type, number), - info)) { - GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" - << containing_type->GetTypeName() - << "\", field number " << number << "."; - } -} - -const ExtensionInfo* FindRegisteredExtension( - const MessageLite* containing_type, int number) { - return (registry_ == NULL) ? NULL : - FindOrNull(*registry_, make_pair(containing_type, number)); -} - -} // namespace - -ExtensionFinder::~ExtensionFinder() {} - -bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { - const ExtensionInfo* extension = - FindRegisteredExtension(containing_type_, number); - if (extension == NULL) { - return false; - } else { - *output = *extension; - return true; - } -} - -void ExtensionSet::RegisterExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed) { - GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); - GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); - GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); - ExtensionInfo info(type, is_repeated, is_packed); - Register(containing_type, number, info); -} - -static bool CallNoArgValidityFunc(const void* arg, int number) { - // Note: Must use C-style cast here rather than reinterpret_cast because - // the C++ standard at one point did not allow casts between function and - // data pointers and some compilers enforce this for C++-style casts. No - // compiler enforces it for C-style casts since lots of C-style code has - // relied on these kinds of casts for a long time, despite being - // technically undefined. See: - // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 - // Also note: Some compilers do not allow function pointers to be "const". - // Which makes sense, I suppose, because it's meaningless. - return ((EnumValidityFunc*)arg)(number); -} - -void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, - EnumValidityFunc* is_valid) { - GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); - ExtensionInfo info(type, is_repeated, is_packed); - info.enum_validity_check.func = CallNoArgValidityFunc; - // See comment in CallNoArgValidityFunc() about why we use a c-style cast. - info.enum_validity_check.arg = (void*)is_valid; - Register(containing_type, number, info); -} - -void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, - const MessageLite* prototype) { - GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || - type == WireFormatLite::TYPE_GROUP); - ExtensionInfo info(type, is_repeated, is_packed); - info.message_prototype = prototype; - Register(containing_type, number, info); -} - - -// =================================================================== -// Constructors and basic methods. - -ExtensionSet::ExtensionSet() {} - -ExtensionSet::~ExtensionSet() { - for (map::iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - iter->second.Free(); - } -} - -// Defined in extension_set_heavy.cc. -// void ExtensionSet::AppendToList(const Descriptor* containing_type, -// const DescriptorPool* pool, -// vector* output) const - -bool ExtensionSet::Has(int number) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return false; - GOOGLE_DCHECK(!iter->second.is_repeated); - return !iter->second.is_cleared; -} - -int ExtensionSet::ExtensionSize(int number) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return false; - return iter->second.GetSize(); -} - -void ExtensionSet::ClearExtension(int number) { - map::iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return; - iter->second.Clear(); -} - -// =================================================================== -// Field accessors - -namespace { - -enum Cardinality { - REPEATED, - OPTIONAL -}; - -} // namespace - -#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ - GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ - GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) - -// ------------------------------------------------------------------- -// Primitives - -#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ - \ -LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ - LOWERCASE default_value) const { \ - map::const_iterator iter = extensions_.find(number); \ - if (iter == extensions_.end() || iter->second.is_cleared) { \ - return default_value; \ - } else { \ - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \ - return iter->second.LOWERCASE##_value; \ - } \ -} \ - \ -void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ - LOWERCASE value, \ - const FieldDescriptor* descriptor) { \ - Extension* extension; \ - if (MaybeNewExtension(number, descriptor, &extension)) { \ - extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ - extension->is_repeated = false; \ - } else { \ - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ - } \ - extension->is_cleared = false; \ - extension->LOWERCASE##_value = value; \ -} \ - \ -LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ - map::const_iterator iter = extensions_.find(number); \ - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ - return iter->second.repeated_##LOWERCASE##_value->Get(index); \ -} \ - \ -void ExtensionSet::SetRepeated##CAMELCASE( \ - int number, int index, LOWERCASE value) { \ - map::iterator iter = extensions_.find(number); \ - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ - iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ -} \ - \ -void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ - bool packed, LOWERCASE value, \ - const FieldDescriptor* descriptor) { \ - Extension* extension; \ - if (MaybeNewExtension(number, descriptor, &extension)) { \ - extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ - extension->is_repeated = true; \ - extension->is_packed = packed; \ - extension->repeated_##LOWERCASE##_value = new RepeatedField(); \ - } else { \ - GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \ - GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ - } \ - extension->repeated_##LOWERCASE##_value->Add(value); \ -} - -PRIMITIVE_ACCESSORS( INT32, int32, Int32) -PRIMITIVE_ACCESSORS( INT64, int64, Int64) -PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) -PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) -PRIMITIVE_ACCESSORS( FLOAT, float, Float) -PRIMITIVE_ACCESSORS(DOUBLE, double, Double) -PRIMITIVE_ACCESSORS( BOOL, bool, Bool) - -#undef PRIMITIVE_ACCESSORS - -// ------------------------------------------------------------------- -// Enums - -int ExtensionSet::GetEnum(int number, int default_value) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end() || iter->second.is_cleared) { - // Not present. Return the default value. - return default_value; - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM); - return iter->second.enum_value; - } -} - -void ExtensionSet::SetEnum(int number, FieldType type, int value, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); - extension->is_repeated = false; - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); - } - extension->is_cleared = false; - extension->enum_value = value; -} - -int ExtensionSet::GetRepeatedEnum(int number, int index) const { - map::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); - return iter->second.repeated_enum_value->Get(index); -} - -void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { - map::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); - iter->second.repeated_enum_value->Set(index, value); -} - -void ExtensionSet::AddEnum(int number, FieldType type, - bool packed, int value, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); - extension->is_repeated = true; - extension->is_packed = packed; - extension->repeated_enum_value = new RepeatedField(); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM); - GOOGLE_DCHECK_EQ(extension->is_packed, packed); - } - extension->repeated_enum_value->Add(value); -} - -// ------------------------------------------------------------------- -// Strings - -const string& ExtensionSet::GetString(int number, - const string& default_value) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end() || iter->second.is_cleared) { - // Not present. Return the default value. - return default_value; - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING); - return *iter->second.string_value; - } -} - -string* ExtensionSet::MutableString(int number, FieldType type, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); - extension->is_repeated = false; - extension->string_value = new string; - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING); - } - extension->is_cleared = false; - return extension->string_value; -} - -const string& ExtensionSet::GetRepeatedString(int number, int index) const { - map::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); - return iter->second.repeated_string_value->Get(index); -} - -string* ExtensionSet::MutableRepeatedString(int number, int index) { - map::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); - return iter->second.repeated_string_value->Mutable(index); -} - -string* ExtensionSet::AddString(int number, FieldType type, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); - extension->is_repeated = true; - extension->is_packed = false; - extension->repeated_string_value = new RepeatedPtrField(); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING); - } - return extension->repeated_string_value->Add(); -} - -// ------------------------------------------------------------------- -// Messages - -const MessageLite& ExtensionSet::GetMessage( - int number, const MessageLite& default_value) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) { - // Not present. Return the default value. - return default_value; - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - return *iter->second.message_value; - } -} - -// Defined in extension_set_heavy.cc. -// const MessageLite& ExtensionSet::GetMessage(int number, -// const Descriptor* message_type, -// MessageFactory* factory) const - -MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, - const MessageLite& prototype, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); - extension->is_repeated = false; - extension->message_value = prototype.New(); - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - } - extension->is_cleared = false; - return extension->message_value; -} - -// Defined in extension_set_heavy.cc. -// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, -// const Descriptor* message_type, -// MessageFactory* factory) - -const MessageLite& ExtensionSet::GetRepeatedMessage( - int number, int index) const { - map::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); - return iter->second.repeated_message_value->Get(index); -} - -MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { - map::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); - return iter->second.repeated_message_value->Mutable(index); -} - -MessageLite* ExtensionSet::AddMessage(int number, FieldType type, - const MessageLite& prototype, - const FieldDescriptor* descriptor) { - Extension* extension; - if (MaybeNewExtension(number, descriptor, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); - extension->is_repeated = true; - extension->repeated_message_value = - new RepeatedPtrField(); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); - } - - // RepeatedPtrField does not know how to Add() since it cannot - // allocate an abstract object, so we have to be tricky. - MessageLite* result = extension->repeated_message_value - ->AddFromCleared >(); - if (result == NULL) { - result = prototype.New(); - extension->repeated_message_value->AddAllocated(result); - } - return result; -} - -// Defined in extension_set_heavy.cc. -// MessageLite* ExtensionSet::AddMessage(int number, FieldType type, -// const Descriptor* message_type, -// MessageFactory* factory) - -#undef GOOGLE_DCHECK_TYPE - -void ExtensionSet::RemoveLast(int number) { - map::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - - Extension* extension = &iter->second; - GOOGLE_DCHECK(extension->is_repeated); - - switch(cpp_type(extension->type)) { - case WireFormatLite::CPPTYPE_INT32: - extension->repeated_int32_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_INT64: - extension->repeated_int64_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_UINT32: - extension->repeated_uint32_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_UINT64: - extension->repeated_uint64_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_FLOAT: - extension->repeated_float_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_DOUBLE: - extension->repeated_double_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_BOOL: - extension->repeated_bool_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_ENUM: - extension->repeated_enum_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_STRING: - extension->repeated_string_value->RemoveLast(); - break; - case WireFormatLite::CPPTYPE_MESSAGE: - extension->repeated_message_value->RemoveLast(); - break; - } -} - -void ExtensionSet::SwapElements(int number, int index1, int index2) { - map::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - - Extension* extension = &iter->second; - GOOGLE_DCHECK(extension->is_repeated); - - switch(cpp_type(extension->type)) { - case WireFormatLite::CPPTYPE_INT32: - extension->repeated_int32_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_INT64: - extension->repeated_int64_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_UINT32: - extension->repeated_uint32_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_UINT64: - extension->repeated_uint64_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_FLOAT: - extension->repeated_float_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_DOUBLE: - extension->repeated_double_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_BOOL: - extension->repeated_bool_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_ENUM: - extension->repeated_enum_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_STRING: - extension->repeated_string_value->SwapElements(index1, index2); - break; - case WireFormatLite::CPPTYPE_MESSAGE: - extension->repeated_message_value->SwapElements(index1, index2); - break; - } -} - -// =================================================================== - -void ExtensionSet::Clear() { - for (map::iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - iter->second.Clear(); - } -} - -void ExtensionSet::MergeFrom(const ExtensionSet& other) { - for (map::const_iterator iter = other.extensions_.begin(); - iter != other.extensions_.end(); ++iter) { - const Extension& other_extension = iter->second; - - if (other_extension.is_repeated) { - Extension* extension; - bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor, - &extension); - if (is_new) { - // Extension did not already exist in set. - extension->type = other_extension.type; - extension->is_repeated = true; - } else { - GOOGLE_DCHECK_EQ(extension->type, other_extension.type); - GOOGLE_DCHECK(extension->is_repeated); - } - - switch (cpp_type(other_extension.type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ - if (is_new) { \ - extension->repeated_##LOWERCASE##_value = \ - new REPEATED_TYPE; \ - } \ - extension->repeated_##LOWERCASE##_value->MergeFrom( \ - *other_extension.repeated_##LOWERCASE##_value); \ - break; - - HANDLE_TYPE( INT32, int32, RepeatedField < int32>); - HANDLE_TYPE( INT64, int64, RepeatedField < int64>); - HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>); - HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>); - HANDLE_TYPE( FLOAT, float, RepeatedField < float>); - HANDLE_TYPE( DOUBLE, double, RepeatedField < double>); - HANDLE_TYPE( BOOL, bool, RepeatedField < bool>); - HANDLE_TYPE( ENUM, enum, RepeatedField < int>); - HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); -#undef HANDLE_TYPE - - case WireFormatLite::CPPTYPE_MESSAGE: - if (is_new) { - extension->repeated_message_value = - new RepeatedPtrField(); - } - // We can't call RepeatedPtrField::MergeFrom() because - // it would attempt to allocate new objects. - RepeatedPtrField* other_repeated_message = - other_extension.repeated_message_value; - for (int i = 0; i < other_repeated_message->size(); i++) { - const MessageLite& other_message = other_repeated_message->Get(i); - MessageLite* target = extension->repeated_message_value - ->AddFromCleared >(); - if (target == NULL) { - target = other_message.New(); - extension->repeated_message_value->AddAllocated(target); - } - target->CheckTypeAndMergeFrom(other_message); - } - break; - } - } else { - if (!other_extension.is_cleared) { - switch (cpp_type(other_extension.type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ - Set##CAMELCASE(iter->first, other_extension.type, \ - other_extension.LOWERCASE##_value, \ - other_extension.descriptor); \ - break; - - HANDLE_TYPE( INT32, int32, Int32); - HANDLE_TYPE( INT64, int64, Int64); - HANDLE_TYPE(UINT32, uint32, UInt32); - HANDLE_TYPE(UINT64, uint64, UInt64); - HANDLE_TYPE( FLOAT, float, Float); - HANDLE_TYPE(DOUBLE, double, Double); - HANDLE_TYPE( BOOL, bool, Bool); - HANDLE_TYPE( ENUM, enum, Enum); -#undef HANDLE_TYPE - case WireFormatLite::CPPTYPE_STRING: - SetString(iter->first, other_extension.type, - *other_extension.string_value, - other_extension.descriptor); - break; - case WireFormatLite::CPPTYPE_MESSAGE: - MutableMessage(iter->first, other_extension.type, - *other_extension.message_value, - other_extension.descriptor) - ->CheckTypeAndMergeFrom(*other_extension.message_value); - break; - } - } - } - } -} - -void ExtensionSet::Swap(ExtensionSet* x) { - extensions_.swap(x->extensions_); -} - -bool ExtensionSet::IsInitialized() const { - // Extensions are never required. However, we need to check that all - // embedded messages are initialized. - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - const Extension& extension = iter->second; - if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { - if (extension.is_repeated) { - for (int i = 0; i < extension.repeated_message_value->size(); i++) { - if (!extension.repeated_message_value->Get(i).IsInitialized()) { - return false; - } - } - } else { - if (!extension.is_cleared) { - if (!extension.message_value->IsInitialized()) return false; - } - } - } - } - - return true; -} - -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper) { - int number = WireFormatLite::GetTagFieldNumber(tag); - WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); - - ExtensionInfo extension; - bool is_unknown; - if (!extension_finder->Find(number, &extension)) { - is_unknown = true; - } else if (extension.is_packed) { - is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - } else { - WireFormatLite::WireType expected_wire_type = - WireFormatLite::WireTypeForFieldType(real_type(extension.type)); - is_unknown = (wire_type != expected_wire_type); - } - - if (is_unknown) { - field_skipper->SkipField(input, tag); - } else if (extension.is_packed) { - uint32 size; - if (!input->ReadVarint32(&size)) return false; - io::CodedInputStream::Limit limit = input->PushLimit(size); - - switch (extension.type) { -#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - while (input->BytesUntilLimit() > 0) { \ - CPP_LOWERCASE value; \ - if (!WireFormatLite::ReadPrimitive< \ - CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ - input, &value)) return false; \ - Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ - true, value, extension.descriptor); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, Int32, int32); - HANDLE_TYPE( SINT64, Int64, int64); - HANDLE_TYPE( FIXED32, UInt32, uint32); - HANDLE_TYPE( FIXED64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, Int32, int32); - HANDLE_TYPE(SFIXED64, Int64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); -#undef HANDLE_TYPE - - case WireFormatLite::TYPE_ENUM: - while (input->BytesUntilLimit() > 0) { - int value; - if (!WireFormatLite::ReadPrimitive( - input, &value)) return false; - if (extension.enum_validity_check.func( - extension.enum_validity_check.arg, value)) { - AddEnum(number, WireFormatLite::TYPE_ENUM, true, value, - extension.descriptor); - } - } - break; - - case WireFormatLite::TYPE_STRING: - case WireFormatLite::TYPE_BYTES: - case WireFormatLite::TYPE_GROUP: - case WireFormatLite::TYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; - break; - } - - input->PopLimit(limit); - } else { - switch (extension.type) { -#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: { \ - CPP_LOWERCASE value; \ - if (!WireFormatLite::ReadPrimitive< \ - CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ - input, &value)) return false; \ - if (extension.is_repeated) { \ - Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ - false, value, extension.descriptor); \ - } else { \ - Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ - extension.descriptor); \ - } \ - } break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, Int32, int32); - HANDLE_TYPE( SINT64, Int64, int64); - HANDLE_TYPE( FIXED32, UInt32, uint32); - HANDLE_TYPE( FIXED64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, Int32, int32); - HANDLE_TYPE(SFIXED64, Int64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); -#undef HANDLE_TYPE - - case WireFormatLite::TYPE_ENUM: { - int value; - if (!WireFormatLite::ReadPrimitive( - input, &value)) return false; - - if (!extension.enum_validity_check.func( - extension.enum_validity_check.arg, value)) { - // Invalid value. Treat as unknown. - field_skipper->SkipUnknownEnum(number, value); - } else if (extension.is_repeated) { - AddEnum(number, WireFormatLite::TYPE_ENUM, false, value, - extension.descriptor); - } else { - SetEnum(number, WireFormatLite::TYPE_ENUM, value, - extension.descriptor); - } - break; - } - - case WireFormatLite::TYPE_STRING: { - string* value = extension.is_repeated ? - AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : - MutableString(number, WireFormatLite::TYPE_STRING, - extension.descriptor); - if (!WireFormatLite::ReadString(input, value)) return false; - break; - } - - case WireFormatLite::TYPE_BYTES: { - string* value = extension.is_repeated ? - AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : - MutableString(number, WireFormatLite::TYPE_STRING, - extension.descriptor); - if (!WireFormatLite::ReadBytes(input, value)) return false; - break; - } - - case WireFormatLite::TYPE_GROUP: { - MessageLite* value = extension.is_repeated ? - AddMessage(number, WireFormatLite::TYPE_GROUP, - *extension.message_prototype, extension.descriptor) : - MutableMessage(number, WireFormatLite::TYPE_GROUP, - *extension.message_prototype, extension.descriptor); - if (!WireFormatLite::ReadGroup(number, input, value)) return false; - break; - } - - case WireFormatLite::TYPE_MESSAGE: { - MessageLite* value = extension.is_repeated ? - AddMessage(number, WireFormatLite::TYPE_MESSAGE, - *extension.message_prototype, extension.descriptor) : - MutableMessage(number, WireFormatLite::TYPE_MESSAGE, - *extension.message_prototype, extension.descriptor); - if (!WireFormatLite::ReadMessage(input, value)) return false; - break; - } - } - } - - return true; -} - -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type) { - FieldSkipper skipper; - GeneratedExtensionFinder finder(containing_type); - return ParseField(tag, input, &finder, &skipper); -} - -// Defined in extension_set_heavy.cc. -// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, -// const MessageLite* containing_type, -// UnknownFieldSet* unknown_fields) - -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper) { - while (true) { - uint32 tag = input->ReadTag(); - switch (tag) { - case 0: - return true; - case WireFormatLite::kMessageSetItemStartTag: - if (!ParseMessageSetItem(input, extension_finder, field_skipper)) { - return false; - } - break; - default: - if (!ParseField(tag, input, extension_finder, field_skipper)) { - return false; - } - break; - } - } -} - -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type) { - FieldSkipper skipper; - GeneratedExtensionFinder finder(containing_type); - return ParseMessageSet(input, &finder, &skipper); -} - -// Defined in extension_set_heavy.cc. -// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, -// const MessageLite* containing_type, -// UnknownFieldSet* unknown_fields); - -bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper) { - // TODO(kenton): It would be nice to share code between this and - // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the - // differences would be hard to factor out. - - // This method parses a group which should contain two fields: - // required int32 type_id = 2; - // required data message = 3; - - // Once we see a type_id, we'll construct a fake tag for this extension - // which is the tag it would have had under the proto2 extensions wire - // format. - uint32 fake_tag = 0; - - // If we see message data before the type_id, we'll append it to this so - // we can parse it later. This will probably never happen in practice, - // as no MessageSet encoder I know of writes the message before the type ID. - // But, it's technically valid so we should allow it. - // TODO(kenton): Use a Cord instead? Do I care? - string message_data; - - while (true) { - uint32 tag = input->ReadTag(); - if (tag == 0) return false; - - switch (tag) { - case WireFormatLite::kMessageSetTypeIdTag: { - uint32 type_id; - if (!input->ReadVarint32(&type_id)) return false; - fake_tag = WireFormatLite::MakeTag(type_id, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - - if (!message_data.empty()) { - // We saw some message data before the type_id. Have to parse it - // now. - io::CodedInputStream sub_input( - reinterpret_cast(message_data.data()), - message_data.size()); - if (!ParseField(fake_tag, &sub_input, - extension_finder, field_skipper)) { - return false; - } - message_data.clear(); - } - - break; - } - - case WireFormatLite::kMessageSetMessageTag: { - if (fake_tag == 0) { - // We haven't seen a type_id yet. Append this data to message_data. - string temp; - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(&temp, length)) return false; - message_data.append(temp); - } else { - // Already saw type_id, so we can parse this directly. - if (!ParseField(fake_tag, input, - extension_finder, field_skipper)) { - return false; - } - } - - break; - } - - case WireFormatLite::kMessageSetItemEndTag: { - return true; - } - - default: { - if (!field_skipper->SkipField(input, tag)) return false; - } - } - } -} - -void ExtensionSet::SerializeWithCachedSizes( - int start_field_number, int end_field_number, - io::CodedOutputStream* output) const { - map::const_iterator iter; - for (iter = extensions_.lower_bound(start_field_number); - iter != extensions_.end() && iter->first < end_field_number; - ++iter) { - iter->second.SerializeFieldWithCachedSizes(iter->first, output); - } -} - -void ExtensionSet::SerializeMessageSetWithCachedSizes( - io::CodedOutputStream* output) const { - map::const_iterator iter; - for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { - iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); - } -} - -int ExtensionSet::ByteSize() const { - int total_size = 0; - - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - total_size += iter->second.ByteSize(iter->first); - } - - return total_size; -} - -int ExtensionSet::MessageSetByteSize() const { - int total_size = 0; - - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - total_size += iter->second.MessageSetItemByteSize(iter->first); - } - - return total_size; -} - -// Defined in extension_set_heavy.cc. -// int ExtensionSet::SpaceUsedExcludingSelf() const - -bool ExtensionSet::MaybeNewExtension(int number, - const FieldDescriptor* descriptor, - Extension** result) { - pair::iterator, bool> insert_result = - extensions_.insert(make_pair(number, Extension())); - *result = &insert_result.first->second; - (*result)->descriptor = descriptor; - return insert_result.second; -} - -// =================================================================== -// Methods of ExtensionSet::Extension - -void ExtensionSet::Extension::Clear() { - if (is_repeated) { - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ - repeated_##LOWERCASE##_value->Clear(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - } else { - if (!is_cleared) { - switch (cpp_type(type)) { - case WireFormatLite::CPPTYPE_STRING: - string_value->clear(); - break; - case WireFormatLite::CPPTYPE_MESSAGE: - message_value->Clear(); - break; - default: - // No need to do anything. Get*() will return the default value - // as long as is_cleared is true and Set*() will overwrite the - // previous value. - break; - } - - is_cleared = true; - } - } -} - -void ExtensionSet::Extension::SerializeFieldWithCachedSizes( - int number, - io::CodedOutputStream* output) const { - if (is_repeated) { - if (is_packed) { - if (cached_size == 0) return; - - WireFormatLite::WriteTag(number, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(cached_size); - - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormatLite::Write##CAMELCASE##NoTag( \ - repeated_##LOWERCASE##_value->Get(i), output); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); - HANDLE_TYPE( ENUM, Enum, enum); -#undef HANDLE_TYPE - - case WireFormatLite::TYPE_STRING: - case WireFormatLite::TYPE_BYTES: - case WireFormatLite::TYPE_GROUP: - case WireFormatLite::TYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; - break; - } - } else { - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormatLite::Write##CAMELCASE(number, \ - repeated_##LOWERCASE##_value->Get(i), output); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); - HANDLE_TYPE( STRING, String, string); - HANDLE_TYPE( BYTES, Bytes, string); - HANDLE_TYPE( ENUM, Enum, enum); - HANDLE_TYPE( GROUP, Group, message); - HANDLE_TYPE( MESSAGE, Message, message); -#undef HANDLE_TYPE - } - } - } else if (!is_cleared) { - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ - break - - HANDLE_TYPE( INT32, Int32, int32_value); - HANDLE_TYPE( INT64, Int64, int64_value); - HANDLE_TYPE( UINT32, UInt32, uint32_value); - HANDLE_TYPE( UINT64, UInt64, uint64_value); - HANDLE_TYPE( SINT32, SInt32, int32_value); - HANDLE_TYPE( SINT64, SInt64, int64_value); - HANDLE_TYPE( FIXED32, Fixed32, uint32_value); - HANDLE_TYPE( FIXED64, Fixed64, uint64_value); - HANDLE_TYPE(SFIXED32, SFixed32, int32_value); - HANDLE_TYPE(SFIXED64, SFixed64, int64_value); - HANDLE_TYPE( FLOAT, Float, float_value); - HANDLE_TYPE( DOUBLE, Double, double_value); - HANDLE_TYPE( BOOL, Bool, bool_value); - HANDLE_TYPE( STRING, String, *string_value); - HANDLE_TYPE( BYTES, Bytes, *string_value); - HANDLE_TYPE( ENUM, Enum, enum_value); - HANDLE_TYPE( GROUP, Group, *message_value); - HANDLE_TYPE( MESSAGE, Message, *message_value); -#undef HANDLE_TYPE - } - } -} - -void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( - int number, - io::CodedOutputStream* output) const { - if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { - // Not a valid MessageSet extension, but serialize it the normal way. - SerializeFieldWithCachedSizes(number, output); - return; - } - - if (is_cleared) return; - - // Start group. - output->WriteTag(WireFormatLite::kMessageSetItemStartTag); - - // Write type ID. - WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, - number, - output); - // Write message. - WireFormatLite::WriteMessageMaybeToArray( - WireFormatLite::kMessageSetMessageNumber, - *message_value, - output); - - // End group. - output->WriteTag(WireFormatLite::kMessageSetItemEndTag); -} - -int ExtensionSet::Extension::ByteSize(int number) const { - int result = 0; - - if (is_repeated) { - if (is_packed) { - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormatLite::CAMELCASE##Size( \ - repeated_##LOWERCASE##_value->Get(i)); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( ENUM, Enum, enum); -#undef HANDLE_TYPE - - // Stuff with fixed size. -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - result += WireFormatLite::k##CAMELCASE##Size * \ - repeated_##LOWERCASE##_value->size(); \ - break - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); -#undef HANDLE_TYPE - - case WireFormatLite::TYPE_STRING: - case WireFormatLite::TYPE_BYTES: - case WireFormatLite::TYPE_GROUP: - case WireFormatLite::TYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; - break; - } - - cached_size = result; - if (result > 0) { - result += io::CodedOutputStream::VarintSize32(result); - result += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(number, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); - } - } else { - int tag_size = WireFormatLite::TagSize(number, real_type(type)); - - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - result += tag_size * repeated_##LOWERCASE##_value->size(); \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormatLite::CAMELCASE##Size( \ - repeated_##LOWERCASE##_value->Get(i)); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( STRING, String, string); - HANDLE_TYPE( BYTES, Bytes, string); - HANDLE_TYPE( ENUM, Enum, enum); - HANDLE_TYPE( GROUP, Group, message); - HANDLE_TYPE( MESSAGE, Message, message); -#undef HANDLE_TYPE - - // Stuff with fixed size. -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ - repeated_##LOWERCASE##_value->size(); \ - break - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); -#undef HANDLE_TYPE - } - } - } else if (!is_cleared) { - result += WireFormatLite::TagSize(number, real_type(type)); - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ - break - - HANDLE_TYPE( INT32, Int32, int32_value); - HANDLE_TYPE( INT64, Int64, int64_value); - HANDLE_TYPE( UINT32, UInt32, uint32_value); - HANDLE_TYPE( UINT64, UInt64, uint64_value); - HANDLE_TYPE( SINT32, SInt32, int32_value); - HANDLE_TYPE( SINT64, SInt64, int64_value); - HANDLE_TYPE( STRING, String, *string_value); - HANDLE_TYPE( BYTES, Bytes, *string_value); - HANDLE_TYPE( ENUM, Enum, enum_value); - HANDLE_TYPE( GROUP, Group, *message_value); - HANDLE_TYPE( MESSAGE, Message, *message_value); -#undef HANDLE_TYPE - - // Stuff with fixed size. -#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ - case WireFormatLite::TYPE_##UPPERCASE: \ - result += WireFormatLite::k##CAMELCASE##Size; \ - break - HANDLE_TYPE( FIXED32, Fixed32); - HANDLE_TYPE( FIXED64, Fixed64); - HANDLE_TYPE(SFIXED32, SFixed32); - HANDLE_TYPE(SFIXED64, SFixed64); - HANDLE_TYPE( FLOAT, Float); - HANDLE_TYPE( DOUBLE, Double); - HANDLE_TYPE( BOOL, Bool); -#undef HANDLE_TYPE - } - } - - return result; -} - -int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { - if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { - // Not a valid MessageSet extension, but compute the byte size for it the - // normal way. - return ByteSize(number); - } - - if (is_cleared) return 0; - - int our_size = WireFormatLite::kMessageSetItemTagsSize; - - // type_id - our_size += io::CodedOutputStream::VarintSize32(number); - - // message - int message_size = message_value->ByteSize(); - - our_size += io::CodedOutputStream::VarintSize32(message_size); - our_size += message_size; - - return our_size; -} - -int ExtensionSet::Extension::GetSize() const { - GOOGLE_DCHECK(is_repeated); - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ - return repeated_##LOWERCASE##_value->size() - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; -} - -void ExtensionSet::Extension::Free() { - if (is_repeated) { - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ - delete repeated_##LOWERCASE##_value; \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - } else { - switch (cpp_type(type)) { - case WireFormatLite::CPPTYPE_STRING: - delete string_value; - break; - case WireFormatLite::CPPTYPE_MESSAGE: - delete message_value; - break; - default: - break; - } - } -} - -// Defined in extension_set_heavy.cc. -// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/extension_set.h b/Resources/NetHook/google/protobuf/extension_set.h deleted file mode 100644 index 14d5d150..00000000 --- a/Resources/NetHook/google/protobuf/extension_set.h +++ /dev/null @@ -1,902 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ -#define GOOGLE_PROTOBUF_EXTENSION_SET_H__ - -#include -#include -#include -#include -#include - -#include - -namespace google { - -namespace protobuf { - class Descriptor; // descriptor.h - class FieldDescriptor; // descriptor.h - class DescriptorPool; // descriptor.h - class MessageLite; // message_lite.h - class Message; // message.h - class MessageFactory; // message.h - class UnknownFieldSet; // unknown_field_set.h - namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h - } - namespace internal { - class FieldSkipper; // wire_format_lite.h - class RepeatedPtrFieldBase; // repeated_field.h - } - template class RepeatedField; // repeated_field.h - template class RepeatedPtrField; // repeated_field.h -} - -namespace protobuf { -namespace internal { - -// Used to store values of type WireFormatLite::FieldType without having to -// #include wire_format_lite.h. Also, ensures that we use only one byte to -// store these values, which is important to keep the layout of -// ExtensionSet::Extension small. -typedef uint8 FieldType; - -// A function which, given an integer value, returns true if the number -// matches one of the defined values for the corresponding enum type. This -// is used with RegisterEnumExtension, below. -typedef bool EnumValidityFunc(int number); - -// Version of the above which takes an argument. This is needed to deal with -// extensions that are not compiled in. -typedef bool EnumValidityFuncWithArg(const void* arg, int number); - -// Information about a registered extension. -struct ExtensionInfo { - inline ExtensionInfo() {} - inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed) - : type(type), is_repeated(is_repeated), is_packed(is_packed), - descriptor(NULL) {} - - FieldType type; - bool is_repeated; - bool is_packed; - - struct EnumValidityCheck { - EnumValidityFuncWithArg* func; - const void* arg; - }; - - union { - EnumValidityCheck enum_validity_check; - const MessageLite* message_prototype; - }; - - // The descriptor for this extension, if one exists and is known. May be - // NULL. Must not be NULL if the descriptor for the extension does not - // live in the same pool as the descriptor for the containing type. - const FieldDescriptor* descriptor; -}; - -// Abstract interface for an object which looks up extension definitions. Used -// when parsing. -class LIBPROTOBUF_EXPORT ExtensionFinder { - public: - virtual ~ExtensionFinder(); - - // Find the extension with the given containing type and number. - virtual bool Find(int number, ExtensionInfo* output) = 0; -}; - -// Implementation of ExtensionFinder which finds extensions defined in .proto -// files which have been compiled into the binary. -class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { - public: - GeneratedExtensionFinder(const MessageLite* containing_type) - : containing_type_(containing_type) {} - virtual ~GeneratedExtensionFinder() {} - - // Returns true and fills in *output if found, otherwise returns false. - virtual bool Find(int number, ExtensionInfo* output); - - private: - const MessageLite* containing_type_; -}; - -// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for -// finding extensions from a DescriptorPool. - -// This is an internal helper class intended for use within the protocol buffer -// library and generated classes. Clients should not use it directly. Instead, -// use the generated accessors such as GetExtension() of the class being -// extended. -// -// This class manages extensions for a protocol message object. The -// message's HasExtension(), GetExtension(), MutableExtension(), and -// ClearExtension() methods are just thin wrappers around the embedded -// ExtensionSet. When parsing, if a tag number is encountered which is -// inside one of the message type's extension ranges, the tag is passed -// off to the ExtensionSet for parsing. Etc. -class LIBPROTOBUF_EXPORT ExtensionSet { - public: - ExtensionSet(); - ~ExtensionSet(); - - // These are called at startup by protocol-compiler-generated code to - // register known extensions. The registrations are used by ParseField() - // to look up extensions for parsed field numbers. Note that dynamic parsing - // does not use ParseField(); only protocol-compiler-generated parsing - // methods do. - static void RegisterExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed); - static void RegisterEnumExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, - EnumValidityFunc* is_valid); - static void RegisterMessageExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, - const MessageLite* prototype); - - // ================================================================= - - // Add all fields which are currently present to the given vector. This - // is useful to implement Reflection::ListFields(). - void AppendToList(const Descriptor* containing_type, - const DescriptorPool* pool, - vector* output) const; - - // ================================================================= - // Accessors - // - // Generated message classes include type-safe templated wrappers around - // these methods. Generally you should use those rather than call these - // directly, unless you are doing low-level memory management. - // - // When calling any of these accessors, the extension number requested - // MUST exist in the DescriptorPool provided to the constructor. Otheriwse, - // the method will fail an assert. Normally, though, you would not call - // these directly; you would either call the generated accessors of your - // message class (e.g. GetExtension()) or you would call the accessors - // of the reflection interface. In both cases, it is impossible to - // trigger this assert failure: the generated accessors only accept - // linked-in extension types as parameters, while the Reflection interface - // requires you to provide the FieldDescriptor describing the extension. - // - // When calling any of these accessors, a protocol-compiler-generated - // implementation of the extension corresponding to the number MUST - // be linked in, and the FieldDescriptor used to refer to it MUST be - // the one generated by that linked-in code. Otherwise, the method will - // die on an assert failure. The message objects returned by the message - // accessors are guaranteed to be of the correct linked-in type. - // - // These methods pretty much match Reflection except that: - // - They're not virtual. - // - They identify fields by number rather than FieldDescriptors. - // - They identify enum values using integers rather than descriptors. - // - Strings provide Mutable() in addition to Set() accessors. - - bool Has(int number) const; - int ExtensionSize(int number) const; // Size of a repeated extension. - void ClearExtension(int number); - - // singular fields ------------------------------------------------- - - int32 GetInt32 (int number, int32 default_value) const; - int64 GetInt64 (int number, int64 default_value) const; - uint32 GetUInt32(int number, uint32 default_value) const; - uint64 GetUInt64(int number, uint64 default_value) const; - float GetFloat (int number, float default_value) const; - double GetDouble(int number, double default_value) const; - bool GetBool (int number, bool default_value) const; - int GetEnum (int number, int default_value) const; - const string & GetString (int number, const string& default_value) const; - const MessageLite& GetMessage(int number, - const MessageLite& default_value) const; - const MessageLite& GetMessage(int number, const Descriptor* message_type, - MessageFactory* factory) const; - - // |descriptor| may be NULL so long as it is known that the descriptor for - // the extension lives in the same pool as the descriptor for the containing - // type. -#define desc const FieldDescriptor* descriptor // avoid line wrapping - void SetInt32 (int number, FieldType type, int32 value, desc); - void SetInt64 (int number, FieldType type, int64 value, desc); - void SetUInt32(int number, FieldType type, uint32 value, desc); - void SetUInt64(int number, FieldType type, uint64 value, desc); - void SetFloat (int number, FieldType type, float value, desc); - void SetDouble(int number, FieldType type, double value, desc); - void SetBool (int number, FieldType type, bool value, desc); - void SetEnum (int number, FieldType type, int value, desc); - void SetString(int number, FieldType type, const string& value, desc); - string * MutableString (int number, FieldType type, desc); - MessageLite* MutableMessage(int number, FieldType type, - const MessageLite& prototype, desc); - MessageLite* MutableMessage(const FieldDescriptor* decsriptor, - MessageFactory* factory); -#undef desc - - // repeated fields ------------------------------------------------- - - int32 GetRepeatedInt32 (int number, int index) const; - int64 GetRepeatedInt64 (int number, int index) const; - uint32 GetRepeatedUInt32(int number, int index) const; - uint64 GetRepeatedUInt64(int number, int index) const; - float GetRepeatedFloat (int number, int index) const; - double GetRepeatedDouble(int number, int index) const; - bool GetRepeatedBool (int number, int index) const; - int GetRepeatedEnum (int number, int index) const; - const string & GetRepeatedString (int number, int index) const; - const MessageLite& GetRepeatedMessage(int number, int index) const; - - void SetRepeatedInt32 (int number, int index, int32 value); - void SetRepeatedInt64 (int number, int index, int64 value); - void SetRepeatedUInt32(int number, int index, uint32 value); - void SetRepeatedUInt64(int number, int index, uint64 value); - void SetRepeatedFloat (int number, int index, float value); - void SetRepeatedDouble(int number, int index, double value); - void SetRepeatedBool (int number, int index, bool value); - void SetRepeatedEnum (int number, int index, int value); - void SetRepeatedString(int number, int index, const string& value); - string * MutableRepeatedString (int number, int index); - MessageLite* MutableRepeatedMessage(int number, int index); - -#define desc const FieldDescriptor* descriptor // avoid line wrapping - void AddInt32 (int number, FieldType type, bool packed, int32 value, desc); - void AddInt64 (int number, FieldType type, bool packed, int64 value, desc); - void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc); - void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc); - void AddFloat (int number, FieldType type, bool packed, float value, desc); - void AddDouble(int number, FieldType type, bool packed, double value, desc); - void AddBool (int number, FieldType type, bool packed, bool value, desc); - void AddEnum (int number, FieldType type, bool packed, int value, desc); - void AddString(int number, FieldType type, const string& value, desc); - string * AddString (int number, FieldType type, desc); - MessageLite* AddMessage(int number, FieldType type, - const MessageLite& prototype, desc); - MessageLite* AddMessage(const FieldDescriptor* descriptor, - MessageFactory* factory); -#undef desc - - void RemoveLast(int number); - void SwapElements(int number, int index1, int index2); - - // ----------------------------------------------------------------- - // TODO(kenton): Hardcore memory management accessors - - // ================================================================= - // convenience methods for implementing methods of Message - // - // These could all be implemented in terms of the other methods of this - // class, but providing them here helps keep the generated code size down. - - void Clear(); - void MergeFrom(const ExtensionSet& other); - void Swap(ExtensionSet* other); - bool IsInitialized() const; - - // Parses a single extension from the input. The input should start out - // positioned immediately after the tag. |containing_type| is the default - // instance for the containing message; it is used only to look up the - // extension by number. See RegisterExtension(), above. Unlike the other - // methods of ExtensionSet, this only works for generated message types -- - // it looks up extensions registered using RegisterExtension(). - bool ParseField(uint32 tag, io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper); - - // Specific versions for lite or full messages (constructs the appropriate - // FieldSkipper automatically). - bool ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type); - bool ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields); - - // Parse an entire message in MessageSet format. Such messages have no - // fields, only extensions. - bool ParseMessageSet(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper); - - // Specific versions for lite or full messages (constructs the appropriate - // FieldSkipper automatically). - bool ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type); - bool ParseMessageSet(io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields); - - // Write all extension fields with field numbers in the range - // [start_field_number, end_field_number) - // to the output stream, using the cached sizes computed when ByteSize() was - // last called. Note that the range bounds are inclusive-exclusive. - void SerializeWithCachedSizes(int start_field_number, - int end_field_number, - io::CodedOutputStream* output) const; - - // Same as SerializeWithCachedSizes, but without any bounds checking. - // The caller must ensure that target has sufficient capacity for the - // serialized extensions. - // - // Returns a pointer past the last written byte. - uint8* SerializeWithCachedSizesToArray(int start_field_number, - int end_field_number, - uint8* target) const; - - // Like above but serializes in MessageSet format. - void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const; - uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; - - // Returns the total serialized size of all the extensions. - int ByteSize() const; - - // Like ByteSize() but uses MessageSet format. - int MessageSetByteSize() const; - - // Returns (an estimate of) the total number of bytes used for storing the - // extensions in memory, excluding sizeof(*this). If the ExtensionSet is - // for a lite message (and thus possibly contains lite messages), the results - // are undefined (might work, might crash, might corrupt data, might not even - // be linked in). It's up to the protocol compiler to avoid calling this on - // such ExtensionSets (easy enough since lite messages don't implement - // SpaceUsed()). - int SpaceUsedExcludingSelf() const; - - private: - - struct Extension { - union { - int32 int32_value; - int64 int64_value; - uint32 uint32_value; - uint64 uint64_value; - float float_value; - double double_value; - bool bool_value; - int enum_value; - string* string_value; - MessageLite* message_value; - - RepeatedField * repeated_int32_value; - RepeatedField * repeated_int64_value; - RepeatedField * repeated_uint32_value; - RepeatedField * repeated_uint64_value; - RepeatedField * repeated_float_value; - RepeatedField * repeated_double_value; - RepeatedField * repeated_bool_value; - RepeatedField * repeated_enum_value; - RepeatedPtrField* repeated_string_value; - RepeatedPtrField* repeated_message_value; - }; - - FieldType type; - bool is_repeated; - - // For singular types, indicates if the extension is "cleared". This - // happens when an extension is set and then later cleared by the caller. - // We want to keep the Extension object around for reuse, so instead of - // removing it from the map, we just set is_cleared = true. This has no - // meaning for repeated types; for those, the size of the RepeatedField - // simply becomes zero when cleared. - bool is_cleared; - - // For repeated types, this indicates if the [packed=true] option is set. - bool is_packed; - - // The descriptor for this extension, if one exists and is known. May be - // NULL. Must not be NULL if the descriptor for the extension does not - // live in the same pool as the descriptor for the containing type. - const FieldDescriptor* descriptor; - - // For packed fields, the size of the packed data is recorded here when - // ByteSize() is called then used during serialization. - // TODO(kenton): Use atomic when C++ supports it. - mutable int cached_size; - - // Some helper methods for operations on a single Extension. - void SerializeFieldWithCachedSizes( - int number, - io::CodedOutputStream* output) const; - uint8* SerializeFieldWithCachedSizesToArray( - int number, - uint8* target) const; - void SerializeMessageSetItemWithCachedSizes( - int number, - io::CodedOutputStream* output) const; - uint8* SerializeMessageSetItemWithCachedSizesToArray( - int number, - uint8* target) const; - int ByteSize(int number) const; - int MessageSetItemByteSize(int number) const; - void Clear(); - int GetSize() const; - void Free(); - int SpaceUsedExcludingSelf() const; - }; - - // Gets the extension with the given number, creating it if it does not - // already exist. Returns true if the extension did not already exist. - bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, - Extension** result); - - // Parse a single MessageSet item -- called just after the item group start - // tag has been read. - bool ParseMessageSetItem(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - FieldSkipper* field_skipper); - - - // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This - // friendship should automatically extend to ExtensionSet::Extension, but - // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this - // correctly. So, we must provide helpers for calling methods of that - // class. - - // Defined in extension_set_heavy.cc. - static inline int RepeatedMessage_SpaceUsedExcludingSelf( - RepeatedPtrFieldBase* field); - - // The Extension struct is small enough to be passed by value, so we use it - // directly as the value type in the map rather than use pointers. We use - // a map rather than hash_map here because we expect most ExtensionSets will - // only contain a small number of extensions whereas hash_map is optimized - // for 100 elements or more. Also, we want AppendToList() to order fields - // by field number. - map extensions_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); -}; - -// These are just for convenience... -inline void ExtensionSet::SetString(int number, FieldType type, - const string& value, - const FieldDescriptor* descriptor) { - MutableString(number, type, descriptor)->assign(value); -} -inline void ExtensionSet::SetRepeatedString(int number, int index, - const string& value) { - MutableRepeatedString(number, index)->assign(value); -} -inline void ExtensionSet::AddString(int number, FieldType type, - const string& value, - const FieldDescriptor* descriptor) { - AddString(number, type, descriptor)->assign(value); -} - -// =================================================================== -// Glue for generated extension accessors - -// ------------------------------------------------------------------- -// Template magic - -// First we have a set of classes representing "type traits" for different -// field types. A type traits class knows how to implement basic accessors -// for extensions of a particular type given an ExtensionSet. The signature -// for a type traits class looks like this: -// -// class TypeTraits { -// public: -// typedef ? ConstType; -// typedef ? MutableType; -// -// static inline ConstType Get(int number, const ExtensionSet& set); -// static inline void Set(int number, ConstType value, ExtensionSet* set); -// static inline MutableType Mutable(int number, ExtensionSet* set); -// -// // Variants for repeated fields. -// static inline ConstType Get(int number, const ExtensionSet& set, -// int index); -// static inline void Set(int number, int index, -// ConstType value, ExtensionSet* set); -// static inline MutableType Mutable(int number, int index, -// ExtensionSet* set); -// static inline void Add(int number, ConstType value, ExtensionSet* set); -// static inline MutableType Add(int number, ExtensionSet* set); -// }; -// -// Not all of these methods make sense for all field types. For example, the -// "Mutable" methods only make sense for strings and messages, and the -// repeated methods only make sense for repeated types. So, each type -// traits class implements only the set of methods from this signature that it -// actually supports. This will cause a compiler error if the user tries to -// access an extension using a method that doesn't make sense for its type. -// For example, if "foo" is an extension of type "optional int32", then if you -// try to write code like: -// my_message.MutableExtension(foo) -// you will get a compile error because PrimitiveTypeTraits does not -// have a "Mutable()" method. - -// ------------------------------------------------------------------- -// PrimitiveTypeTraits - -// Since the ExtensionSet has different methods for each primitive type, -// we must explicitly define the methods of the type traits class for each -// known type. -template -class PrimitiveTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set, - ConstType default_value); - static inline void Set(int number, FieldType field_type, - ConstType value, ExtensionSet* set); -}; - -template -class RepeatedPrimitiveTypeTraits { - public: - typedef Type ConstType; - - static inline Type Get(int number, const ExtensionSet& set, int index); - static inline void Set(int number, int index, Type value, ExtensionSet* set); - static inline void Add(int number, FieldType field_type, - bool is_packed, Type value, ExtensionSet* set); -}; - -#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ -template<> inline TYPE PrimitiveTypeTraits::Get( \ - int number, const ExtensionSet& set, TYPE default_value) { \ - return set.Get##METHOD(number, default_value); \ -} \ -template<> inline void PrimitiveTypeTraits::Set( \ - int number, FieldType field_type, TYPE value, ExtensionSet* set) { \ - set->Set##METHOD(number, field_type, value, NULL); \ -} \ - \ -template<> inline TYPE RepeatedPrimitiveTypeTraits::Get( \ - int number, const ExtensionSet& set, int index) { \ - return set.GetRepeated##METHOD(number, index); \ -} \ -template<> inline void RepeatedPrimitiveTypeTraits::Set( \ - int number, int index, TYPE value, ExtensionSet* set) { \ - set->SetRepeated##METHOD(number, index, value); \ -} \ -template<> inline void RepeatedPrimitiveTypeTraits::Add( \ - int number, FieldType field_type, bool is_packed, \ - TYPE value, ExtensionSet* set) { \ - set->Add##METHOD(number, field_type, is_packed, value, NULL); \ -} - -PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool) - -#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE - -// ------------------------------------------------------------------- -// StringTypeTraits - -// Strings support both Set() and Mutable(). -class LIBPROTOBUF_EXPORT StringTypeTraits { - public: - typedef const string& ConstType; - typedef string* MutableType; - - static inline const string& Get(int number, const ExtensionSet& set, - ConstType default_value) { - return set.GetString(number, default_value); - } - static inline void Set(int number, FieldType field_type, - const string& value, ExtensionSet* set) { - set->SetString(number, field_type, value, NULL); - } - static inline string* Mutable(int number, FieldType field_type, - ExtensionSet* set) { - return set->MutableString(number, field_type, NULL); - } -}; - -class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { - public: - typedef const string& ConstType; - typedef string* MutableType; - - static inline const string& Get(int number, const ExtensionSet& set, - int index) { - return set.GetRepeatedString(number, index); - } - static inline void Set(int number, int index, - const string& value, ExtensionSet* set) { - set->SetRepeatedString(number, index, value); - } - static inline string* Mutable(int number, int index, ExtensionSet* set) { - return set->MutableRepeatedString(number, index); - } - static inline void Add(int number, FieldType field_type, - bool /*is_packed*/, const string& value, - ExtensionSet* set) { - set->AddString(number, field_type, value, NULL); - } - static inline string* Add(int number, FieldType field_type, - ExtensionSet* set) { - return set->AddString(number, field_type, NULL); - } -}; - -// ------------------------------------------------------------------- -// EnumTypeTraits - -// ExtensionSet represents enums using integers internally, so we have to -// static_cast around. -template -class EnumTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set, - ConstType default_value) { - return static_cast(set.GetEnum(number, default_value)); - } - static inline void Set(int number, FieldType field_type, - ConstType value, ExtensionSet* set) { - GOOGLE_DCHECK(IsValid(value)); - set->SetEnum(number, field_type, value, NULL); - } -}; - -template -class RepeatedEnumTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set, int index) { - return static_cast(set.GetRepeatedEnum(number, index)); - } - static inline void Set(int number, int index, - ConstType value, ExtensionSet* set) { - GOOGLE_DCHECK(IsValid(value)); - set->SetRepeatedEnum(number, index, value); - } - static inline void Add(int number, FieldType field_type, - bool is_packed, ConstType value, ExtensionSet* set) { - GOOGLE_DCHECK(IsValid(value)); - set->AddEnum(number, field_type, is_packed, value, NULL); - } -}; - -// ------------------------------------------------------------------- -// MessageTypeTraits - -// ExtensionSet guarantees that when manipulating extensions with message -// types, the implementation used will be the compiled-in class representing -// that type. So, we can static_cast down to the exact type we expect. -template -class MessageTypeTraits { - public: - typedef const Type& ConstType; - typedef Type* MutableType; - - static inline ConstType Get(int number, const ExtensionSet& set, - ConstType default_value) { - return static_cast( - set.GetMessage(number, default_value)); - } - static inline MutableType Mutable(int number, FieldType field_type, - ExtensionSet* set) { - return static_cast( - set->MutableMessage(number, field_type, Type::default_instance(), NULL)); - } -}; - -template -class RepeatedMessageTypeTraits { - public: - typedef const Type& ConstType; - typedef Type* MutableType; - - static inline ConstType Get(int number, const ExtensionSet& set, int index) { - return static_cast(set.GetRepeatedMessage(number, index)); - } - static inline MutableType Mutable(int number, int index, ExtensionSet* set) { - return static_cast(set->MutableRepeatedMessage(number, index)); - } - static inline MutableType Add(int number, FieldType field_type, - ExtensionSet* set) { - return static_cast( - set->AddMessage(number, field_type, Type::default_instance(), NULL)); - } -}; - -// ------------------------------------------------------------------- -// ExtensionIdentifier - -// This is the type of actual extension objects. E.g. if you have: -// extends Foo with optional int32 bar = 1234; -// then "bar" will be defined in C++ as: -// ExtensionIdentifier, 1, false> bar(1234); -// -// Note that we could, in theory, supply the field number as a template -// parameter, and thus make an instance of ExtensionIdentifier have no -// actual contents. However, if we did that, then using at extension -// identifier would not necessarily cause the compiler to output any sort -// of reference to any simple defined in the extension's .pb.o file. Some -// linkers will actually drop object files that are not explicitly referenced, -// but that would be bad because it would cause this extension to not be -// registered at static initialization, and therefore using it would crash. - -template -class ExtensionIdentifier { - public: - typedef TypeTraitsType TypeTraits; - typedef ExtendeeType Extendee; - - ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value) - : number_(number), default_value_(default_value) {} - inline int number() const { return number_; } - typename TypeTraits::ConstType default_value() const { - return default_value_; - } - - private: - const int number_; - typename TypeTraits::ConstType default_value_; -}; - -// ------------------------------------------------------------------- -// Generated accessors - -// This macro should be expanded in the context of a generated type which -// has extensions. -// -// We use "_proto_TypeTraits" as a type name below because "TypeTraits" -// causes problems if the class has a nested message or enum type with that -// name and "_TypeTraits" is technically reserved for the C++ library since -// it starts with an underscore followed by a capital letter. -#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \ - /* Has, Size, Clear */ \ - template \ - inline bool HasExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \ - return _extensions_.Has(id.number()); \ - } \ - \ - template \ - inline void ClearExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \ - _extensions_.ClearExtension(id.number()); \ - } \ - \ - template \ - inline int ExtensionSize( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \ - return _extensions_.ExtensionSize(id.number()); \ - } \ - \ - /* Singular accessors */ \ - template \ - inline typename _proto_TypeTraits::ConstType GetExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \ - return _proto_TypeTraits::Get(id.number(), _extensions_, \ - id.default_value()); \ - } \ - \ - template \ - inline typename _proto_TypeTraits::MutableType MutableExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \ - return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\ - } \ - \ - template \ - inline void SetExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \ - typename _proto_TypeTraits::ConstType value) { \ - _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_); \ - } \ - \ - /* Repeated accessors */ \ - template \ - inline typename _proto_TypeTraits::ConstType GetExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \ - int index) const { \ - return _proto_TypeTraits::Get(id.number(), _extensions_, index); \ - } \ - \ - template \ - inline typename _proto_TypeTraits::MutableType MutableExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \ - int index) { \ - return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \ - } \ - \ - template \ - inline void SetExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \ - int index, typename _proto_TypeTraits::ConstType value) { \ - _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \ - } \ - \ - template \ - inline typename _proto_TypeTraits::MutableType AddExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \ - return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_); \ - } \ - \ - template \ - inline void AddExtension( \ - const ::google::protobuf::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \ - typename _proto_TypeTraits::ConstType value) { \ - _proto_TypeTraits::Add(id.number(), field_type, is_packed, \ - value, &_extensions_); \ - } - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__ diff --git a/Resources/NetHook/google/protobuf/extension_set_heavy.cc b/Resources/NetHook/google/protobuf/extension_set_heavy.cc deleted file mode 100644 index 2721f15d..00000000 --- a/Resources/NetHook/google/protobuf/extension_set_heavy.cc +++ /dev/null @@ -1,457 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Contains methods defined in extension_set.h which cannot be part of the -// lite library because they use descriptors or reflection. - -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -// Implementation of ExtensionFinder which finds extensions in a given -// DescriptorPool, using the given MessageFactory to construct sub-objects. -// This class is implemented in extension_set_heavy.cc. -class DescriptorPoolExtensionFinder : public ExtensionFinder { - public: - DescriptorPoolExtensionFinder(const DescriptorPool* pool, - MessageFactory* factory, - const Descriptor* containing_type) - : pool_(pool), factory_(factory), containing_type_(containing_type) {} - virtual ~DescriptorPoolExtensionFinder() {} - - virtual bool Find(int number, ExtensionInfo* output); - - private: - const DescriptorPool* pool_; - MessageFactory* factory_; - const Descriptor* containing_type_; -}; - -void ExtensionSet::AppendToList(const Descriptor* containing_type, - const DescriptorPool* pool, - vector* output) const { - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - bool has = false; - if (iter->second.is_repeated) { - has = iter->second.GetSize() > 0; - } else { - has = !iter->second.is_cleared; - } - - if (has) { - // TODO(kenton): Looking up each field by number is somewhat unfortunate. - // Is there a better way? The problem is that descriptors are lazily- - // initialized, so they might not even be constructed until - // AppendToList() is called. - - if (iter->second.descriptor == NULL) { - output->push_back(pool->FindExtensionByNumber( - containing_type, iter->first)); - } else { - output->push_back(iter->second.descriptor); - } - } - } -} - -inline FieldDescriptor::Type real_type(FieldType type) { - GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); - return static_cast(type); -} - -inline FieldDescriptor::CppType cpp_type(FieldType type) { - return FieldDescriptor::TypeToCppType( - static_cast(type)); -} - -#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ - GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ - : FieldDescriptor::LABEL_OPTIONAL, \ - FieldDescriptor::LABEL_##LABEL); \ - GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) - -const MessageLite& ExtensionSet::GetMessage(int number, - const Descriptor* message_type, - MessageFactory* factory) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end() || iter->second.is_cleared) { - // Not present. Return the default value. - return *factory->GetPrototype(message_type); - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - return *iter->second.message_value; - } -} - -MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { - extension->type = descriptor->type(); - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = false; - extension->is_packed = false; - const MessageLite* prototype = - factory->GetPrototype(descriptor->message_type()); - GOOGLE_CHECK(prototype != NULL); - extension->message_value = prototype->New(); - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - } - extension->is_cleared = false; - return extension->message_value; -} - -MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { - extension->type = descriptor->type(); - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = true; - extension->repeated_message_value = - new RepeatedPtrField(); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); - } - - // RepeatedPtrField does not know how to Add() since it cannot - // allocate an abstract object, so we have to be tricky. - MessageLite* result = extension->repeated_message_value - ->AddFromCleared >(); - if (result == NULL) { - const MessageLite* prototype; - if (extension->repeated_message_value->size() == 0) { - prototype = factory->GetPrototype(descriptor->message_type()); - GOOGLE_CHECK(prototype != NULL); - } else { - prototype = &extension->repeated_message_value->Get(0); - } - result = prototype->New(); - extension->repeated_message_value->AddAllocated(result); - } - return result; -} - -static bool ValidateEnumUsingDescriptor(const void* arg, int number) { - return reinterpret_cast(arg) - ->FindValueByNumber(number) != NULL; -} - -bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { - const FieldDescriptor* extension = - pool_->FindExtensionByNumber(containing_type_, number); - if (extension == NULL) { - return false; - } else { - output->type = extension->type(); - output->is_repeated = extension->is_repeated(); - output->is_packed = extension->options().packed(); - output->descriptor = extension; - if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - output->message_prototype = - factory_->GetPrototype(extension->message_type()); - GOOGLE_CHECK(output->message_prototype != NULL) - << "Extension factory's GetPrototype() returned NULL for extension: " - << extension->full_name(); - } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - output->enum_validity_check.func = ValidateEnumUsingDescriptor; - output->enum_validity_check.arg = extension->enum_type(); - } - - return true; - } -} - -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields) { - UnknownFieldSetFieldSkipper skipper(unknown_fields); - if (input->GetExtensionPool() == NULL) { - GeneratedExtensionFinder finder(containing_type); - return ParseField(tag, input, &finder, &skipper); - } else { - DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), - input->GetExtensionFactory(), - containing_type->GetDescriptor()); - return ParseField(tag, input, &finder, &skipper); - } -} - -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields) { - UnknownFieldSetFieldSkipper skipper(unknown_fields); - if (input->GetExtensionPool() == NULL) { - GeneratedExtensionFinder finder(containing_type); - return ParseMessageSet(input, &finder, &skipper); - } else { - DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), - input->GetExtensionFactory(), - containing_type->GetDescriptor()); - return ParseMessageSet(input, &finder, &skipper); - } -} - -int ExtensionSet::SpaceUsedExcludingSelf() const { - int total_size = - extensions_.size() * sizeof(map::value_type); - for (map::const_iterator iter = extensions_.begin(), - end = extensions_.end(); - iter != end; - ++iter) { - total_size += iter->second.SpaceUsedExcludingSelf(); - } - return total_size; -} - -inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf( - RepeatedPtrFieldBase* field) { - return field->SpaceUsedExcludingSelf >(); -} - -int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { - int total_size = 0; - if (is_repeated) { - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - total_size += sizeof(*repeated_##LOWERCASE##_value) + \ - repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - // repeated_message_value is actually a RepeatedPtrField, - // but MessageLite has no SpaceUsed(), so we must directly call - // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type - // handler. - total_size += sizeof(*repeated_message_value) + - RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value); - break; - } - } else { - switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: - total_size += sizeof(*string_value) + - StringSpaceUsedExcludingSelf(*string_value); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - total_size += down_cast(message_value)->SpaceUsed(); - break; - default: - // No extra storage costs for primitive types. - break; - } - } - return total_size; -} - -// The Serialize*ToArray methods are only needed in the heavy library, as -// the lite library only generates SerializeWithCachedSizes. -uint8* ExtensionSet::SerializeWithCachedSizesToArray( - int start_field_number, int end_field_number, - uint8* target) const { - map::const_iterator iter; - for (iter = extensions_.lower_bound(start_field_number); - iter != extensions_.end() && iter->first < end_field_number; - ++iter) { - target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first, - target); - } - return target; -} - -uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( - uint8* target) const { - map::const_iterator iter; - for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { - target = iter->second.SerializeMessageSetItemWithCachedSizesToArray( - iter->first, target); - } - return target; -} - -uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( - int number, uint8* target) const { - if (is_repeated) { - if (is_packed) { - if (cached_size == 0) return target; - - target = WireFormatLite::WriteTagToArray(number, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); - target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target); - - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \ - repeated_##LOWERCASE##_value->Get(i), target); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); - HANDLE_TYPE( ENUM, Enum, enum); -#undef HANDLE_TYPE - - case WireFormatLite::TYPE_STRING: - case WireFormatLite::TYPE_BYTES: - case WireFormatLite::TYPE_GROUP: - case WireFormatLite::TYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; - break; - } - } else { - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - target = WireFormatLite::Write##CAMELCASE##ToArray(number, \ - repeated_##LOWERCASE##_value->Get(i), target); \ - } \ - break - - HANDLE_TYPE( INT32, Int32, int32); - HANDLE_TYPE( INT64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, int32); - HANDLE_TYPE( SINT64, SInt64, int64); - HANDLE_TYPE( FIXED32, Fixed32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); - HANDLE_TYPE( FLOAT, Float, float); - HANDLE_TYPE( DOUBLE, Double, double); - HANDLE_TYPE( BOOL, Bool, bool); - HANDLE_TYPE( STRING, String, string); - HANDLE_TYPE( BYTES, Bytes, string); - HANDLE_TYPE( ENUM, Enum, enum); - HANDLE_TYPE( GROUP, Group, message); - HANDLE_TYPE( MESSAGE, Message, message); -#undef HANDLE_TYPE - } - } - } else if (!is_cleared) { - switch (real_type(type)) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - target = WireFormatLite::Write##CAMELCASE##ToArray( \ - number, VALUE, target); \ - break - - HANDLE_TYPE( INT32, Int32, int32_value); - HANDLE_TYPE( INT64, Int64, int64_value); - HANDLE_TYPE( UINT32, UInt32, uint32_value); - HANDLE_TYPE( UINT64, UInt64, uint64_value); - HANDLE_TYPE( SINT32, SInt32, int32_value); - HANDLE_TYPE( SINT64, SInt64, int64_value); - HANDLE_TYPE( FIXED32, Fixed32, uint32_value); - HANDLE_TYPE( FIXED64, Fixed64, uint64_value); - HANDLE_TYPE(SFIXED32, SFixed32, int32_value); - HANDLE_TYPE(SFIXED64, SFixed64, int64_value); - HANDLE_TYPE( FLOAT, Float, float_value); - HANDLE_TYPE( DOUBLE, Double, double_value); - HANDLE_TYPE( BOOL, Bool, bool_value); - HANDLE_TYPE( STRING, String, *string_value); - HANDLE_TYPE( BYTES, Bytes, *string_value); - HANDLE_TYPE( ENUM, Enum, enum_value); - HANDLE_TYPE( GROUP, Group, *message_value); - HANDLE_TYPE( MESSAGE, Message, *message_value); -#undef HANDLE_TYPE - } - } - return target; -} - -uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( - int number, - uint8* target) const { - if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { - // Not a valid MessageSet extension, but serialize it the normal way. - GOOGLE_LOG(WARNING) << "Invalid message set extension."; - return SerializeFieldWithCachedSizesToArray(number, target); - } - - if (is_cleared) return target; - - // Start group. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetItemStartTag, target); - // Write type ID. - target = WireFormatLite::WriteUInt32ToArray( - WireFormatLite::kMessageSetTypeIdNumber, number, target); - // Write message. - target = WireFormatLite::WriteMessageToArray( - WireFormatLite::kMessageSetMessageNumber, *message_value, target); - // End group. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetItemEndTag, target); - return target; -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/extension_set_unittest.cc b/Resources/NetHook/google/protobuf/extension_set_unittest.cc deleted file mode 100644 index 000f846c..00000000 --- a/Resources/NetHook/google/protobuf/extension_set_unittest.cc +++ /dev/null @@ -1,642 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc -// except that it uses extensions rather than regular fields. - -TEST(ExtensionSetTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllExtensions message; - - TestUtil::ExpectExtensionsClear(message); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); -} - -TEST(ExtensionSetTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - TestUtil::ExpectAllExtensionsSet(message); - - TestUtil::ModifyRepeatedExtensions(&message); - TestUtil::ExpectRepeatedExtensionsModified(message); -} - -TEST(ExtensionSetTest, Clear) { - // Set every field to a unique value, clear the message, then check that - // it is cleared. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - message.Clear(); - TestUtil::ExpectExtensionsClear(message); - - // Unlike with the defaults test, we do NOT expect that requesting embedded - // messages will return a pointer to the default instance. Instead, they - // should return the objects that were created when mutable_blah() was - // called. - EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); - - // Make sure setting stuff again after clearing works. (This takes slightly - // different code paths since the objects are reused.) - TestUtil::SetAllExtensions(&message); - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ExtensionSetTest, ClearOneField) { - // Set every field to a unique value, then clear one value and insure that - // only that one value is cleared. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - int64 original_value = - message.GetExtension(unittest::optional_int64_extension); - - // Clear the field and make sure it shows up as cleared. - message.ClearExtension(unittest::optional_int64_extension); - EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension)); - EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension)); - - // Other adjacent fields should not be cleared. - EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension)); - - // Make sure if we set it again, then all fields are set. - message.SetExtension(unittest::optional_int64_extension, original_value); - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ExtensionSetTest, CopyFrom) { - unittest::TestAllExtensions message1, message2; - string data; - - TestUtil::SetAllExtensions(&message1); - message2.CopyFrom(message1); - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(ExtensionSetTest, CopyFromUpcasted) { - unittest::TestAllExtensions message1, message2; - string data; - const Message& upcasted_message = message1; - - TestUtil::SetAllExtensions(&message1); - message2.CopyFrom(upcasted_message); - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(ExtensionSetTest, SwapWithEmpty) { - unittest::TestAllExtensions message1, message2; - TestUtil::SetAllExtensions(&message1); - - TestUtil::ExpectAllExtensionsSet(message1); - TestUtil::ExpectExtensionsClear(message2); - message1.Swap(&message2); - TestUtil::ExpectAllExtensionsSet(message2); - TestUtil::ExpectExtensionsClear(message1); -} - -TEST(ExtensionSetTest, SwapWithSelf) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - TestUtil::ExpectAllExtensionsSet(message); - message.Swap(&message); - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ExtensionSetTest, SerializationToArray) { - // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire - // compatibility of extensions. - // - // This checks serialization to a flat array by explicitly reserving space in - // the string and calling the generated message's - // SerializeWithCachedSizesToArray. - unittest::TestAllExtensions source; - unittest::TestAllTypes destination; - TestUtil::SetAllExtensions(&source); - int size = source.ByteSize(); - string data; - data.resize(size); - uint8* target = reinterpret_cast(string_as_array(&data)); - uint8* end = source.SerializeWithCachedSizesToArray(target); - EXPECT_EQ(size, end - target); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(destination); -} - -TEST(ExtensionSetTest, SerializationToStream) { - // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire - // compatibility of extensions. - // - // This checks serialization to an output stream by creating an array output - // stream that can only buffer 1 byte at a time - this prevents the message - // from ever jumping to the fast path, ensuring that serialization happens via - // the CodedOutputStream. - unittest::TestAllExtensions source; - unittest::TestAllTypes destination; - TestUtil::SetAllExtensions(&source); - int size = source.ByteSize(); - string data; - data.resize(size); - { - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - source.SerializeWithCachedSizes(&output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(destination); -} - -TEST(ExtensionSetTest, PackedSerializationToArray) { - // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure - // wire compatibility of extensions. - // - // This checks serialization to a flat array by explicitly reserving space in - // the string and calling the generated message's - // SerializeWithCachedSizesToArray. - unittest::TestPackedExtensions source; - unittest::TestPackedTypes destination; - TestUtil::SetPackedExtensions(&source); - int size = source.ByteSize(); - string data; - data.resize(size); - uint8* target = reinterpret_cast(string_as_array(&data)); - uint8* end = source.SerializeWithCachedSizesToArray(target); - EXPECT_EQ(size, end - target); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectPackedFieldsSet(destination); -} - -TEST(ExtensionSetTest, PackedSerializationToStream) { - // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure - // wire compatibility of extensions. - // - // This checks serialization to an output stream by creating an array output - // stream that can only buffer 1 byte at a time - this prevents the message - // from ever jumping to the fast path, ensuring that serialization happens via - // the CodedOutputStream. - unittest::TestPackedExtensions source; - unittest::TestPackedTypes destination; - TestUtil::SetPackedExtensions(&source); - int size = source.ByteSize(); - string data; - data.resize(size); - { - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - source.SerializeWithCachedSizes(&output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectPackedFieldsSet(destination); -} - -TEST(ExtensionSetTest, Parsing) { - // Serialize as TestAllTypes and parse as TestAllExtensions. - unittest::TestAllTypes source; - unittest::TestAllExtensions destination; - string data; - - TestUtil::SetAllFields(&source); - source.SerializeToString(&data); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectAllExtensionsSet(destination); -} - -TEST(ExtensionSetTest, PackedParsing) { - // Serialize as TestPackedTypes and parse as TestPackedExtensions. - unittest::TestPackedTypes source; - unittest::TestPackedExtensions destination; - string data; - - TestUtil::SetPackedFields(&source); - source.SerializeToString(&data); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectPackedExtensionsSet(destination); -} - -TEST(ExtensionSetTest, IsInitialized) { - // Test that IsInitialized() returns false if required fields in nested - // extensions are missing. - unittest::TestAllExtensions message; - - EXPECT_TRUE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::single); - EXPECT_FALSE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::single)->set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::single)->set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::single)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); - - message.AddExtension(unittest::TestRequired::multi); - EXPECT_FALSE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(ExtensionSetTest, MutableString) { - // Test the mutable string accessors. - unittest::TestAllExtensions message; - - message.MutableExtension(unittest::optional_string_extension)->assign("foo"); - EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension)); - EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension)); - - message.AddExtension(unittest::repeated_string_extension)->assign("bar"); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension)); - EXPECT_EQ("bar", - message.GetExtension(unittest::repeated_string_extension, 0)); -} - -TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { - // Scalar primitive extensions should increase the extension set size by a - // minimum of the size of the primitive type. -#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \ - do { \ - unittest::TestAllExtensions message; \ - const int base_size = message.SpaceUsed(); \ - message.SetExtension(unittest::optional_##type##_extension, value); \ - int min_expected_size = base_size + \ - sizeof(message.GetExtension(unittest::optional_##type##_extension)); \ - EXPECT_LE(min_expected_size, message.SpaceUsed()); \ - } while (0) - - TEST_SCALAR_EXTENSIONS_SPACE_USED(int32 , 101); - TEST_SCALAR_EXTENSIONS_SPACE_USED(int64 , 102); - TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32 , 103); - TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64 , 104); - TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32 , 105); - TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64 , 106); - TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32 , 107); - TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64 , 108); - TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109); - TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110); - TEST_SCALAR_EXTENSIONS_SPACE_USED(float , 111); - TEST_SCALAR_EXTENSIONS_SPACE_USED(double , 112); - TEST_SCALAR_EXTENSIONS_SPACE_USED(bool , true); -#undef TEST_SCALAR_EXTENSIONS_SPACE_USED - { - unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - message.SetExtension(unittest::optional_nested_enum_extension, - unittest::TestAllTypes::FOO); - int min_expected_size = base_size + - sizeof(message.GetExtension(unittest::optional_nested_enum_extension)); - EXPECT_LE(min_expected_size, message.SpaceUsed()); - } - { - // Strings may cause extra allocations depending on their length; ensure - // that gets included as well. - unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - const string s("this is a fairly large string that will cause some " - "allocation in order to store it in the extension"); - message.SetExtension(unittest::optional_string_extension, s); - int min_expected_size = base_size + s.length(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); - } - { - // Messages also have additional allocation that need to be counted. - unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - unittest::ForeignMessage foreign; - foreign.set_c(42); - message.MutableExtension(unittest::optional_foreign_message_extension)-> - CopyFrom(foreign); - int min_expected_size = base_size + foreign.SpaceUsed(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); - } - - // Repeated primitive extensions will increase space used by at least a - // RepeatedField, and will cause additional allocations when the array - // gets too big for the initial space. - // This macro: - // - Adds a value to the repeated extension, then clears it, establishing - // the base size. - // - Adds a small number of values, testing that it doesn't increase the - // SpaceUsed() - // - Adds a large number of values (requiring allocation in the repeated - // field), and ensures that that allocation is included in SpaceUsed() -#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \ - do { \ - unittest::TestAllExtensions message; \ - const int base_size = message.SpaceUsed(); \ - int min_expected_size = sizeof(RepeatedField) + base_size; \ - message.AddExtension(unittest::repeated_##type##_extension, value); \ - message.ClearExtension(unittest::repeated_##type##_extension); \ - const int empty_repeated_field_size = message.SpaceUsed(); \ - EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \ - message.AddExtension(unittest::repeated_##type##_extension, value); \ - message.AddExtension(unittest::repeated_##type##_extension, value); \ - EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \ - message.ClearExtension(unittest::repeated_##type##_extension); \ - for (int i = 0; i < 16; ++i) { \ - message.AddExtension(unittest::repeated_##type##_extension, value); \ - } \ - int expected_size = sizeof(cpptype) * 16 + empty_repeated_field_size; \ - EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \ - } while (0) - - TEST_REPEATED_EXTENSIONS_SPACE_USED(int32 , int32 , 101); - TEST_REPEATED_EXTENSIONS_SPACE_USED(int64 , int64 , 102); - TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32 , uint32, 103); - TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64 , uint64, 104); - TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32 , int32 , 105); - TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64 , int64 , 106); - TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32 , uint32, 107); - TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64 , uint64, 108); - TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32 , 109); - TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64 , 110); - TEST_REPEATED_EXTENSIONS_SPACE_USED(float , float , 111); - TEST_REPEATED_EXTENSIONS_SPACE_USED(double , double, 112); - TEST_REPEATED_EXTENSIONS_SPACE_USED(bool , bool , true); - TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int, - unittest::TestAllTypes::FOO); -#undef TEST_REPEATED_EXTENSIONS_SPACE_USED - // Repeated strings - { - unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - int min_expected_size = sizeof(RepeatedPtrField) + base_size; - const string value(256, 'x'); - // Once items are allocated, they may stick around even when cleared so - // without the hardcore memory management accessors there isn't a notion of - // the empty repeated field memory usage as there is with primitive types. - for (int i = 0; i < 16; ++i) { - message.AddExtension(unittest::repeated_string_extension, value); - } - min_expected_size += (sizeof(value) + value.size()) * 16; - EXPECT_LE(min_expected_size, message.SpaceUsed()); - } - // Repeated messages - { - unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - int min_expected_size = sizeof(RepeatedPtrField) + - base_size; - unittest::ForeignMessage prototype; - prototype.set_c(2); - for (int i = 0; i < 16; ++i) { - message.AddExtension(unittest::repeated_foreign_message_extension)-> - CopyFrom(prototype); - } - min_expected_size += 16 * prototype.SpaceUsed(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); - } -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(ExtensionSetTest, InvalidEnumDeath) { - unittest::TestAllExtensions message; - EXPECT_DEBUG_DEATH( - message.SetExtension(unittest::optional_foreign_enum_extension, - static_cast(53)), - "IsValid"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(ExtensionSetTest, DynamicExtensions) { - // Test adding a dynamic extension to a compiled-in message object. - - FileDescriptorProto dynamic_proto; - dynamic_proto.set_name("dynamic_extensions_test.proto"); - dynamic_proto.add_dependency( - unittest::TestAllExtensions::descriptor()->file()->name()); - dynamic_proto.set_package("dynamic_extensions"); - - // Copy the fields and nested types from TestDynamicExtensions into our new - // proto, converting the fields into extensions. - const Descriptor* template_descriptor = - unittest::TestDynamicExtensions::descriptor(); - DescriptorProto template_descriptor_proto; - template_descriptor->CopyTo(&template_descriptor_proto); - dynamic_proto.mutable_message_type()->MergeFrom( - template_descriptor_proto.nested_type()); - dynamic_proto.mutable_enum_type()->MergeFrom( - template_descriptor_proto.enum_type()); - dynamic_proto.mutable_extension()->MergeFrom( - template_descriptor_proto.field()); - - // For each extension that we added... - for (int i = 0; i < dynamic_proto.extension_size(); i++) { - // Set its extendee to TestAllExtensions. - FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i); - extension->set_extendee( - unittest::TestAllExtensions::descriptor()->full_name()); - - // If the field refers to one of the types nested in TestDynamicExtensions, - // make it refer to the type in our dynamic proto instead. - string prefix = "." + template_descriptor->full_name() + "."; - if (extension->has_type_name()) { - string* type_name = extension->mutable_type_name(); - if (HasPrefixString(*type_name, prefix)) { - type_name->replace(0, prefix.size(), ".dynamic_extensions."); - } - } - } - - // Now build the file, using the generated pool as an underlay. - DescriptorPool dynamic_pool(DescriptorPool::generated_pool()); - const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto); - ASSERT_TRUE(file != NULL); - DynamicMessageFactory dynamic_factory(&dynamic_pool); - dynamic_factory.SetDelegateToGeneratedFactory(true); - - // Construct a message that we can parse with the extensions we defined. - // Since the extensions were based off of the fields of TestDynamicExtensions, - // we can use that message to create this test message. - string data; - { - unittest::TestDynamicExtensions message; - message.set_scalar_extension(123); - message.set_enum_extension(unittest::FOREIGN_BAR); - message.set_dynamic_enum_extension( - unittest::TestDynamicExtensions::DYNAMIC_BAZ); - message.mutable_message_extension()->set_c(456); - message.mutable_dynamic_message_extension()->set_dynamic_field(789); - message.add_repeated_extension("foo"); - message.add_repeated_extension("bar"); - message.add_packed_extension(12); - message.add_packed_extension(-34); - message.add_packed_extension(56); - message.add_packed_extension(-78); - - // Also add some unknown fields. - - // An unknown enum value (for a known field). - message.mutable_unknown_fields()->AddVarint( - unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber, - 12345); - // A regular unknown field. - message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown"); - - message.SerializeToString(&data); - } - - // Now we can parse this using our dynamic extension definitions... - unittest::TestAllExtensions message; - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); - ASSERT_TRUE(message.ParseFromCodedStream(&input)); - ASSERT_TRUE(input.ConsumedEntireMessage()); - } - - // Can we print it? - EXPECT_EQ( - "[dynamic_extensions.scalar_extension]: 123\n" - "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n" - "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n" - "[dynamic_extensions.message_extension] {\n" - " c: 456\n" - "}\n" - "[dynamic_extensions.dynamic_message_extension] {\n" - " dynamic_field: 789\n" - "}\n" - "[dynamic_extensions.repeated_extension]: \"foo\"\n" - "[dynamic_extensions.repeated_extension]: \"bar\"\n" - "[dynamic_extensions.packed_extension]: 12\n" - "[dynamic_extensions.packed_extension]: -34\n" - "[dynamic_extensions.packed_extension]: 56\n" - "[dynamic_extensions.packed_extension]: -78\n" - "2002: 12345\n" - "54321: \"unknown\"\n", - message.DebugString()); - - // Can we serialize it? - // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the - // terminal on failure.) - EXPECT_TRUE(message.SerializeAsString() == data); - - // What if we parse using the reflection-based parser? - { - unittest::TestAllExtensions message2; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2)); - ASSERT_TRUE(input.ConsumedEntireMessage()); - EXPECT_EQ(message.DebugString(), message2.DebugString()); - } - - // Are the embedded generated types actually using the generated objects? - { - const FieldDescriptor* message_extension = - file->FindExtensionByName("message_extension"); - ASSERT_TRUE(message_extension != NULL); - const Message& sub_message = - message.GetReflection()->GetMessage(message, message_extension); - const unittest::ForeignMessage* typed_sub_message = - dynamic_cast(&sub_message); - ASSERT_TRUE(typed_sub_message != NULL); - EXPECT_EQ(456, typed_sub_message->c()); - } - - // What does GetMessage() return for the embedded dynamic type if it isn't - // present? - { - const FieldDescriptor* dynamic_message_extension = - file->FindExtensionByName("dynamic_message_extension"); - ASSERT_TRUE(dynamic_message_extension != NULL); - const Message& parent = unittest::TestAllExtensions::default_instance(); - const Message& sub_message = - parent.GetReflection()->GetMessage(parent, dynamic_message_extension, - &dynamic_factory); - const Message* prototype = - dynamic_factory.GetPrototype(dynamic_message_extension->message_type()); - EXPECT_EQ(prototype, &sub_message); - } -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/generated_message_reflection.cc b/Resources/NetHook/google/protobuf/generated_message_reflection.cc deleted file mode 100644 index 0f065ff2..00000000 --- a/Resources/NetHook/google/protobuf/generated_message_reflection.cc +++ /dev/null @@ -1,1231 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -namespace { const string kEmptyString; } - -int StringSpaceUsedExcludingSelf(const string& str) { - const void* start = &str; - const void* end = &str + 1; - - if (start <= str.data() && str.data() <= end) { - // The string's data is stored inside the string object itself. - return 0; - } else { - return str.capacity(); - } -} - -bool ParseNamedEnum(const EnumDescriptor* descriptor, - const string& name, - int* value) { - const EnumValueDescriptor* d = descriptor->FindValueByName(name); - if (d == NULL) return false; - *value = d->number(); - return true; -} - -const string& NameOfEnum(const EnumDescriptor* descriptor, int value) { - static string kEmptyString; - const EnumValueDescriptor* d = descriptor->FindValueByNumber(value); - return (d == NULL ? kEmptyString : d->name()); -} - -// =================================================================== -// Helpers for reporting usage errors (e.g. trying to use GetInt32() on -// a string field). - -namespace { - -void ReportReflectionUsageError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, const char* description) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : " << description; -} - -const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = { - "INVALID_CPPTYPE", - "CPPTYPE_INT32", - "CPPTYPE_INT64", - "CPPTYPE_UINT32", - "CPPTYPE_UINT64", - "CPPTYPE_DOUBLE", - "CPPTYPE_FLOAT", - "CPPTYPE_BOOL", - "CPPTYPE_ENUM", - "CPPTYPE_STRING", - "CPPTYPE_MESSAGE" -}; - -static void ReportReflectionUsageTypeError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, - FieldDescriptor::CppType expected_type) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : Field is not the right type for this message:\n" - " Expected : " << cpptype_names_[expected_type] << "\n" - " Field type: " << cpptype_names_[field->cpp_type()]; -} - -static void ReportReflectionUsageEnumTypeError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, const EnumValueDescriptor* value) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : Enum value did not match field type:\n" - " Expected : " << field->enum_type()->full_name() << "\n" - " Actual : " << value->full_name(); -} - -#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ - if (!(CONDITION)) \ - ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) -#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \ - USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION) -#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \ - USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION) - -#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \ - if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \ - ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \ - FieldDescriptor::CPPTYPE_##CPPTYPE) - -#define USAGE_CHECK_ENUM_VALUE(METHOD) \ - if (value->type() != field->enum_type()) \ - ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value) - -#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \ - USAGE_CHECK_EQ(field->containing_type(), descriptor_, \ - METHOD, "Field does not match message type."); -#define USAGE_CHECK_SINGULAR(METHOD) \ - USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ - "Field is repeated; the method requires a singular field.") -#define USAGE_CHECK_REPEATED(METHOD) \ - USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ - "Field is singular; the method requires a repeated field.") - -#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ - USAGE_CHECK_MESSAGE_TYPE(METHOD); \ - USAGE_CHECK_##LABEL(METHOD); \ - USAGE_CHECK_TYPE(METHOD, CPPTYPE) - -} // namespace - -// =================================================================== - -GeneratedMessageReflection::GeneratedMessageReflection( - const Descriptor* descriptor, - const Message* default_instance, - const int offsets[], - int has_bits_offset, - int unknown_fields_offset, - int extensions_offset, - const DescriptorPool* descriptor_pool, - MessageFactory* factory, - int object_size) - : descriptor_ (descriptor), - default_instance_ (default_instance), - offsets_ (offsets), - has_bits_offset_ (has_bits_offset), - unknown_fields_offset_(unknown_fields_offset), - extensions_offset_(extensions_offset), - object_size_ (object_size), - descriptor_pool_ ((descriptor_pool == NULL) ? - DescriptorPool::generated_pool() : - descriptor_pool), - message_factory_ (factory) { -} - -GeneratedMessageReflection::~GeneratedMessageReflection() {} - -const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( - const Message& message) const { - const void* ptr = reinterpret_cast(&message) + - unknown_fields_offset_; - return *reinterpret_cast(ptr); -} -UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( - Message* message) const { - void* ptr = reinterpret_cast(message) + unknown_fields_offset_; - return reinterpret_cast(ptr); -} - -int GeneratedMessageReflection::SpaceUsed(const Message& message) const { - // object_size_ already includes the in-memory representation of each field - // in the message, so we only need to account for additional memory used by - // the fields. - int total_size = object_size_; - - total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); - - if (extensions_offset_ != -1) { - total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_repeated()) { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - total_size += GetRaw >(message, field) \ - .SpaceUsedExcludingSelf(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - total_size += GetRaw >(message, field) - .SpaceUsedExcludingSelf(); - break; - } - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - // We don't know which subclass of RepeatedPtrFieldBase the type is, - // so we use RepeatedPtrFieldBase directly. - total_size += - GetRaw(message, field) - .SpaceUsedExcludingSelf >(); - break; - } - } else { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32 : - case FieldDescriptor::CPPTYPE_INT64 : - case FieldDescriptor::CPPTYPE_UINT32: - case FieldDescriptor::CPPTYPE_UINT64: - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT : - case FieldDescriptor::CPPTYPE_BOOL : - case FieldDescriptor::CPPTYPE_ENUM : - // Field is inline, so we've already counted it. - break; - - case FieldDescriptor::CPPTYPE_STRING: { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: { - const string* ptr = GetField(message, field); - - // Initially, the string points to the default value stored in - // the prototype. Only count the string if it has been changed - // from the default value. - const string* default_ptr = DefaultRaw(field); - - if (ptr != default_ptr) { - // string fields are represented by just a pointer, so also - // include sizeof(string) as well. - total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); - } - break; - } - } - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: - if (&message == default_instance_) { - // For singular fields, the prototype just stores a pointer to the - // external type's prototype, so there is no extra memory usage. - } else { - const Message* sub_message = GetRaw(message, field); - if (sub_message != NULL) { - total_size += sub_message->SpaceUsed(); - } - } - break; - } - } - } - - return total_size; -} - -void GeneratedMessageReflection::Swap( - Message* message1, - Message* message2) const { - if (message1 == message2) return; - - // TODO(kenton): Other Reflection methods should probably check this too. - GOOGLE_CHECK_EQ(message1->GetReflection(), this) - << "First argument to Swap() (of type \"" - << message1->GetDescriptor()->full_name() - << "\") is not compatible with this reflection object (which is for type \"" - << descriptor_->full_name() - << "\"). Note that the exact same class is required; not just the same " - "descriptor."; - GOOGLE_CHECK_EQ(message2->GetReflection(), this) - << "Second argument to Swap() (of type \"" - << message1->GetDescriptor()->full_name() - << "\") is not compatible with this reflection object (which is for type \"" - << descriptor_->full_name() - << "\"). Note that the exact same class is required; not just the same " - "descriptor."; - - uint32* has_bits1 = MutableHasBits(message1); - uint32* has_bits2 = MutableHasBits(message2); - int has_bits_size = (descriptor_->field_count() + 31) / 32; - - for (int i = 0; i < has_bits_size; i++) { - std::swap(has_bits1[i], has_bits2[i]); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->is_repeated()) { - switch (field->cpp_type()) { -#define SWAP_ARRAYS(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - MutableRaw >(message1, field)->Swap( \ - MutableRaw >(message2, field)); \ - break; - - SWAP_ARRAYS(INT32 , int32 ); - SWAP_ARRAYS(INT64 , int64 ); - SWAP_ARRAYS(UINT32, uint32); - SWAP_ARRAYS(UINT64, uint64); - SWAP_ARRAYS(FLOAT , float ); - SWAP_ARRAYS(DOUBLE, double); - SWAP_ARRAYS(BOOL , bool ); - SWAP_ARRAYS(ENUM , int ); -#undef SWAP_ARRAYS - - case FieldDescriptor::CPPTYPE_STRING: - case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message1, field)->Swap( - MutableRaw(message2, field)); - break; - - default: - GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); - } - } else { - switch (field->cpp_type()) { -#define SWAP_VALUES(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - std::swap(*MutableRaw(message1, field), \ - *MutableRaw(message2, field)); \ - break; - - SWAP_VALUES(INT32 , int32 ); - SWAP_VALUES(INT64 , int64 ); - SWAP_VALUES(UINT32, uint32); - SWAP_VALUES(UINT64, uint64); - SWAP_VALUES(FLOAT , float ); - SWAP_VALUES(DOUBLE, double); - SWAP_VALUES(BOOL , bool ); - SWAP_VALUES(ENUM , int ); - SWAP_VALUES(MESSAGE, Message*); -#undef SWAP_VALUES - - case FieldDescriptor::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - std::swap(*MutableRaw(message1, field), - *MutableRaw(message2, field)); - break; - } - break; - - default: - GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); - } - } - } - - if (extensions_offset_ != -1) { - MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2)); - } - - MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2)); -} - -// ------------------------------------------------------------------- - -bool GeneratedMessageReflection::HasField(const Message& message, - const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(HasField); - USAGE_CHECK_SINGULAR(HasField); - - if (field->is_extension()) { - return GetExtensionSet(message).Has(field->number()); - } else { - return HasBit(message, field); - } -} - -int GeneratedMessageReflection::FieldSize(const Message& message, - const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(FieldSize); - USAGE_CHECK_REPEATED(FieldSize); - - if (field->is_extension()) { - return GetExtensionSet(message).ExtensionSize(field->number()); - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - return GetRaw >(message, field).size() - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: - case FieldDescriptor::CPPTYPE_MESSAGE: - return GetRaw(message, field).size(); - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; - } -} - -void GeneratedMessageReflection::ClearField( - Message* message, const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(ClearField); - - if (field->is_extension()) { - MutableExtensionSet(message)->ClearExtension(field->number()); - } else if (!field->is_repeated()) { - if (HasBit(*message, field)) { - ClearBit(message, field); - - // We need to set the field back to its default value. - switch (field->cpp_type()) { -#define CLEAR_TYPE(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - *MutableRaw(message, field) = \ - field->default_value_##TYPE(); \ - break; - - CLEAR_TYPE(INT32 , int32 ); - CLEAR_TYPE(INT64 , int64 ); - CLEAR_TYPE(UINT32, uint32); - CLEAR_TYPE(UINT64, uint64); - CLEAR_TYPE(FLOAT , float ); - CLEAR_TYPE(DOUBLE, double); - CLEAR_TYPE(BOOL , bool ); -#undef CLEAR_TYPE - - case FieldDescriptor::CPPTYPE_ENUM: - *MutableRaw(message, field) = - field->default_value_enum()->number(); - break; - - case FieldDescriptor::CPPTYPE_STRING: { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - const string* default_ptr = DefaultRaw(field); - string** value = MutableRaw(message, field); - if (*value != default_ptr) { - if (field->has_default_value()) { - (*value)->assign(field->default_value_string()); - } else { - (*value)->clear(); - } - } - break; - } - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: - (*MutableRaw(message, field))->Clear(); - break; - } - } - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - MutableRaw >(message, field)->Clear(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - MutableRaw >(message, field)->Clear(); - break; - } - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: { - // We don't know which subclass of RepeatedPtrFieldBase the type is, - // so we use RepeatedPtrFieldBase directly. - MutableRaw(message, field) - ->Clear >(); - break; - } - } - } -} - -void GeneratedMessageReflection::RemoveLast( - Message* message, - const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(RemoveLast); - USAGE_CHECK_REPEATED(RemoveLast); - - if (field->is_extension()) { - MutableExtensionSet(message)->RemoveLast(field->number()); - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - MutableRaw >(message, field)->RemoveLast(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - MutableRaw >(message, field)->RemoveLast(); - break; - } - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message, field) - ->RemoveLast >(); - break; - } - } -} - -void GeneratedMessageReflection::SwapElements( - Message* message, - const FieldDescriptor* field, - int index1, - int index2) const { - USAGE_CHECK_MESSAGE_TYPE(Swap); - USAGE_CHECK_REPEATED(Swap); - - if (field->is_extension()) { - MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE : \ - MutableRaw >(message, field) \ - ->SwapElements(index1, index2); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, int); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_STRING: - case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message, field) - ->SwapElements(index1, index2); - break; - } - } -} - -namespace { -// Comparison functor for sorting FieldDescriptors by field number. -struct FieldNumberSorter { - bool operator()(const FieldDescriptor* left, - const FieldDescriptor* right) const { - return left->number() < right->number(); - } -}; -} // namespace - -void GeneratedMessageReflection::ListFields( - const Message& message, - vector* output) const { - output->clear(); - - // Optimization: The default instance never has any fields set. - if (&message == default_instance_) return; - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->is_repeated()) { - if (FieldSize(message, field) > 0) { - output->push_back(field); - } - } else { - if (HasBit(message, field)) { - output->push_back(field); - } - } - } - - if (extensions_offset_ != -1) { - GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, - output); - } - - // ListFields() must sort output by field number. - sort(output->begin(), output->end(), FieldNumberSorter()); -} - -// ------------------------------------------------------------------- - -#undef DEFINE_PRIMITIVE_ACCESSORS -#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \ - PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \ - const Message& message, const FieldDescriptor* field) const { \ - USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \ - if (field->is_extension()) { \ - return GetExtensionSet(message).Get##TYPENAME( \ - field->number(), field->default_value_##PASSTYPE()); \ - } else { \ - return GetField(message, field); \ - } \ - } \ - \ - void GeneratedMessageReflection::Set##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - PASSTYPE value) const { \ - USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ - if (field->is_extension()) { \ - return MutableExtensionSet(message)->Set##TYPENAME( \ - field->number(), field->type(), value, field); \ - } else { \ - SetField(message, field, value); \ - } \ - } \ - \ - PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \ - const Message& message, \ - const FieldDescriptor* field, int index) const { \ - USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - return GetExtensionSet(message).GetRepeated##TYPENAME( \ - field->number(), index); \ - } else { \ - return GetRepeatedField(message, field, index); \ - } \ - } \ - \ - void GeneratedMessageReflection::SetRepeated##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - int index, PASSTYPE value) const { \ - USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - MutableExtensionSet(message)->SetRepeated##TYPENAME( \ - field->number(), index, value); \ - } else { \ - SetRepeatedField(message, field, index, value); \ - } \ - } \ - \ - void GeneratedMessageReflection::Add##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - PASSTYPE value) const { \ - USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - MutableExtensionSet(message)->Add##TYPENAME( \ - field->number(), field->type(), field->options().packed(), value, \ - field); \ - } else { \ - AddField(message, field, value); \ - } \ - } - -DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 ) -DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 ) -DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32) -DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64) -DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT ) -DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) -DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL ) -#undef DEFINE_PRIMITIVE_ACCESSORS - -// ------------------------------------------------------------------- - -string GeneratedMessageReflection::GetString( - const Message& message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(GetString, SINGULAR, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetString(field->number(), - field->default_value_string()); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return *GetField(message, field); - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return kEmptyString; // Make compiler happy. - } -} - -const string& GeneratedMessageReflection::GetStringReference( - const Message& message, - const FieldDescriptor* field, string* scratch) const { - USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetString(field->number(), - field->default_value_string()); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return *GetField(message, field); - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return kEmptyString; // Make compiler happy. - } -} - - -void GeneratedMessageReflection::SetString( - Message* message, const FieldDescriptor* field, - const string& value) const { - USAGE_CHECK_ALL(SetString, SINGULAR, STRING); - if (field->is_extension()) { - return MutableExtensionSet(message)->SetString(field->number(), - field->type(), value, field); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: { - string** ptr = MutableField(message, field); - if (*ptr == DefaultRaw(field)) { - *ptr = new string(value); - } else { - (*ptr)->assign(value); - } - break; - } - } - } -} - - -string GeneratedMessageReflection::GetRepeatedString( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedString(field->number(), index); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return GetRepeatedPtrField(message, field, index); - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return kEmptyString; // Make compiler happy. - } -} - -const string& GeneratedMessageReflection::GetRepeatedStringReference( - const Message& message, const FieldDescriptor* field, - int index, string* scratch) const { - USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedString(field->number(), index); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - return GetRepeatedPtrField(message, field, index); - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return kEmptyString; // Make compiler happy. - } -} - - -void GeneratedMessageReflection::SetRepeatedString( - Message* message, const FieldDescriptor* field, - int index, const string& value) const { - USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING); - if (field->is_extension()) { - MutableExtensionSet(message)->SetRepeatedString( - field->number(), index, value); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - *MutableRepeatedField(message, field, index) = value; - break; - } - } -} - - -void GeneratedMessageReflection::AddString( - Message* message, const FieldDescriptor* field, - const string& value) const { - USAGE_CHECK_ALL(AddString, REPEATED, STRING); - if (field->is_extension()) { - MutableExtensionSet(message)->AddString(field->number(), - field->type(), value, field); - } else { - switch (field->options().ctype()) { - default: // TODO(kenton): Support other string reps. - case FieldOptions::STRING: - *AddField(message, field) = value; - break; - } - } -} - - -// ------------------------------------------------------------------- - -const EnumValueDescriptor* GeneratedMessageReflection::GetEnum( - const Message& message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM); - - int value; - if (field->is_extension()) { - value = GetExtensionSet(message).GetEnum( - field->number(), field->default_value_enum()->number()); - } else { - value = GetField(message, field); - } - const EnumValueDescriptor* result = - field->enum_type()->FindValueByNumber(value); - GOOGLE_CHECK(result != NULL); - return result; -} - -void GeneratedMessageReflection::SetEnum( - Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM); - USAGE_CHECK_ENUM_VALUE(SetEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->SetEnum(field->number(), field->type(), - value->number(), field); - } else { - SetField(message, field, value->number()); - } -} - -const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM); - - int value; - if (field->is_extension()) { - value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index); - } else { - value = GetRepeatedField(message, field, index); - } - const EnumValueDescriptor* result = - field->enum_type()->FindValueByNumber(value); - GOOGLE_CHECK(result != NULL); - return result; -} - -void GeneratedMessageReflection::SetRepeatedEnum( - Message* message, - const FieldDescriptor* field, int index, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); - USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->SetRepeatedEnum( - field->number(), index, value->number()); - } else { - SetRepeatedField(message, field, index, value->number()); - } -} - -void GeneratedMessageReflection::AddEnum( - Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); - USAGE_CHECK_ENUM_VALUE(AddEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->AddEnum(field->number(), field->type(), - field->options().packed(), - value->number(), field); - } else { - AddField(message, field, value->number()); - } -} - -// ------------------------------------------------------------------- - -const Message& GeneratedMessageReflection::GetMessage( - const Message& message, const FieldDescriptor* field, - MessageFactory* factory) const { - USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); - - if (field->is_extension()) { - return static_cast( - GetExtensionSet(message).GetMessage( - field->number(), field->message_type(), - factory == NULL ? message_factory_ : factory)); - } else { - const Message* result = GetRaw(message, field); - if (result == NULL) { - result = DefaultRaw(field); - } - return *result; - } -} - -Message* GeneratedMessageReflection::MutableMessage( - Message* message, const FieldDescriptor* field, - MessageFactory* factory) const { - USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); - - if (field->is_extension()) { - return static_cast( - MutableExtensionSet(message)->MutableMessage(field, - factory == NULL ? message_factory_ : factory)); - } else { - Message** result = MutableField(message, field); - if (*result == NULL) { - const Message* default_message = DefaultRaw(field); - *result = default_message->New(); - } - return *result; - } -} - -const Message& GeneratedMessageReflection::GetRepeatedMessage( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); - - if (field->is_extension()) { - return static_cast( - GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); - } else { - return GetRaw(message, field) - .Get >(index); - } -} - -Message* GeneratedMessageReflection::MutableRepeatedMessage( - Message* message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); - - if (field->is_extension()) { - return static_cast( - MutableExtensionSet(message)->MutableRepeatedMessage( - field->number(), index)); - } else { - return MutableRaw(message, field) - ->Mutable >(index); - } -} - -Message* GeneratedMessageReflection::AddMessage( - Message* message, const FieldDescriptor* field, - MessageFactory* factory) const { - USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); - - if (factory == NULL) factory = message_factory_; - - if (field->is_extension()) { - return static_cast( - MutableExtensionSet(message)->AddMessage(field, factory)); - } else { - // We can't use AddField() because RepeatedPtrFieldBase doesn't - // know how to allocate one. - RepeatedPtrFieldBase* repeated = - MutableRaw(message, field); - Message* result = repeated->AddFromCleared >(); - if (result == NULL) { - // We must allocate a new object. - const Message* prototype; - if (repeated->size() == 0) { - prototype = factory->GetPrototype(field->message_type()); - } else { - prototype = &repeated->Get >(0); - } - result = prototype->New(); - repeated->AddAllocated >(result); - } - return result; - } -} - -// ------------------------------------------------------------------- - -const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( - const string& name) const { - if (extensions_offset_ == -1) return NULL; - - const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); - if (result != NULL && result->containing_type() == descriptor_) { - return result; - } - - if (descriptor_->options().message_set_wire_format()) { - // MessageSet extensions may be identified by type name. - const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); - if (type != NULL) { - // Look for a matching extension in the foreign type's scope. - for (int i = 0; i < type->extension_count(); i++) { - const FieldDescriptor* extension = type->extension(i); - if (extension->containing_type() == descriptor_ && - extension->type() == FieldDescriptor::TYPE_MESSAGE && - extension->is_optional() && - extension->message_type() == type) { - // Found it. - return extension; - } - } - } - } - - return NULL; -} - -const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( - int number) const { - if (extensions_offset_ == -1) return NULL; - return descriptor_pool_->FindExtensionByNumber(descriptor_, number); -} - -// =================================================================== -// Some private helpers. - -// These simple template accessors obtain pointers (or references) to -// the given field. -template -inline const Type& GeneratedMessageReflection::GetRaw( - const Message& message, const FieldDescriptor* field) const { - const void* ptr = reinterpret_cast(&message) + - offsets_[field->index()]; - return *reinterpret_cast(ptr); -} - -template -inline Type* GeneratedMessageReflection::MutableRaw( - Message* message, const FieldDescriptor* field) const { - void* ptr = reinterpret_cast(message) + offsets_[field->index()]; - return reinterpret_cast(ptr); -} - -template -inline const Type& GeneratedMessageReflection::DefaultRaw( - const FieldDescriptor* field) const { - const void* ptr = reinterpret_cast(default_instance_) + - offsets_[field->index()]; - return *reinterpret_cast(ptr); -} - -inline const uint32* GeneratedMessageReflection::GetHasBits( - const Message& message) const { - const void* ptr = reinterpret_cast(&message) + has_bits_offset_; - return reinterpret_cast(ptr); -} -inline uint32* GeneratedMessageReflection::MutableHasBits( - Message* message) const { - void* ptr = reinterpret_cast(message) + has_bits_offset_; - return reinterpret_cast(ptr); -} - -inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( - const Message& message) const { - GOOGLE_DCHECK_NE(extensions_offset_, -1); - const void* ptr = reinterpret_cast(&message) + - extensions_offset_; - return *reinterpret_cast(ptr); -} -inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( - Message* message) const { - GOOGLE_DCHECK_NE(extensions_offset_, -1); - void* ptr = reinterpret_cast(message) + extensions_offset_; - return reinterpret_cast(ptr); -} - -// Simple accessors for manipulating has_bits_. -inline bool GeneratedMessageReflection::HasBit( - const Message& message, const FieldDescriptor* field) const { - return GetHasBits(message)[field->index() / 32] & - (1 << (field->index() % 32)); -} - -inline void GeneratedMessageReflection::SetBit( - Message* message, const FieldDescriptor* field) const { - MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32)); -} - -inline void GeneratedMessageReflection::ClearBit( - Message* message, const FieldDescriptor* field) const { - MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32)); -} - -// Template implementations of basic accessors. Inline because each -// template instance is only called from one location. These are -// used for all types except messages. -template -inline const Type& GeneratedMessageReflection::GetField( - const Message& message, const FieldDescriptor* field) const { - return GetRaw(message, field); -} - -template -inline void GeneratedMessageReflection::SetField( - Message* message, const FieldDescriptor* field, const Type& value) const { - *MutableRaw(message, field) = value; - SetBit(message, field); -} - -template -inline Type* GeneratedMessageReflection::MutableField( - Message* message, const FieldDescriptor* field) const { - SetBit(message, field); - return MutableRaw(message, field); -} - -template -inline const Type& GeneratedMessageReflection::GetRepeatedField( - const Message& message, const FieldDescriptor* field, int index) const { - return GetRaw >(message, field).Get(index); -} - -template -inline const Type& GeneratedMessageReflection::GetRepeatedPtrField( - const Message& message, const FieldDescriptor* field, int index) const { - return GetRaw >(message, field).Get(index); -} - -template -inline void GeneratedMessageReflection::SetRepeatedField( - Message* message, const FieldDescriptor* field, - int index, Type value) const { - MutableRaw >(message, field)->Set(index, value); -} - -template -inline Type* GeneratedMessageReflection::MutableRepeatedField( - Message* message, const FieldDescriptor* field, int index) const { - RepeatedPtrField* repeated = - MutableRaw >(message, field); - return repeated->Mutable(index); -} - -template -inline void GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field, const Type& value) const { - MutableRaw >(message, field)->Add(value); -} - -template -inline Type* GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field) const { - RepeatedPtrField* repeated = - MutableRaw >(message, field); - return repeated->Add(); -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/generated_message_reflection.h b/Resources/NetHook/google/protobuf/generated_message_reflection.h deleted file mode 100644 index b545fa1a..00000000 --- a/Resources/NetHook/google/protobuf/generated_message_reflection.h +++ /dev/null @@ -1,424 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ - -#include -#include -#include -#include - - -namespace google { -namespace protobuf { - class DescriptorPool; - // Generated code needs these to have been forward-declared. Easier to do it - // here than to print them inside every .pb.h file. - class FileDescriptor; - class EnumDescriptor; -} - -namespace protobuf { -namespace internal { - -// Defined in this file. -class GeneratedMessageReflection; - -// Defined in other files. -class ExtensionSet; // extension_set.h - -// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use -// by generated code. This class is just a big hack that reduces code -// size. -// -// A GeneratedMessageReflection is an implementation of Reflection -// which expects all fields to be backed by simple variables located in -// memory. The locations are given using a base pointer and a set of -// offsets. -// -// It is required that the user represents fields of each type in a standard -// way, so that GeneratedMessageReflection can cast the void* pointer to -// the appropriate type. For primitive fields and string fields, each field -// should be represented using the obvious C++ primitive type. Enums and -// Messages are different: -// - Singular Message fields are stored as a pointer to a Message. These -// should start out NULL, except for in the default instance where they -// should start out pointing to other default instances. -// - Enum fields are stored as an int. This int must always contain -// a valid value, such that EnumDescriptor::FindValueByNumber() would -// not return NULL. -// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields -// of whatever type the individual field would be. Strings and -// Messages use RepeatedPtrFields while everything else uses -// RepeatedFields. -class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { - public: - // Constructs a GeneratedMessageReflection. - // Parameters: - // descriptor: The descriptor for the message type being implemented. - // default_instance: The default instance of the message. This is only - // used to obtain pointers to default instances of embedded - // messages, which GetMessage() will return if the particular - // sub-message has not been initialized yet. (Thus, all - // embedded message fields *must* have non-NULL pointers - // in the default instance.) - // offsets: An array of ints giving the byte offsets, relative to - // the start of the message object, of each field. These can - // be computed at compile time using the - // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined - // below. - // has_bits_offset: Offset in the message of an array of uint32s of size - // descriptor->field_count()/32, rounded up. This is a - // bitfield where each bit indicates whether or not the - // corresponding field of the message has been initialized. - // The bit for field index i is obtained by the expression: - // has_bits[i / 32] & (1 << (i % 32)) - // unknown_fields_offset: Offset in the message of the UnknownFieldSet for - // the message. - // extensions_offset: Offset in the message of the ExtensionSet for the - // message, or -1 if the message type has no extension - // ranges. - // pool: DescriptorPool to search for extension definitions. Only - // used by FindKnownExtensionByName() and - // FindKnownExtensionByNumber(). - // factory: MessageFactory to use to construct extension messages. - // object_size: The size of a message object of this type, as measured - // by sizeof(). - GeneratedMessageReflection(const Descriptor* descriptor, - const Message* default_instance, - const int offsets[], - int has_bits_offset, - int unknown_fields_offset, - int extensions_offset, - const DescriptorPool* pool, - MessageFactory* factory, - int object_size); - ~GeneratedMessageReflection(); - - // implements Reflection ------------------------------------------- - - const UnknownFieldSet& GetUnknownFields(const Message& message) const; - UnknownFieldSet* MutableUnknownFields(Message* message) const; - - int SpaceUsed(const Message& message) const; - - bool HasField(const Message& message, const FieldDescriptor* field) const; - int FieldSize(const Message& message, const FieldDescriptor* field) const; - void ClearField(Message* message, const FieldDescriptor* field) const; - void RemoveLast(Message* message, const FieldDescriptor* field) const; - void Swap(Message* message1, Message* message2) const; - void SwapElements(Message* message, const FieldDescriptor* field, - int index1, int index2) const; - void ListFields(const Message& message, - vector* output) const; - - int32 GetInt32 (const Message& message, - const FieldDescriptor* field) const; - int64 GetInt64 (const Message& message, - const FieldDescriptor* field) const; - uint32 GetUInt32(const Message& message, - const FieldDescriptor* field) const; - uint64 GetUInt64(const Message& message, - const FieldDescriptor* field) const; - float GetFloat (const Message& message, - const FieldDescriptor* field) const; - double GetDouble(const Message& message, - const FieldDescriptor* field) const; - bool GetBool (const Message& message, - const FieldDescriptor* field) const; - string GetString(const Message& message, - const FieldDescriptor* field) const; - const string& GetStringReference(const Message& message, - const FieldDescriptor* field, - string* scratch) const; - const EnumValueDescriptor* GetEnum(const Message& message, - const FieldDescriptor* field) const; - const Message& GetMessage(const Message& message, - const FieldDescriptor* field, - MessageFactory* factory = NULL) const; - - void SetInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; - void SetInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; - void SetUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; - void SetUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; - void SetFloat (Message* message, - const FieldDescriptor* field, float value) const; - void SetDouble(Message* message, - const FieldDescriptor* field, double value) const; - void SetBool (Message* message, - const FieldDescriptor* field, bool value) const; - void SetString(Message* message, - const FieldDescriptor* field, - const string& value) const; - void SetEnum (Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const; - Message* MutableMessage(Message* message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; - - int32 GetRepeatedInt32 (const Message& message, - const FieldDescriptor* field, int index) const; - int64 GetRepeatedInt64 (const Message& message, - const FieldDescriptor* field, int index) const; - uint32 GetRepeatedUInt32(const Message& message, - const FieldDescriptor* field, int index) const; - uint64 GetRepeatedUInt64(const Message& message, - const FieldDescriptor* field, int index) const; - float GetRepeatedFloat (const Message& message, - const FieldDescriptor* field, int index) const; - double GetRepeatedDouble(const Message& message, - const FieldDescriptor* field, int index) const; - bool GetRepeatedBool (const Message& message, - const FieldDescriptor* field, int index) const; - string GetRepeatedString(const Message& message, - const FieldDescriptor* field, int index) const; - const string& GetRepeatedStringReference(const Message& message, - const FieldDescriptor* field, - int index, string* scratch) const; - const EnumValueDescriptor* GetRepeatedEnum(const Message& message, - const FieldDescriptor* field, - int index) const; - const Message& GetRepeatedMessage(const Message& message, - const FieldDescriptor* field, - int index) const; - - // Set the value of a field. - void SetRepeatedInt32 (Message* message, - const FieldDescriptor* field, int index, int32 value) const; - void SetRepeatedInt64 (Message* message, - const FieldDescriptor* field, int index, int64 value) const; - void SetRepeatedUInt32(Message* message, - const FieldDescriptor* field, int index, uint32 value) const; - void SetRepeatedUInt64(Message* message, - const FieldDescriptor* field, int index, uint64 value) const; - void SetRepeatedFloat (Message* message, - const FieldDescriptor* field, int index, float value) const; - void SetRepeatedDouble(Message* message, - const FieldDescriptor* field, int index, double value) const; - void SetRepeatedBool (Message* message, - const FieldDescriptor* field, int index, bool value) const; - void SetRepeatedString(Message* message, - const FieldDescriptor* field, int index, - const string& value) const; - void SetRepeatedEnum(Message* message, const FieldDescriptor* field, - int index, const EnumValueDescriptor* value) const; - // Get a mutable pointer to a field with a message type. - Message* MutableRepeatedMessage(Message* message, - const FieldDescriptor* field, - int index) const; - - void AddInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; - void AddInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; - void AddUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; - void AddUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; - void AddFloat (Message* message, - const FieldDescriptor* field, float value) const; - void AddDouble(Message* message, - const FieldDescriptor* field, double value) const; - void AddBool (Message* message, - const FieldDescriptor* field, bool value) const; - void AddString(Message* message, - const FieldDescriptor* field, const string& value) const; - void AddEnum(Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const; - Message* AddMessage(Message* message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; - - const FieldDescriptor* FindKnownExtensionByName(const string& name) const; - const FieldDescriptor* FindKnownExtensionByNumber(int number) const; - - private: - friend class GeneratedMessage; - - const Descriptor* descriptor_; - const Message* default_instance_; - const int* offsets_; - - int has_bits_offset_; - int unknown_fields_offset_; - int extensions_offset_; - int object_size_; - - const DescriptorPool* descriptor_pool_; - MessageFactory* message_factory_; - - template - inline const Type& GetRaw(const Message& message, - const FieldDescriptor* field) const; - template - inline Type* MutableRaw(Message* message, - const FieldDescriptor* field) const; - template - inline const Type& DefaultRaw(const FieldDescriptor* field) const; - inline const Message* GetMessagePrototype(const FieldDescriptor* field) const; - - inline const uint32* GetHasBits(const Message& message) const; - inline uint32* MutableHasBits(Message* message) const; - inline const ExtensionSet& GetExtensionSet(const Message& message) const; - inline ExtensionSet* MutableExtensionSet(Message* message) const; - - inline bool HasBit(const Message& message, - const FieldDescriptor* field) const; - inline void SetBit(Message* message, - const FieldDescriptor* field) const; - inline void ClearBit(Message* message, - const FieldDescriptor* field) const; - - template - inline const Type& GetField(const Message& message, - const FieldDescriptor* field) const; - template - inline void SetField(Message* message, - const FieldDescriptor* field, const Type& value) const; - template - inline Type* MutableField(Message* message, - const FieldDescriptor* field) const; - template - inline const Type& GetRepeatedField(const Message& message, - const FieldDescriptor* field, - int index) const; - template - inline const Type& GetRepeatedPtrField(const Message& message, - const FieldDescriptor* field, - int index) const; - template - inline void SetRepeatedField(Message* message, - const FieldDescriptor* field, int index, - Type value) const; - template - inline Type* MutableRepeatedField(Message* message, - const FieldDescriptor* field, - int index) const; - template - inline void AddField(Message* message, - const FieldDescriptor* field, const Type& value) const; - template - inline Type* AddField(Message* message, - const FieldDescriptor* field) const; - - int GetExtensionNumberOrDie(const Descriptor* type) const; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); -}; - -// Returns the offset of the given field within the given aggregate type. -// This is equivalent to the ANSI C offsetof() macro. However, according -// to the C++ standard, offsetof() only works on POD types, and GCC -// enforces this requirement with a warning. In practice, this rule is -// unnecessarily strict; there is probably no compiler or platform on -// which the offsets of the direct fields of a class are non-constant. -// Fields inherited from superclasses *can* have non-constant offsets, -// but that's not what this macro will be used for. -// -// Note that we calculate relative to the pointer value 16 here since if we -// just use zero, GCC complains about dereferencing a NULL pointer. We -// choose 16 rather than some other number just in case the compiler would -// be confused by an unaligned pointer. -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ - static_cast( \ - reinterpret_cast( \ - &reinterpret_cast(16)->FIELD) - \ - reinterpret_cast(16)) - -// There are some places in proto2 where dynamic_cast would be useful as an -// optimization. For example, take Message::MergeFrom(const Message& other). -// For a given generated message FooMessage, we generate these two methods: -// void MergeFrom(const FooMessage& other); -// void MergeFrom(const Message& other); -// The former method can be implemented directly in terms of FooMessage's -// inline accessors, but the latter method must work with the reflection -// interface. However, if the parameter to the latter method is actually of -// type FooMessage, then we'd like to be able to just call the other method -// as an optimization. So, we use dynamic_cast to check this. -// -// That said, dynamic_cast requires RTTI, which many people like to disable -// for performance and code size reasons. When RTTI is not available, we -// still need to produce correct results. So, in this case we have to fall -// back to using reflection, which is what we would have done anyway if the -// objects were not of the exact same class. -// -// dynamic_cast_if_available() implements this logic. If RTTI is -// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns -// NULL. -// -// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. -// On MSVC, this should be detected automatically. -template -inline To dynamic_cast_if_available(From from) { -#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) - return NULL; -#else - return dynamic_cast(from); -#endif -} - -// Helper for EnumType_Parse functions: try to parse the string 'name' as an -// enum name of the given type, returning true and filling in value on success, -// or returning false and leaving value unchanged on failure. -LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, - const string& name, - int* value); - -template -bool ParseNamedEnum(const EnumDescriptor* descriptor, - const string& name, - EnumType* value) { - int tmp; - if (!ParseNamedEnum(descriptor, name, &tmp)) return false; - *value = static_cast(tmp); - return true; -} - -// Just a wrapper around printing the name of a value. The main point of this -// function is not to be inlined, so that you can do this without including -// descriptor.h. -LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ diff --git a/Resources/NetHook/google/protobuf/generated_message_reflection_unittest.cc b/Resources/NetHook/google/protobuf/generated_message_reflection_unittest.cc deleted file mode 100644 index a03bcdb7..00000000 --- a/Resources/NetHook/google/protobuf/generated_message_reflection_unittest.cc +++ /dev/null @@ -1,384 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// To test GeneratedMessageReflection, we actually let the protocol compiler -// generate a full protocol message implementation and then test its -// reflection interface. This is much easier and more maintainable than -// trying to create our own Message class for GeneratedMessageReflection -// to wrap. -// -// The tests here closely mirror some of the tests in -// compiler/cpp/unittest, except using the reflection interface -// rather than generated accessors. - -#include -#include -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { - -namespace { - -// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. -const FieldDescriptor* F(const string& name) { - const FieldDescriptor* result = - unittest::TestAllTypes::descriptor()->FindFieldByName(name); - GOOGLE_CHECK(result != NULL); - return result; -} - -TEST(GeneratedMessageReflectionTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - reflection_tester.ExpectClearViaReflection(message); - - const Reflection* reflection = message.GetReflection(); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &reflection->GetMessage(message, F("optionalgroup"))); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &reflection->GetMessage(message, F("optional_nested_message"))); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &reflection->GetMessage(message, F("optional_foreign_message"))); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &reflection->GetMessage(message, F("optional_import_message"))); -} - -TEST(GeneratedMessageReflectionTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - reflection_tester.SetAllFieldsViaReflection(&message); - TestUtil::ExpectAllFieldsSet(message); - reflection_tester.ExpectAllFieldsSetViaReflection(message); - - reflection_tester.ModifyRepeatedFieldsViaReflection(&message); - TestUtil::ExpectRepeatedFieldsModified(message); -} - -TEST(GeneratedMessageReflectionTest, GetStringReference) { - // Test that GetStringReference() returns the underlying string when it is - // a normal string field. - unittest::TestAllTypes message; - message.set_optional_string("foo"); - message.add_repeated_string("foo"); - - const Reflection* reflection = message.GetReflection(); - string scratch; - - EXPECT_EQ(&message.optional_string(), - &reflection->GetStringReference(message, F("optional_string"), &scratch)) - << "For simple string fields, GetStringReference() should return a " - "reference to the underlying string."; - EXPECT_EQ(&message.repeated_string(0), - &reflection->GetRepeatedStringReference(message, F("repeated_string"), - 0, &scratch)) - << "For simple string fields, GetRepeatedStringReference() should return " - "a reference to the underlying string."; -} - - -TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { - // Check that after setting all fields and then clearing, getting an - // embedded message does NOT return the default instance. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - TestUtil::SetAllFields(&message); - message.Clear(); - - const Reflection* reflection = message.GetReflection(); - - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &reflection->GetMessage(message, F("optionalgroup"))); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &reflection->GetMessage(message, F("optional_nested_message"))); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &reflection->GetMessage(message, F("optional_foreign_message"))); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &reflection->GetMessage(message, F("optional_import_message"))); -} - - -TEST(GeneratedMessageReflectionTest, Swap) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; - - TestUtil::SetAllFields(&message1); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - TestUtil::ExpectClear(message1); - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; - - TestUtil::SetAllFields(&message1); - TestUtil::SetAllFields(&message2); - TestUtil::ModifyRepeatedFields(&message2); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - TestUtil::ExpectRepeatedFieldsModified(message1); - TestUtil::ExpectAllFieldsSet(message2); - - message1.set_optional_int32(532819); - - reflection->Swap(&message1, &message2); - - EXPECT_EQ(532819, message2.optional_int32()); -} - -TEST(GeneratedMessageReflectionTest, SwapExtensions) { - unittest::TestAllExtensions message1; - unittest::TestAllExtensions message2; - - TestUtil::SetAllExtensions(&message1); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - TestUtil::ExpectExtensionsClear(message1); - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(GeneratedMessageReflectionTest, SwapUnknown) { - unittest::TestEmptyMessage message1, message2; - - message1.mutable_unknown_fields()->AddVarint(1234, 1); - - EXPECT_EQ(1, message1.unknown_fields().field_count()); - EXPECT_EQ(0, message2.unknown_fields().field_count()); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - EXPECT_EQ(0, message1.unknown_fields().field_count()); - EXPECT_EQ(1, message2.unknown_fields().field_count()); -} - -TEST(GeneratedMessageReflectionTest, RemoveLast) { - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - TestUtil::SetAllFields(&message); - - reflection_tester.RemoveLastRepeatedsViaReflection(&message); - - TestUtil::ExpectLastRepeatedsRemoved(message); -} - -TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { - unittest::TestAllExtensions message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllExtensions::descriptor()); - - TestUtil::SetAllExtensions(&message); - reflection_tester.RemoveLastRepeatedsViaReflection(&message); - - TestUtil::ExpectLastRepeatedExtensionsRemoved(message); -} - -TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - TestUtil::SetAllFields(&message); - - // Swap and test that fields are all swapped. - reflection_tester.SwapRepeatedsViaReflection(&message); - TestUtil::ExpectRepeatedsSwapped(message); - - // Swap back and test that fields are all back to original values. - reflection_tester.SwapRepeatedsViaReflection(&message); - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { - unittest::TestAllExtensions message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllExtensions::descriptor()); - - TestUtil::SetAllExtensions(&message); - - // Swap and test that fields are all swapped. - reflection_tester.SwapRepeatedsViaReflection(&message); - TestUtil::ExpectRepeatedExtensionsSwapped(message); - - // Swap back and test that fields are all back to original values. - reflection_tester.SwapRepeatedsViaReflection(&message); - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(GeneratedMessageReflectionTest, Extensions) { - // Set every extension to a unique value then go back and check all those - // values. - unittest::TestAllExtensions message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllExtensions::descriptor()); - - reflection_tester.SetAllFieldsViaReflection(&message); - TestUtil::ExpectAllExtensionsSet(message); - reflection_tester.ExpectAllFieldsSetViaReflection(message); - - reflection_tester.ModifyRepeatedFieldsViaReflection(&message); - TestUtil::ExpectRepeatedExtensionsModified(message); -} - -TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { - const Reflection* reflection = - unittest::TestAllExtensions::default_instance().GetReflection(); - - const FieldDescriptor* extension1 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "optional_int32_extension"); - const FieldDescriptor* extension2 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "repeated_string_extension"); - - EXPECT_EQ(extension1, - reflection->FindKnownExtensionByNumber(extension1->number())); - EXPECT_EQ(extension2, - reflection->FindKnownExtensionByNumber(extension2->number())); - - // Non-existent extension. - EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); - - // Extensions of TestAllExtensions should not show up as extensions of - // other types. - EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> - FindKnownExtensionByNumber(extension1->number()) == NULL); -} - -TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { - const Reflection* reflection = - unittest::TestAllExtensions::default_instance().GetReflection(); - - const FieldDescriptor* extension1 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "optional_int32_extension"); - const FieldDescriptor* extension2 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "repeated_string_extension"); - - EXPECT_EQ(extension1, - reflection->FindKnownExtensionByName(extension1->full_name())); - EXPECT_EQ(extension2, - reflection->FindKnownExtensionByName(extension2->full_name())); - - // Non-existent extension. - EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); - - // Extensions of TestAllExtensions should not show up as extensions of - // other types. - EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> - FindKnownExtensionByName(extension1->full_name()) == NULL); -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(GeneratedMessageReflectionTest, UsageErrors) { - unittest::TestAllTypes message; - const Reflection* reflection = message.GetReflection(); - const Descriptor* descriptor = message.GetDescriptor(); - -#define f(NAME) descriptor->FindFieldByName(NAME) - - // Testing every single failure mode would be too much work. Let's just - // check a few. - EXPECT_DEATH( - reflection->GetInt32( - message, descriptor->FindFieldByName("optional_int64")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest\\.TestAllTypes\n" - " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" - " Problem : Field is not the right type for this message:\n" - " Expected : CPPTYPE_INT32\n" - " Field type: CPPTYPE_INT64"); - EXPECT_DEATH( - reflection->GetInt32( - message, descriptor->FindFieldByName("repeated_int32")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" - " Problem : Field is repeated; the method requires a singular field."); - EXPECT_DEATH( - reflection->GetInt32( - message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.ForeignMessage.c\n" - " Problem : Field does not match message type."); - EXPECT_DEATH( - reflection->HasField( - message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::HasField\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.ForeignMessage.c\n" - " Problem : Field does not match message type."); - -#undef f -} - -#endif // GTEST_HAS_DEATH_TEST - - -} // namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/generated_message_util.cc b/Resources/NetHook/google/protobuf/generated_message_util.cc deleted file mode 100644 index 7ac015d0..00000000 --- a/Resources/NetHook/google/protobuf/generated_message_util.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -#include - -namespace google { -namespace protobuf { -namespace internal { - -double Infinity() { - return std::numeric_limits::infinity(); -} -double NaN() { - return std::numeric_limits::quiet_NaN(); -} - - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/generated_message_util.h b/Resources/NetHook/google/protobuf/generated_message_util.h deleted file mode 100644 index daa16f77..00000000 --- a/Resources/NetHook/google/protobuf/generated_message_util.h +++ /dev/null @@ -1,77 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains miscellaneous helper code used by generated code -- -// including lite types -- but which should not be used directly by users. - -#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ - -#include - - -namespace google { -namespace protobuf { - namespace io { - class CodedInputStream; // coded_stream.h - } -} - -namespace protobuf { -namespace internal { - -// Annotation for the compiler to emit a deprecation message if a field marked -// with option 'deprecated=true' is used in the code, or for other things in -// generated code which are deprecated. -// -// For internal use in the pb.cc files, deprecation warnings are suppressed -// there. -#undef DEPRECATED_PROTOBUF_FIELD -#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION) -# define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED -#else -# define PROTOBUF_DEPRECATED -#endif - - -// Constants for special floating point values. -LIBPROTOBUF_EXPORT double Infinity(); -LIBPROTOBUF_EXPORT double NaN(); - - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ diff --git a/Resources/NetHook/google/protobuf/io/coded_stream.cc b/Resources/NetHook/google/protobuf/io/coded_stream.cc deleted file mode 100644 index 6a91a13d..00000000 --- a/Resources/NetHook/google/protobuf/io/coded_stream.cc +++ /dev/null @@ -1,830 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This implementation is heavily optimized to make reads and writes -// of small values (especially varints) as fast as possible. In -// particular, we optimize for the common case that a read or a write -// will not cross the end of the buffer, since we can avoid a lot -// of branching in this case. - -#include -#include -#include -#include -#include -#include - - -namespace google { -namespace protobuf { -namespace io { - -namespace { - -static const int kMaxVarintBytes = 10; -static const int kMaxVarint32Bytes = 5; - - -} // namespace - -// CodedInputStream ================================================== - - -void CodedInputStream::BackUpInputToCurrentPosition() { - int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_; - if (backup_bytes > 0) { - input_->BackUp(backup_bytes); - - // total_bytes_read_ doesn't include overflow_bytes_. - total_bytes_read_ -= BufferSize() + buffer_size_after_limit_; - buffer_end_ = buffer_; - buffer_size_after_limit_ = 0; - overflow_bytes_ = 0; - } -} - -inline void CodedInputStream::RecomputeBufferLimits() { - buffer_end_ += buffer_size_after_limit_; - int closest_limit = min(current_limit_, total_bytes_limit_); - if (closest_limit < total_bytes_read_) { - // The limit position is in the current buffer. We must adjust - // the buffer size accordingly. - buffer_size_after_limit_ = total_bytes_read_ - closest_limit; - buffer_end_ -= buffer_size_after_limit_; - } else { - buffer_size_after_limit_ = 0; - } -} - -CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { - // Current position relative to the beginning of the stream. - int current_position = total_bytes_read_ - - (BufferSize() + buffer_size_after_limit_); - - Limit old_limit = current_limit_; - - // security: byte_limit is possibly evil, so check for negative values - // and overflow. - if (byte_limit >= 0 && - byte_limit <= INT_MAX - current_position) { - current_limit_ = current_position + byte_limit; - } else { - // Negative or overflow. - current_limit_ = INT_MAX; - } - - // We need to enforce all limits, not just the new one, so if the previous - // limit was before the new requested limit, we continue to enforce the - // previous limit. - current_limit_ = min(current_limit_, old_limit); - - RecomputeBufferLimits(); - return old_limit; -} - -void CodedInputStream::PopLimit(Limit limit) { - // The limit passed in is actually the *old* limit, which we returned from - // PushLimit(). - current_limit_ = limit; - RecomputeBufferLimits(); - - // We may no longer be at a legitimate message end. ReadTag() needs to be - // called again to find out. - legitimate_message_end_ = false; -} - -int CodedInputStream::BytesUntilLimit() { - if (current_limit_ == INT_MAX) return -1; - int current_position = total_bytes_read_ - - (BufferSize() + buffer_size_after_limit_); - - return current_limit_ - current_position; -} - -void CodedInputStream::SetTotalBytesLimit( - int total_bytes_limit, int warning_threshold) { - // Make sure the limit isn't already past, since this could confuse other - // code. - int current_position = total_bytes_read_ - - (BufferSize() + buffer_size_after_limit_); - total_bytes_limit_ = max(current_position, total_bytes_limit); - total_bytes_warning_threshold_ = warning_threshold; - RecomputeBufferLimits(); -} - -void CodedInputStream::PrintTotalBytesLimitError() { - GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too " - "big (more than " << total_bytes_limit_ - << " bytes). To increase the limit (or to disable these " - "warnings), see CodedInputStream::SetTotalBytesLimit() " - "in google/protobuf/io/coded_stream.h."; -} - -bool CodedInputStream::Skip(int count) { - if (count < 0) return false; // security: count is often user-supplied - - const int original_buffer_size = BufferSize(); - - if (count <= original_buffer_size) { - // Just skipping within the current buffer. Easy. - Advance(count); - return true; - } - - if (buffer_size_after_limit_ > 0) { - // We hit a limit inside this buffer. Advance to the limit and fail. - Advance(original_buffer_size); - return false; - } - - count -= original_buffer_size; - buffer_ = NULL; - buffer_end_ = buffer_; - - // Make sure this skip doesn't try to skip past the current limit. - int closest_limit = min(current_limit_, total_bytes_limit_); - int bytes_until_limit = closest_limit - total_bytes_read_; - if (bytes_until_limit < count) { - // We hit the limit. Skip up to it then fail. - if (bytes_until_limit > 0) { - total_bytes_read_ = closest_limit; - input_->Skip(bytes_until_limit); - } - return false; - } - - total_bytes_read_ += count; - return input_->Skip(count); -} - -bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { - if (BufferSize() == 0 && !Refresh()) return false; - - *data = buffer_; - *size = BufferSize(); - return true; -} - -bool CodedInputStream::ReadRaw(void* buffer, int size) { - int current_buffer_size; - while ((current_buffer_size = BufferSize()) < size) { - // Reading past end of buffer. Copy what we have, then refresh. - memcpy(buffer, buffer_, current_buffer_size); - buffer = reinterpret_cast(buffer) + current_buffer_size; - size -= current_buffer_size; - Advance(current_buffer_size); - if (!Refresh()) return false; - } - - memcpy(buffer, buffer_, size); - Advance(size); - - return true; -} - -bool CodedInputStream::ReadString(string* buffer, int size) { - if (size < 0) return false; // security: size is often user-supplied - return InternalReadStringInline(buffer, size); -} - -bool CodedInputStream::ReadStringFallback(string* buffer, int size) { - if (!buffer->empty()) { - buffer->clear(); - } - - int current_buffer_size; - while ((current_buffer_size = BufferSize()) < size) { - // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). - if (current_buffer_size != 0) { - // Note: string1.append(string2) is O(string2.size()) (as opposed to - // O(string1.size() + string2.size()), which would be bad). - buffer->append(reinterpret_cast(buffer_), - current_buffer_size); - } - size -= current_buffer_size; - Advance(current_buffer_size); - if (!Refresh()) return false; - } - - buffer->append(reinterpret_cast(buffer_), size); - Advance(size); - - return true; -} - - -bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { - uint8 bytes[sizeof(*value)]; - - const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { - // Fast path: Enough bytes in the buffer to read directly. - ptr = buffer_; - Advance(sizeof(*value)); - } else { - // Slow path: Had to read past the end of the buffer. - if (!ReadRaw(bytes, sizeof(*value))) return false; - ptr = bytes; - } - ReadLittleEndian32FromArray(ptr, value); - return true; -} - -bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { - uint8 bytes[sizeof(*value)]; - - const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { - // Fast path: Enough bytes in the buffer to read directly. - ptr = buffer_; - Advance(sizeof(*value)); - } else { - // Slow path: Had to read past the end of the buffer. - if (!ReadRaw(bytes, sizeof(*value))) return false; - ptr = bytes; - } - ReadLittleEndian64FromArray(ptr, value); - return true; -} - -namespace { - -inline const uint8* ReadVarint32FromArray( - const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - const uint8* ptr = buffer; - uint32 b; - uint32 result; - - b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done; - - // If the input is larger than 32 bits, we still need to read it all - // and discard the high-order bits. - for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { - b = *(ptr++); if (!(b & 0x80)) goto done; - } - - // We have overrun the maximum size of a varint (10 bytes). Assume - // the data is corrupt. - return NULL; - - done: - *value = result; - return ptr; -} - -} // namespace - -bool CodedInputStream::ReadVarint32Slow(uint32* value) { - uint64 result; - // Directly invoke ReadVarint64Fallback, since we already tried to optimize - // for one-byte varints. - if (!ReadVarint64Fallback(&result)) return false; - *value = (uint32)result; - return true; -} - -bool CodedInputStream::ReadVarint32Fallback(uint32* value) { - if (BufferSize() >= kMaxVarintBytes || - // Optimization: If the varint ends at exactly the end of the buffer, - // we can detect that and still use the fast path. - (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - const uint8* end = ReadVarint32FromArray(buffer_, value); - if (end == NULL) return false; - buffer_ = end; - return true; - } else { - // Really slow case: we will incur the cost of an extra function call here, - // but moving this out of line reduces the size of this function, which - // improves the common case. In micro benchmarks, this is worth about 10-15% - return ReadVarint32Slow(value); - } -} - -uint32 CodedInputStream::ReadTagSlow() { - if (buffer_ == buffer_end_) { - // Call refresh. - if (!Refresh()) { - // Refresh failed. Make sure that it failed due to EOF, not because - // we hit total_bytes_limit_, which, unlike normal limits, is not a - // valid place to end a message. - int current_position = total_bytes_read_ - buffer_size_after_limit_; - if (current_position >= total_bytes_limit_) { - // Hit total_bytes_limit_. But if we also hit the normal limit, - // we're still OK. - legitimate_message_end_ = current_limit_ == total_bytes_limit_; - } else { - legitimate_message_end_ = true; - } - return 0; - } - } - - // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags - // again, since we have now refreshed the buffer. - uint64 result; - if (!ReadVarint64(&result)) return 0; - return static_cast(result); -} - -uint32 CodedInputStream::ReadTagFallback() { - if (BufferSize() >= kMaxVarintBytes || - // Optimization: If the varint ends at exactly the end of the buffer, - // we can detect that and still use the fast path. - (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - uint32 tag; - const uint8* end = ReadVarint32FromArray(buffer_, &tag); - if (end == NULL) { - return 0; - } - buffer_ = end; - return tag; - } else { - // We are commonly at a limit when attempting to read tags. Try to quickly - // detect this case without making another function call. - if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 && - // Make sure that the limit we hit is not total_bytes_limit_, since - // in that case we still need to call Refresh() so that it prints an - // error. - total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { - // We hit a byte limit. - legitimate_message_end_ = true; - return 0; - } - return ReadTagSlow(); - } -} - -bool CodedInputStream::ReadVarint64Slow(uint64* value) { - // Slow path: This read might cross the end of the buffer, so we - // need to check and refresh the buffer if and when it does. - - uint64 result = 0; - int count = 0; - uint32 b; - - do { - if (count == kMaxVarintBytes) return false; - while (buffer_ == buffer_end_) { - if (!Refresh()) return false; - } - b = *buffer_; - result |= static_cast(b & 0x7F) << (7 * count); - Advance(1); - ++count; - } while (b & 0x80); - - *value = result; - return true; -} - -bool CodedInputStream::ReadVarint64Fallback(uint64* value) { - if (BufferSize() >= kMaxVarintBytes || - // Optimization: If the varint ends at exactly the end of the buffer, - // we can detect that and still use the fast path. - (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - - const uint8* ptr = buffer_; - uint32 b; - - // Splitting into 32-bit pieces gives better performance on 32-bit - // processors. - uint32 part0 = 0, part1 = 0, part2 = 0; - - b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - - // We have overrun the maximum size of a varint (10 bytes). The data - // must be corrupt. - return NULL; - - done: - Advance(ptr - buffer_); - *value = (static_cast(part0) ) | - (static_cast(part1) << 28) | - (static_cast(part2) << 56); - return true; - } else { - return ReadVarint64Slow(value); - } -} - -bool CodedInputStream::Refresh() { - GOOGLE_DCHECK_EQ(0, BufferSize()); - - if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || - total_bytes_read_ == current_limit_) { - // We've hit a limit. Stop. - int current_position = total_bytes_read_ - buffer_size_after_limit_; - - if (current_position >= total_bytes_limit_ && - total_bytes_limit_ != current_limit_) { - // Hit total_bytes_limit_. - PrintTotalBytesLimitError(); - } - - return false; - } - - if (total_bytes_warning_threshold_ >= 0 && - total_bytes_read_ >= total_bytes_warning_threshold_) { - GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the " - "message turns out to be larger than " - << total_bytes_limit_ << " bytes, parsing will be halted " - "for security reasons. To increase the limit (or to " - "disable these warnings), see " - "CodedInputStream::SetTotalBytesLimit() in " - "google/protobuf/io/coded_stream.h."; - - // Don't warn again for this stream. - total_bytes_warning_threshold_ = -1; - } - - const void* void_buffer; - int buffer_size; - if (input_->Next(&void_buffer, &buffer_size)) { - buffer_ = reinterpret_cast(void_buffer); - buffer_end_ = buffer_ + buffer_size; - GOOGLE_CHECK_GE(buffer_size, 0); - - if (total_bytes_read_ <= INT_MAX - buffer_size) { - total_bytes_read_ += buffer_size; - } else { - // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX. - // We can't get that far anyway, because total_bytes_limit_ is guaranteed - // to be less than it. We need to keep track of the number of bytes - // we discarded, though, so that we can call input_->BackUp() to back - // up over them on destruction. - - // The following line is equivalent to: - // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX; - // except that it avoids overflows. Signed integer overflow has - // undefined results according to the C standard. - overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size); - buffer_end_ -= overflow_bytes_; - total_bytes_read_ = INT_MAX; - } - - RecomputeBufferLimits(); - return true; - } else { - buffer_ = NULL; - buffer_end_ = NULL; - return false; - } -} - -// CodedOutputStream ================================================= - -CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) - : output_(output), - buffer_(NULL), - buffer_size_(0), - total_bytes_(0), - had_error_(false) { - // Eagerly Refresh() so buffer space is immediately available. - Refresh(); - // The Refresh() may have failed. If the client doesn't write any data, - // though, don't consider this an error. If the client does write data, then - // another Refresh() will be attempted and it will set the error once again. - had_error_ = false; -} - -CodedOutputStream::~CodedOutputStream() { - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } -} - -bool CodedOutputStream::Skip(int count) { - if (count < 0) return false; - - while (count > buffer_size_) { - count -= buffer_size_; - if (!Refresh()) return false; - } - - Advance(count); - return true; -} - -bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) { - if (buffer_size_ == 0 && !Refresh()) return false; - - *data = buffer_; - *size = buffer_size_; - return true; -} - -void CodedOutputStream::WriteRaw(const void* data, int size) { - while (buffer_size_ < size) { - memcpy(buffer_, data, buffer_size_); - size -= buffer_size_; - data = reinterpret_cast(data) + buffer_size_; - if (!Refresh()) return; - } - - memcpy(buffer_, data, size); - Advance(size); -} - -uint8* CodedOutputStream::WriteRawToArray( - const void* data, int size, uint8* target) { - memcpy(target, data, size); - return target + size; -} - - -void CodedOutputStream::WriteLittleEndian32(uint32 value) { - uint8 bytes[sizeof(value)]; - - bool use_fast = buffer_size_ >= sizeof(value); - uint8* ptr = use_fast ? buffer_ : bytes; - - WriteLittleEndian32ToArray(value, ptr); - - if (use_fast) { - Advance(sizeof(value)); - } else { - WriteRaw(bytes, sizeof(value)); - } -} - -void CodedOutputStream::WriteLittleEndian64(uint64 value) { - uint8 bytes[sizeof(value)]; - - bool use_fast = buffer_size_ >= sizeof(value); - uint8* ptr = use_fast ? buffer_ : bytes; - - WriteLittleEndian64ToArray(value, ptr); - - if (use_fast) { - Advance(sizeof(value)); - } else { - WriteRaw(bytes, sizeof(value)); - } -} - -inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline( - uint32 value, uint8* target) { - target[0] = static_cast(value | 0x80); - if (value >= (1 << 7)) { - target[1] = static_cast((value >> 7) | 0x80); - if (value >= (1 << 14)) { - target[2] = static_cast((value >> 14) | 0x80); - if (value >= (1 << 21)) { - target[3] = static_cast((value >> 21) | 0x80); - if (value >= (1 << 28)) { - target[4] = static_cast(value >> 28); - return target + 5; - } else { - target[3] &= 0x7F; - return target + 4; - } - } else { - target[2] &= 0x7F; - return target + 3; - } - } else { - target[1] &= 0x7F; - return target + 2; - } - } else { - target[0] &= 0x7F; - return target + 1; - } -} - -void CodedOutputStream::WriteVarint32(uint32 value) { - if (buffer_size_ >= kMaxVarint32Bytes) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this write won't cross the end, so we can skip the checks. - uint8* target = buffer_; - uint8* end = WriteVarint32FallbackToArrayInline(value, target); - int size = end - target; - Advance(size); - } else { - // Slow path: This write might cross the end of the buffer, so we - // compose the bytes first then use WriteRaw(). - uint8 bytes[kMaxVarint32Bytes]; - int size = 0; - while (value > 0x7F) { - bytes[size++] = (static_cast(value) & 0x7F) | 0x80; - value >>= 7; - } - bytes[size++] = static_cast(value) & 0x7F; - WriteRaw(bytes, size); - } -} - -uint8* CodedOutputStream::WriteVarint32FallbackToArray( - uint32 value, uint8* target) { - return WriteVarint32FallbackToArrayInline(value, target); -} - -inline uint8* CodedOutputStream::WriteVarint64ToArrayInline( - uint64 value, uint8* target) { - // Splitting into 32-bit pieces gives better performance on 32-bit - // processors. - uint32 part0 = static_cast(value ); - uint32 part1 = static_cast(value >> 28); - uint32 part2 = static_cast(value >> 56); - - int size; - - // Here we can't really optimize for small numbers, since the value is - // split into three parts. Cheking for numbers < 128, for instance, - // would require three comparisons, since you'd have to make sure part1 - // and part2 are zero. However, if the caller is using 64-bit integers, - // it is likely that they expect the numbers to often be very large, so - // we probably don't want to optimize for small numbers anyway. Thus, - // we end up with a hardcoded binary search tree... - if (part2 == 0) { - if (part1 == 0) { - if (part0 < (1 << 14)) { - if (part0 < (1 << 7)) { - size = 1; goto size1; - } else { - size = 2; goto size2; - } - } else { - if (part0 < (1 << 21)) { - size = 3; goto size3; - } else { - size = 4; goto size4; - } - } - } else { - if (part1 < (1 << 14)) { - if (part1 < (1 << 7)) { - size = 5; goto size5; - } else { - size = 6; goto size6; - } - } else { - if (part1 < (1 << 21)) { - size = 7; goto size7; - } else { - size = 8; goto size8; - } - } - } - } else { - if (part2 < (1 << 7)) { - size = 9; goto size9; - } else { - size = 10; goto size10; - } - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - - size10: target[9] = static_cast((part2 >> 7) | 0x80); - size9 : target[8] = static_cast((part2 ) | 0x80); - size8 : target[7] = static_cast((part1 >> 21) | 0x80); - size7 : target[6] = static_cast((part1 >> 14) | 0x80); - size6 : target[5] = static_cast((part1 >> 7) | 0x80); - size5 : target[4] = static_cast((part1 ) | 0x80); - size4 : target[3] = static_cast((part0 >> 21) | 0x80); - size3 : target[2] = static_cast((part0 >> 14) | 0x80); - size2 : target[1] = static_cast((part0 >> 7) | 0x80); - size1 : target[0] = static_cast((part0 ) | 0x80); - - target[size-1] &= 0x7F; - return target + size; -} - -void CodedOutputStream::WriteVarint64(uint64 value) { - if (buffer_size_ >= kMaxVarintBytes) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this write won't cross the end, so we can skip the checks. - uint8* target = buffer_; - - uint8* end = WriteVarint64ToArrayInline(value, target); - int size = end - target; - Advance(size); - } else { - // Slow path: This write might cross the end of the buffer, so we - // compose the bytes first then use WriteRaw(). - uint8 bytes[kMaxVarintBytes]; - int size = 0; - while (value > 0x7F) { - bytes[size++] = (static_cast(value) & 0x7F) | 0x80; - value >>= 7; - } - bytes[size++] = static_cast(value) & 0x7F; - WriteRaw(bytes, size); - } -} - -uint8* CodedOutputStream::WriteVarint64ToArray( - uint64 value, uint8* target) { - return WriteVarint64ToArrayInline(value, target); -} - -bool CodedOutputStream::Refresh() { - void* void_buffer; - if (output_->Next(&void_buffer, &buffer_size_)) { - buffer_ = reinterpret_cast(void_buffer); - total_bytes_ += buffer_size_; - return true; - } else { - buffer_ = NULL; - buffer_size_ = 0; - had_error_ = true; - return false; - } -} - -int CodedOutputStream::VarintSize32Fallback(uint32 value) { - if (value < (1 << 7)) { - return 1; - } else if (value < (1 << 14)) { - return 2; - } else if (value < (1 << 21)) { - return 3; - } else if (value < (1 << 28)) { - return 4; - } else { - return 5; - } -} - -int CodedOutputStream::VarintSize64(uint64 value) { - if (value < (1ull << 35)) { - if (value < (1ull << 7)) { - return 1; - } else if (value < (1ull << 14)) { - return 2; - } else if (value < (1ull << 21)) { - return 3; - } else if (value < (1ull << 28)) { - return 4; - } else { - return 5; - } - } else { - if (value < (1ull << 42)) { - return 6; - } else if (value < (1ull << 49)) { - return 7; - } else if (value < (1ull << 56)) { - return 8; - } else if (value < (1ull << 63)) { - return 9; - } else { - return 10; - } - } -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/coded_stream.h b/Resources/NetHook/google/protobuf/io/coded_stream.h deleted file mode 100644 index dcbb0d45..00000000 --- a/Resources/NetHook/google/protobuf/io/coded_stream.h +++ /dev/null @@ -1,1090 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains the CodedInputStream and CodedOutputStream classes, -// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, -// and allow you to read or write individual pieces of data in various -// formats. In particular, these implement the varint encoding for -// integers, a simple variable-length encoding in which smaller numbers -// take fewer bytes. -// -// Typically these classes will only be used internally by the protocol -// buffer library in order to encode and decode protocol buffers. Clients -// of the library only need to know about this class if they wish to write -// custom message parsing or serialization procedures. -// -// CodedOutputStream example: -// // Write some data to "myfile". First we write a 4-byte "magic number" -// // to identify the file type, then write a length-delimited string. The -// // string is composed of a varint giving the length followed by the raw -// // bytes. -// int fd = open("myfile", O_WRONLY); -// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); -// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); -// -// int magic_number = 1234; -// char text[] = "Hello world!"; -// coded_output->WriteLittleEndian32(magic_number); -// coded_output->WriteVarint32(strlen(text)); -// coded_output->WriteRaw(text, strlen(text)); -// -// delete coded_output; -// delete raw_output; -// close(fd); -// -// CodedInputStream example: -// // Read a file created by the above code. -// int fd = open("myfile", O_RDONLY); -// ZeroCopyInputStream* raw_input = new FileInputStream(fd); -// CodedInputStream coded_input = new CodedInputStream(raw_input); -// -// coded_input->ReadLittleEndian32(&magic_number); -// if (magic_number != 1234) { -// cerr << "File not in expected format." << endl; -// return; -// } -// -// uint32 size; -// coded_input->ReadVarint32(&size); -// -// char* text = new char[size + 1]; -// coded_input->ReadRaw(buffer, size); -// text[size] = '\0'; -// -// delete coded_input; -// delete raw_input; -// close(fd); -// -// cout << "Text is: " << text << endl; -// delete [] text; -// -// For those who are interested, varint encoding is defined as follows: -// -// The encoding operates on unsigned integers of up to 64 bits in length. -// Each byte of the encoded value has the format: -// * bits 0-6: Seven bits of the number being encoded. -// * bit 7: Zero if this is the last byte in the encoding (in which -// case all remaining bits of the number are zero) or 1 if -// more bytes follow. -// The first byte contains the least-significant 7 bits of the number, the -// second byte (if present) contains the next-least-significant 7 bits, -// and so on. So, the binary number 1011000101011 would be encoded in two -// bytes as "10101011 00101100". -// -// In theory, varint could be used to encode integers of any length. -// However, for practicality we set a limit at 64 bits. The maximum encoded -// length of a number is thus 10 bytes. - -#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ -#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ - -#include -#ifndef _MSC_VER -#include -#endif // !_MSC_VER -#include -#include // for GOOGLE_PREDICT_TRUE macro - -namespace google { - -namespace protobuf { - -class DescriptorPool; -class MessageFactory; - -namespace io { - -// Defined in this file. -class CodedInputStream; -class CodedOutputStream; - -// Defined in other files. -class ZeroCopyInputStream; // zero_copy_stream.h -class ZeroCopyOutputStream; // zero_copy_stream.h - -// Class which reads and decodes binary data which is composed of varint- -// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream. -// Most users will not need to deal with CodedInputStream. -// -// Most methods of CodedInputStream that return a bool return false if an -// underlying I/O error occurs or if the data is malformed. Once such a -// failure occurs, the CodedInputStream is broken and is no longer useful. -class LIBPROTOBUF_EXPORT CodedInputStream { - public: - // Create a CodedInputStream that reads from the given ZeroCopyInputStream. - explicit CodedInputStream(ZeroCopyInputStream* input); - - // Create a CodedInputStream that reads from the given flat array. This is - // faster than using an ArrayInputStream. PushLimit(size) is implied by - // this constructor. - explicit CodedInputStream(const uint8* buffer, int size); - - // Destroy the CodedInputStream and position the underlying - // ZeroCopyInputStream at the first unread byte. If an error occurred while - // reading (causing a method to return false), then the exact position of - // the input stream may be anywhere between the last value that was read - // successfully and the stream's byte limit. - ~CodedInputStream(); - - - // Skips a number of bytes. Returns false if an underlying read error - // occurs. - bool Skip(int count); - - // Sets *data to point directly at the unread part of the CodedInputStream's - // underlying buffer, and *size to the size of that buffer, but does not - // advance the stream's current position. This will always either produce - // a non-empty buffer or return false. If the caller consumes any of - // this data, it should then call Skip() to skip over the consumed bytes. - // This may be useful for implementing external fast parsing routines for - // types of data not covered by the CodedInputStream interface. - bool GetDirectBufferPointer(const void** data, int* size); - - // Like GetDirectBufferPointer, but this method is inlined, and does not - // attempt to Refresh() if the buffer is currently empty. - inline void GetDirectBufferPointerInline(const void** data, - int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Read raw bytes, copying them into the given buffer. - bool ReadRaw(void* buffer, int size); - - // Like ReadRaw, but reads into a string. - // - // Implementation Note: ReadString() grows the string gradually as it - // reads in the data, rather than allocating the entire requested size - // upfront. This prevents denial-of-service attacks in which a client - // could claim that a string is going to be MAX_INT bytes long in order to - // crash the server because it can't allocate this much space at once. - bool ReadString(string* buffer, int size); - // Like the above, with inlined optimizations. This should only be used - // by the protobuf implementation. - inline bool InternalReadStringInline(string* buffer, - int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - - // Read a 32-bit little-endian integer. - bool ReadLittleEndian32(uint32* value); - // Read a 64-bit little-endian integer. - bool ReadLittleEndian64(uint64* value); - - // These methods read from an externally provided buffer. The caller is - // responsible for ensuring that the buffer has sufficient space. - // Read a 32-bit little-endian integer. - static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, - uint32* value); - // Read a 64-bit little-endian integer. - static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, - uint64* value); - - // Read an unsigned integer with Varint encoding, truncating to 32 bits. - // Reading a 32-bit value is equivalent to reading a 64-bit one and casting - // it to uint32, but may be more efficient. - bool ReadVarint32(uint32* value); - // Read an unsigned integer with Varint encoding. - bool ReadVarint64(uint64* value); - - // Read a tag. This calls ReadVarint32() and returns the result, or returns - // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates - // the last tag value, which can be checked with LastTagWas(). - // Always inline because this is only called in once place per parse loop - // but it is called for every iteration of said loop, so it should be fast. - // GCC doesn't want to inline this by default. - uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Usually returns true if calling ReadVarint32() now would produce the given - // value. Will always return false if ReadVarint32() would not return the - // given value. If ExpectTag() returns true, it also advances past - // the varint. For best performance, use a compile-time constant as the - // parameter. - // Always inline because this collapses to a small number of instructions - // when given a constant parameter, but GCC doesn't want to inline by default. - bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Like above, except this reads from the specified buffer. The caller is - // responsible for ensuring that the buffer is large enough to read a varint - // of the expected size. For best performance, use a compile-time constant as - // the expected tag parameter. - // - // Returns a pointer beyond the expected tag if it was found, or NULL if it - // was not. - static const uint8* ExpectTagFromArray( - const uint8* buffer, - uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Usually returns true if no more bytes can be read. Always returns false - // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent - // call to LastTagWas() will act as if ReadTag() had been called and returned - // zero, and ConsumedEntireMessage() will return true. - bool ExpectAtEnd(); - - // If the last call to ReadTag() returned the given value, returns true. - // Otherwise, returns false; - // - // This is needed because parsers for some types of embedded messages - // (with field type TYPE_GROUP) don't actually know that they've reached the - // end of a message until they see an ENDGROUP tag, which was actually part - // of the enclosing message. The enclosing message would like to check that - // tag to make sure it had the right number, so it calls LastTagWas() on - // return from the embedded parser to check. - bool LastTagWas(uint32 expected); - - // When parsing message (but NOT a group), this method must be called - // immediately after MergeFromCodedStream() returns (if it returns true) - // to further verify that the message ended in a legitimate way. For - // example, this verifies that parsing did not end on an end-group tag. - // It also checks for some cases where, due to optimizations, - // MergeFromCodedStream() can incorrectly return true. - bool ConsumedEntireMessage(); - - // Limits ---------------------------------------------------------- - // Limits are used when parsing length-delimited embedded messages. - // After the message's length is read, PushLimit() is used to prevent - // the CodedInputStream from reading beyond that length. Once the - // embedded message has been parsed, PopLimit() is called to undo the - // limit. - - // Opaque type used with PushLimit() and PopLimit(). Do not modify - // values of this type yourself. The only reason that this isn't a - // struct with private internals is for efficiency. - typedef int Limit; - - // Places a limit on the number of bytes that the stream may read, - // starting from the current position. Once the stream hits this limit, - // it will act like the end of the input has been reached until PopLimit() - // is called. - // - // As the names imply, the stream conceptually has a stack of limits. The - // shortest limit on the stack is always enforced, even if it is not the - // top limit. - // - // The value returned by PushLimit() is opaque to the caller, and must - // be passed unchanged to the corresponding call to PopLimit(). - Limit PushLimit(int byte_limit); - - // Pops the last limit pushed by PushLimit(). The input must be the value - // returned by that call to PushLimit(). - void PopLimit(Limit limit); - - // Returns the number of bytes left until the nearest limit on the - // stack is hit, or -1 if no limits are in place. - int BytesUntilLimit(); - - // Total Bytes Limit ----------------------------------------------- - // To prevent malicious users from sending excessively large messages - // and causing integer overflows or memory exhaustion, CodedInputStream - // imposes a hard limit on the total number of bytes it will read. - - // Sets the maximum number of bytes that this CodedInputStream will read - // before refusing to continue. To prevent integer overflows in the - // protocol buffers implementation, as well as to prevent servers from - // allocating enormous amounts of memory to hold parsed messages, the - // maximum message length should be limited to the shortest length that - // will not harm usability. The theoretical shortest message that could - // cause integer overflows is 512MB. The default limit is 64MB. Apps - // should set shorter limits if possible. If warning_threshold is not -1, - // a warning will be printed to stderr after warning_threshold bytes are - // read. An error will always be printed to stderr if the limit is - // reached. - // - // This is unrelated to PushLimit()/PopLimit(). - // - // Hint: If you are reading this because your program is printing a - // warning about dangerously large protocol messages, you may be - // confused about what to do next. The best option is to change your - // design such that excessively large messages are not necessary. - // For example, try to design file formats to consist of many small - // messages rather than a single large one. If this is infeasible, - // you will need to increase the limit. Chances are, though, that - // your code never constructs a CodedInputStream on which the limit - // can be set. You probably parse messages by calling things like - // Message::ParseFromString(). In this case, you will need to change - // your code to instead construct some sort of ZeroCopyInputStream - // (e.g. an ArrayInputStream), construct a CodedInputStream around - // that, then call Message::ParseFromCodedStream() instead. Then - // you can adjust the limit. Yes, it's more work, but you're doing - // something unusual. - void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); - - // Recursion Limit ------------------------------------------------- - // To prevent corrupt or malicious messages from causing stack overflows, - // we must keep track of the depth of recursion when parsing embedded - // messages and groups. CodedInputStream keeps track of this because it - // is the only object that is passed down the stack during parsing. - - // Sets the maximum recursion depth. The default is 64. - void SetRecursionLimit(int limit); - - // Increments the current recursion depth. Returns true if the depth is - // under the limit, false if it has gone over. - bool IncrementRecursionDepth(); - - // Decrements the recursion depth. - void DecrementRecursionDepth(); - - // Extension Registry ---------------------------------------------- - // ADVANCED USAGE: 99.9% of people can ignore this section. - // - // By default, when parsing extensions, the parser looks for extension - // definitions in the pool which owns the outer message's Descriptor. - // However, you may call SetExtensionRegistry() to provide an alternative - // pool instead. This makes it possible, for example, to parse a message - // using a generated class, but represent some extensions using - // DynamicMessage. - - // Set the pool used to look up extensions. Most users do not need to call - // this as the correct pool will be chosen automatically. - // - // WARNING: It is very easy to misuse this. Carefully read the requirements - // below. Do not use this unless you are sure you need it. Almost no one - // does. - // - // Let's say you are parsing a message into message object m, and you want - // to take advantage of SetExtensionRegistry(). You must follow these - // requirements: - // - // The given DescriptorPool must contain m->GetDescriptor(). It is not - // sufficient for it to simply contain a descriptor that has the same name - // and content -- it must be the *exact object*. In other words: - // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) == - // m->GetDescriptor()); - // There are two ways to satisfy this requirement: - // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless - // because this is the pool that would be used anyway if you didn't call - // SetExtensionRegistry() at all. - // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an - // "underlay". Read the documentation for DescriptorPool for more - // information about underlays. - // - // You must also provide a MessageFactory. This factory will be used to - // construct Message objects representing extensions. The factory's - // GetPrototype() MUST return non-NULL for any Descriptor which can be found - // through the provided pool. - // - // If the provided factory might return instances of protocol-compiler- - // generated (i.e. compiled-in) types, or if the outer message object m is - // a generated type, then the given factory MUST have this property: If - // GetPrototype() is given a Descriptor which resides in - // DescriptorPool::generated_pool(), the factory MUST return the same - // prototype which MessageFactory::generated_factory() would return. That - // is, given a descriptor for a generated type, the factory must return an - // instance of the generated class (NOT DynamicMessage). However, when - // given a descriptor for a type that is NOT in generated_pool, the factory - // is free to return any implementation. - // - // The reason for this requirement is that generated sub-objects may be - // accessed via the standard (non-reflection) extension accessor methods, - // and these methods will down-cast the object to the generated class type. - // If the object is not actually of that type, the results would be undefined. - // On the other hand, if an extension is not compiled in, then there is no - // way the code could end up accessing it via the standard accessors -- the - // only way to access the extension is via reflection. When using reflection, - // DynamicMessage and generated messages are indistinguishable, so it's fine - // if these objects are represented using DynamicMessage. - // - // Using DynamicMessageFactory on which you have called - // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the - // above requirement. - // - // If either pool or factory is NULL, both must be NULL. - // - // Note that this feature is ignored when parsing "lite" messages as they do - // not have descriptors. - void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory); - - // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool - // has been provided. - const DescriptorPool* GetExtensionPool(); - - // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no - // factory has been provided. - MessageFactory* GetExtensionFactory(); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); - - ZeroCopyInputStream* input_; - const uint8* buffer_; - const uint8* buffer_end_; // pointer to the end of the buffer. - int total_bytes_read_; // total bytes read from input_, including - // the current buffer - - // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here - // so that we can BackUp() on destruction. - int overflow_bytes_; - - // LastTagWas() stuff. - uint32 last_tag_; // result of last ReadTag(). - - // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly - // at EOF, or by ExpectAtEnd() when it returns true. This happens when we - // reach the end of a message and attempt to read another tag. - bool legitimate_message_end_; - - // See EnableAliasing(). - bool aliasing_enabled_; - - // Limits - Limit current_limit_; // if position = -1, no limit is applied - - // For simplicity, if the current buffer crosses a limit (either a normal - // limit created by PushLimit() or the total bytes limit), buffer_size_ - // only tracks the number of bytes before that limit. This field - // contains the number of bytes after it. Note that this implies that if - // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've - // hit a limit. However, if both are zero, it doesn't necessarily mean - // we aren't at a limit -- the buffer may have ended exactly at the limit. - int buffer_size_after_limit_; - - // Maximum number of bytes to read, period. This is unrelated to - // current_limit_. Set using SetTotalBytesLimit(). - int total_bytes_limit_; - int total_bytes_warning_threshold_; - - // Current recursion depth, controlled by IncrementRecursionDepth() and - // DecrementRecursionDepth(). - int recursion_depth_; - // Recursion depth limit, set by SetRecursionLimit(). - int recursion_limit_; - - // See SetExtensionRegistry(). - const DescriptorPool* extension_pool_; - MessageFactory* extension_factory_; - - // Private member functions. - - // Advance the buffer by a given number of bytes. - void Advance(int amount); - - // Back up input_ to the current buffer position. - void BackUpInputToCurrentPosition(); - - // Recomputes the value of buffer_size_after_limit_. Must be called after - // current_limit_ or total_bytes_limit_ changes. - void RecomputeBufferLimits(); - - // Writes an error message saying that we hit total_bytes_limit_. - void PrintTotalBytesLimitError(); - - // Called when the buffer runs out to request more data. Implies an - // Advance(BufferSize()). - bool Refresh(); - - // When parsing varints, we optimize for the common case of small values, and - // then optimize for the case when the varint fits within the current buffer - // piece. The Fallback method is used when we can't use the one-byte - // optimization. The Slow method is yet another fallback when the buffer is - // not large enough. Making the slow path out-of-line speeds up the common - // case by 10-15%. The slow path is fairly uncommon: it only triggers when a - // message crosses multiple buffers. - bool ReadVarint32Fallback(uint32* value); - bool ReadVarint64Fallback(uint64* value); - bool ReadVarint32Slow(uint32* value); - bool ReadVarint64Slow(uint64* value); - bool ReadLittleEndian32Fallback(uint32* value); - bool ReadLittleEndian64Fallback(uint64* value); - // Fallback/slow methods for reading tags. These do not update last_tag_, - // but will set legitimate_message_end_ if we are at the end of the input - // stream. - uint32 ReadTagFallback(); - uint32 ReadTagSlow(); - bool ReadStringFallback(string* buffer, int size); - - // Return the size of the buffer. - int BufferSize() const; - - static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB - - static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB - static const int kDefaultRecursionLimit = 64; -}; - -// Class which encodes and writes binary data which is composed of varint- -// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. -// Most users will not need to deal with CodedOutputStream. -// -// Most methods of CodedOutputStream which return a bool return false if an -// underlying I/O error occurs. Once such a failure occurs, the -// CodedOutputStream is broken and is no longer useful. The Write* methods do -// not return the stream status, but will invalidate the stream if an error -// occurs. The client can probe HadError() to determine the status. -// -// Note that every method of CodedOutputStream which writes some data has -// a corresponding static "ToArray" version. These versions write directly -// to the provided buffer, returning a pointer past the last written byte. -// They require that the buffer has sufficient capacity for the encoded data. -// This allows an optimization where we check if an output stream has enough -// space for an entire message before we start writing and, if there is, we -// call only the ToArray methods to avoid doing bound checks for each -// individual value. -// i.e., in the example above: -// -// CodedOutputStream coded_output = new CodedOutputStream(raw_output); -// int magic_number = 1234; -// char text[] = "Hello world!"; -// -// int coded_size = sizeof(magic_number) + -// CodedOutputStream::Varint32Size(strlen(text)) + -// strlen(text); -// -// uint8* buffer = -// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); -// if (buffer != NULL) { -// // The output stream has enough space in the buffer: write directly to -// // the array. -// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number, -// buffer); -// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer); -// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer); -// } else { -// // Make bound-checked writes, which will ask the underlying stream for -// // more space as needed. -// coded_output->WriteLittleEndian32(magic_number); -// coded_output->WriteVarint32(strlen(text)); -// coded_output->WriteRaw(text, strlen(text)); -// } -// -// delete coded_output; -class LIBPROTOBUF_EXPORT CodedOutputStream { - public: - // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. - explicit CodedOutputStream(ZeroCopyOutputStream* output); - - // Destroy the CodedOutputStream and position the underlying - // ZeroCopyOutputStream immediately after the last byte written. - ~CodedOutputStream(); - - // Skips a number of bytes, leaving the bytes unmodified in the underlying - // buffer. Returns false if an underlying write error occurs. This is - // mainly useful with GetDirectBufferPointer(). - bool Skip(int count); - - // Sets *data to point directly at the unwritten part of the - // CodedOutputStream's underlying buffer, and *size to the size of that - // buffer, but does not advance the stream's current position. This will - // always either produce a non-empty buffer or return false. If the caller - // writes any data to this buffer, it should then call Skip() to skip over - // the consumed bytes. This may be useful for implementing external fast - // serialization routines for types of data not covered by the - // CodedOutputStream interface. - bool GetDirectBufferPointer(void** data, int* size); - - // If there are at least "size" bytes available in the current buffer, - // returns a pointer directly into the buffer and advances over these bytes. - // The caller may then write directly into this buffer (e.g. using the - // *ToArray static methods) rather than go through CodedOutputStream. If - // there are not enough bytes available, returns NULL. The return pointer is - // invalidated as soon as any other non-const method of CodedOutputStream - // is called. - inline uint8* GetDirectBufferForNBytesAndAdvance(int size); - - // Write raw bytes, copying them from the given buffer. - void WriteRaw(const void* buffer, int size); - // Like WriteRaw() but writing directly to the target array. - // This is _not_ inlined, as the compiler often optimizes memcpy into inline - // copy loops. Since this gets called by every field with string or bytes - // type, inlining may lead to a significant amount of code bloat, with only a - // minor performance gain. - static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); - - // Equivalent to WriteRaw(str.data(), str.size()). - void WriteString(const string& str); - // Like WriteString() but writing directly to the target array. - static uint8* WriteStringToArray(const string& str, uint8* target); - - - // Write a 32-bit little-endian integer. - void WriteLittleEndian32(uint32 value); - // Like WriteLittleEndian32() but writing directly to the target array. - static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); - // Write a 64-bit little-endian integer. - void WriteLittleEndian64(uint64 value); - // Like WriteLittleEndian64() but writing directly to the target array. - static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); - - // Write an unsigned integer with Varint encoding. Writing a 32-bit value - // is equivalent to casting it to uint64 and writing it as a 64-bit value, - // but may be more efficient. - void WriteVarint32(uint32 value); - // Like WriteVarint32() but writing directly to the target array. - static uint8* WriteVarint32ToArray(uint32 value, uint8* target); - // Write an unsigned integer with Varint encoding. - void WriteVarint64(uint64 value); - // Like WriteVarint64() but writing directly to the target array. - static uint8* WriteVarint64ToArray(uint64 value, uint8* target); - - // Equivalent to WriteVarint32() except when the value is negative, - // in which case it must be sign-extended to a full 10 bytes. - void WriteVarint32SignExtended(int32 value); - // Like WriteVarint32SignExtended() but writing directly to the target array. - static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); - - // This is identical to WriteVarint32(), but optimized for writing tags. - // In particular, if the input is a compile-time constant, this method - // compiles down to a couple instructions. - // Always inline because otherwise the aformentioned optimization can't work, - // but GCC by default doesn't want to inline this. - void WriteTag(uint32 value); - // Like WriteTag() but writing directly to the target array. - static uint8* WriteTagToArray( - uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Returns the number of bytes needed to encode the given value as a varint. - static int VarintSize32(uint32 value); - // Returns the number of bytes needed to encode the given value as a varint. - static int VarintSize64(uint64 value); - - // If negative, 10 bytes. Otheriwse, same as VarintSize32(). - static int VarintSize32SignExtended(int32 value); - - // Returns the total number of bytes written since this object was created. - inline int ByteCount() const; - - // Returns true if there was an underlying I/O error since this object was - // created. - bool HadError() const { return had_error_; } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); - - ZeroCopyOutputStream* output_; - uint8* buffer_; - int buffer_size_; - int total_bytes_; // Sum of sizes of all buffers seen so far. - bool had_error_; // Whether an error occurred during output. - - // Advance the buffer by a given number of bytes. - void Advance(int amount); - - // Called when the buffer runs out to request more data. Implies an - // Advance(buffer_size_). - bool Refresh(); - - static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target); - - // Always-inlined versions of WriteVarint* functions so that code can be - // reused, while still controlling size. For instance, WriteVarint32ToArray() - // should not directly call this: since it is inlined itself, doing so - // would greatly increase the size of generated code. Instead, it should call - // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already - // out-of-line, so it should just invoke this directly to avoid any extra - // function call overhead. - static uint8* WriteVarint32FallbackToArrayInline( - uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - static uint8* WriteVarint64ToArrayInline( - uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - static int VarintSize32Fallback(uint32 value); -}; - -// inline methods ==================================================== -// The vast majority of varints are only one byte. These inline -// methods optimize for that case. - -inline bool CodedInputStream::ReadVarint32(uint32* value) { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { - *value = *buffer_; - Advance(1); - return true; - } else { - return ReadVarint32Fallback(value); - } -} - -inline bool CodedInputStream::ReadVarint64(uint64* value) { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { - *value = *buffer_; - Advance(1); - return true; - } else { - return ReadVarint64Fallback(value); - } -} - -// static -inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( - const uint8* buffer, - uint32* value) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(value, buffer, sizeof(*value)); - return buffer + sizeof(*value); -#else - *value = (static_cast(buffer[0]) ) | - (static_cast(buffer[1]) << 8) | - (static_cast(buffer[2]) << 16) | - (static_cast(buffer[3]) << 24); - return buffer + sizeof(*value); -#endif -} -// static -inline const uint8* CodedInputStream::ReadLittleEndian64FromArray( - const uint8* buffer, - uint64* value) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(value, buffer, sizeof(*value)); - return buffer + sizeof(*value); -#else - uint32 part0 = (static_cast(buffer[0]) ) | - (static_cast(buffer[1]) << 8) | - (static_cast(buffer[2]) << 16) | - (static_cast(buffer[3]) << 24); - uint32 part1 = (static_cast(buffer[4]) ) | - (static_cast(buffer[5]) << 8) | - (static_cast(buffer[6]) << 16) | - (static_cast(buffer[7]) << 24); - *value = static_cast(part0) | - (static_cast(part1) << 32); - return buffer + sizeof(*value); -#endif -} - -inline bool CodedInputStream::ReadLittleEndian32(uint32* value) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) { - memcpy(value, buffer_, sizeof(*value)); - Advance(sizeof(*value)); - return true; - } else { - return ReadLittleEndian32Fallback(value); - } -#else - return ReadLittleEndian32Fallback(value); -#endif -} - -inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) { - memcpy(value, buffer_, sizeof(*value)); - Advance(sizeof(*value)); - return true; - } else { - return ReadLittleEndian64Fallback(value); - } -#else - return ReadLittleEndian64Fallback(value); -#endif -} - -inline uint32 CodedInputStream::ReadTag() { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) { - last_tag_ = buffer_[0]; - Advance(1); - return last_tag_; - } else { - last_tag_ = ReadTagFallback(); - return last_tag_; - } -} - -inline bool CodedInputStream::LastTagWas(uint32 expected) { - return last_tag_ == expected; -} - -inline bool CodedInputStream::ConsumedEntireMessage() { - return legitimate_message_end_; -} - -inline bool CodedInputStream::ExpectTag(uint32 expected) { - if (expected < (1 << 7)) { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) { - Advance(1); - return true; - } else { - return false; - } - } else if (expected < (1 << 14)) { - if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) && - buffer_[0] == static_cast(expected | 0x80) && - buffer_[1] == static_cast(expected >> 7)) { - Advance(2); - return true; - } else { - return false; - } - } else { - // Don't bother optimizing for larger values. - return false; - } -} - -inline const uint8* CodedInputStream::ExpectTagFromArray( - const uint8* buffer, uint32 expected) { - if (expected < (1 << 7)) { - if (buffer[0] == expected) { - return buffer + 1; - } - } else if (expected < (1 << 14)) { - if (buffer[0] == static_cast(expected | 0x80) && - buffer[1] == static_cast(expected >> 7)) { - return buffer + 2; - } - } - return NULL; -} - -inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, - int* size) { - *data = buffer_; - *size = buffer_end_ - buffer_; -} - -inline bool CodedInputStream::ExpectAtEnd() { - // If we are at a limit we know no more bytes can be read. Otherwise, it's - // hard to say without calling Refresh(), and we'd rather not do that. - - if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) { - last_tag_ = 0; // Pretend we called ReadTag()... - legitimate_message_end_ = true; // ... and it hit EOF. - return true; - } else { - return false; - } -} - -inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { - if (buffer_size_ < size) { - return NULL; - } else { - uint8* result = buffer_; - Advance(size); - return result; - } -} - -inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, - uint8* target) { - if (value < 0x80) { - *target = value; - return target + 1; - } else { - return WriteVarint32FallbackToArray(value, target); - } -} - -inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { - if (value < 0) { - WriteVarint64(static_cast(value)); - } else { - WriteVarint32(static_cast(value)); - } -} - -inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( - int32 value, uint8* target) { - if (value < 0) { - return WriteVarint64ToArray(static_cast(value), target); - } else { - return WriteVarint32ToArray(static_cast(value), target); - } -} - -inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, - uint8* target) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(target, &value, sizeof(value)); -#else - target[0] = static_cast(value); - target[1] = static_cast(value >> 8); - target[2] = static_cast(value >> 16); - target[3] = static_cast(value >> 24); -#endif - return target + sizeof(value); -} - -inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, - uint8* target) { -#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ - defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(target, &value, sizeof(value)); -#else - uint32 part0 = static_cast(value); - uint32 part1 = static_cast(value >> 32); - - target[0] = static_cast(part0); - target[1] = static_cast(part0 >> 8); - target[2] = static_cast(part0 >> 16); - target[3] = static_cast(part0 >> 24); - target[4] = static_cast(part1); - target[5] = static_cast(part1 >> 8); - target[6] = static_cast(part1 >> 16); - target[7] = static_cast(part1 >> 24); -#endif - return target + sizeof(value); -} - -inline void CodedOutputStream::WriteTag(uint32 value) { - WriteVarint32(value); -} - -inline uint8* CodedOutputStream::WriteTagToArray( - uint32 value, uint8* target) { - if (value < (1 << 7)) { - target[0] = value; - return target + 1; - } else if (value < (1 << 14)) { - target[0] = static_cast(value | 0x80); - target[1] = static_cast(value >> 7); - return target + 2; - } else { - return WriteVarint32FallbackToArray(value, target); - } -} - -inline int CodedOutputStream::VarintSize32(uint32 value) { - if (value < (1 << 7)) { - return 1; - } else { - return VarintSize32Fallback(value); - } -} - -inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { - if (value < 0) { - return 10; // TODO(kenton): Make this a symbolic constant. - } else { - return VarintSize32(static_cast(value)); - } -} - -inline void CodedOutputStream::WriteString(const string& str) { - WriteRaw(str.data(), str.size()); -} - -inline uint8* CodedOutputStream::WriteStringToArray( - const string& str, uint8* target) { - return WriteRawToArray(str.data(), str.size(), target); -} - -inline int CodedOutputStream::ByteCount() const { - return total_bytes_ - buffer_size_; -} - -inline void CodedInputStream::Advance(int amount) { - buffer_ += amount; -} - -inline void CodedOutputStream::Advance(int amount) { - buffer_ += amount; - buffer_size_ -= amount; -} - -inline void CodedInputStream::SetRecursionLimit(int limit) { - recursion_limit_ = limit; -} - -inline bool CodedInputStream::IncrementRecursionDepth() { - ++recursion_depth_; - return recursion_depth_ <= recursion_limit_; -} - -inline void CodedInputStream::DecrementRecursionDepth() { - if (recursion_depth_ > 0) --recursion_depth_; -} - -inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool, - MessageFactory* factory) { - extension_pool_ = pool; - extension_factory_ = factory; -} - -inline const DescriptorPool* CodedInputStream::GetExtensionPool() { - return extension_pool_; -} - -inline MessageFactory* CodedInputStream::GetExtensionFactory() { - return extension_factory_; -} - -inline int CodedInputStream::BufferSize() const { - return buffer_end_ - buffer_; -} - -inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) - : input_(input), - buffer_(NULL), - buffer_end_(NULL), - total_bytes_read_(0), - overflow_bytes_(0), - last_tag_(0), - legitimate_message_end_(false), - aliasing_enabled_(false), - current_limit_(INT_MAX), - buffer_size_after_limit_(0), - total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), - recursion_depth_(0), - recursion_limit_(kDefaultRecursionLimit), - extension_pool_(NULL), - extension_factory_(NULL) { - // Eagerly Refresh() so buffer space is immediately available. - Refresh(); -} - -inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) - : input_(NULL), - buffer_(buffer), - buffer_end_(buffer + size), - total_bytes_read_(size), - overflow_bytes_(0), - last_tag_(0), - legitimate_message_end_(false), - aliasing_enabled_(false), - current_limit_(size), - buffer_size_after_limit_(0), - total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), - recursion_depth_(0), - recursion_limit_(kDefaultRecursionLimit), - extension_pool_(NULL), - extension_factory_(NULL) { - // Note that setting current_limit_ == size is important to prevent some - // code paths from trying to access input_ and segfaulting. -} - -inline CodedInputStream::~CodedInputStream() { - if (input_ != NULL) { - BackUpInputToCurrentPosition(); - } -} - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ diff --git a/Resources/NetHook/google/protobuf/io/coded_stream_inl.h b/Resources/NetHook/google/protobuf/io/coded_stream_inl.h deleted file mode 100644 index e9799d47..00000000 --- a/Resources/NetHook/google/protobuf/io/coded_stream_inl.h +++ /dev/null @@ -1,64 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: jasonh@google.com (Jason Hsueh) -// -// Implements methods of coded_stream.h that need to be inlined for performance -// reasons, but should not be defined in a public header. - -#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ -#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -inline bool CodedInputStream::InternalReadStringInline(string* buffer, - int size) { - if (size < 0) return false; // security: size is often user-supplied - - if (BufferSize() >= size) { - STLStringResizeUninitialized(buffer, size); - memcpy(string_as_array(buffer), buffer_, size); - Advance(size); - return true; - } - - return ReadStringFallback(buffer, size); -} - -} // namespace io -} // namespace protobuf -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ diff --git a/Resources/NetHook/google/protobuf/io/coded_stream_unittest.cc b/Resources/NetHook/google/protobuf/io/coded_stream_unittest.cc deleted file mode 100644 index 7d298332..00000000 --- a/Resources/NetHook/google/protobuf/io/coded_stream_unittest.cc +++ /dev/null @@ -1,1103 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains tests and benchmarks. - -#include - -#include - -#include - -#include -#include -#include -#include -#include - - -// This declares an unsigned long long integer literal in a portable way. -// (The original macro is way too big and ruins my formatting.) -#undef ULL -#define ULL(x) GOOGLE_ULONGLONG(x) - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// =================================================================== -// Data-Driven Test Infrastructure - -// TEST_1D and TEST_2D are macros I'd eventually like to see added to -// gTest. These macros can be used to declare tests which should be -// run multiple times, once for each item in some input array. TEST_1D -// tests all cases in a single input array. TEST_2D tests all -// combinations of cases from two arrays. The arrays must be statically -// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: -// -// int kCases[] = {1, 2, 3, 4} -// TEST_1D(MyFixture, MyTest, kCases) { -// EXPECT_GT(kCases_case, 0); -// } -// -// This test iterates through the numbers 1, 2, 3, and 4 and tests that -// they are all grater than zero. In case of failure, the exact case -// which failed will be printed. The case type must be printable using -// ostream::operator<<. - -// TODO(kenton): gTest now supports "parameterized tests" which would be -// a better way to accomplish this. Rewrite when time permits. - -#define TEST_1D(FIXTURE, NAME, CASES) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template \ - void DoSingleCase(const CaseType& CASES##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES " case #" << i << ": " << CASES[i]); \ - DoSingleCase(CASES[i]); \ - } \ - } \ - \ - template \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) - -#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template \ - void DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ - for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ - << #CASES2 " case #" << j << ": " << CASES2[j]); \ - DoSingleCase(CASES1[i], CASES2[j]); \ - } \ - } \ - } \ - \ - template \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case) - -// =================================================================== - -class CodedStreamTest : public testing::Test { - protected: - static const int kBufferSize = 1024 * 64; - static uint8 buffer_[kBufferSize]; -}; - -uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize]; - -// We test each operation over a variety of block sizes to insure that -// we test cases where reads or writes cross buffer boundaries, cases -// where they don't, and cases where there is so much buffer left that -// we can use special optimized paths that don't worry about bounds -// checks. -const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; - -// ------------------------------------------------------------------- -// Varint tests. - -struct VarintCase { - uint8 bytes[10]; // Encoded bytes. - int size; // Encoded size, in bytes. - uint64 value; // Parsed value. -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) { - return os << c.value; -} - -VarintCase kVarintCases[] = { - // 32-bit values - {{0x00} , 1, 0}, - {{0x01} , 1, 1}, - {{0x7f} , 1, 127}, - {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882 - {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5, // 2961488830 - (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | - (ULL(0x0b) << 28)}, - - // 64-bit - {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5, // 7256456126 - (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | - (ULL(0x1b) << 28)}, - {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8, // 41256202580718336 - (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | - (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) | - (ULL(0x49) << 49)}, - // 11964378330978735131 - {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10, - (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | - (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) | - (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)}, -}; - -TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_TRUE(coded_input.ReadVarint32(&value)); - EXPECT_EQ(static_cast(kVarintCases_case.value), value); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 expected_value = static_cast(kVarintCases_case.value); - EXPECT_EQ(expected_value, coded_input.ReadTag()); - - EXPECT_TRUE(coded_input.LastTagWas(expected_value)); - EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1)); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { - // Leave one byte at the beginning of the buffer so we can read it - // to force the first buffer to be loaded. - buffer_[0] = '\0'; - memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_)); - - { - CodedInputStream coded_input(&input); - - // Read one byte to force coded_input.Refill() to be called. Otherwise, - // ExpectTag() will return a false negative. - uint8 dummy; - coded_input.ReadRaw(&dummy, 1); - EXPECT_EQ((uint)'\0', (uint)dummy); - - uint32 expected_value = static_cast(kVarintCases_case.value); - - // ExpectTag() produces false negatives for large values. - if (kVarintCases_case.size <= 2) { - EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1)); - EXPECT_TRUE(coded_input.ExpectTag(expected_value)); - } else { - EXPECT_FALSE(coded_input.ExpectTag(expected_value)); - } - } - - if (kVarintCases_case.size <= 2) { - EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount()); - } else { - EXPECT_EQ(1, input.ByteCount()); - } -} - -TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - - const uint32 expected_value = static_cast(kVarintCases_case.value); - - // If the expectation succeeds, it should return a pointer past the tag. - if (kVarintCases_case.size <= 2) { - EXPECT_TRUE(NULL == - CodedInputStream::ExpectTagFromArray(buffer_, - expected_value + 1)); - EXPECT_TRUE(buffer_ + kVarintCases_case.size == - CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); - } else { - EXPECT_TRUE(NULL == - CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); - } -} - -TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadVarint64(&value)); - EXPECT_EQ(kVarintCases_case.value, value); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) { - if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) { - // Skip this test for the 64-bit values. - return; - } - - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteVarint32(static_cast(kVarintCases_case.value)); - EXPECT_FALSE(coded_output.HadError()); - - EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); - } - - EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); - EXPECT_EQ(0, - memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); -} - -TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteVarint64(kVarintCases_case.value); - EXPECT_FALSE(coded_output.HadError()); - - EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); - } - - EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); - EXPECT_EQ(0, - memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); -} - -// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -int32 kSignExtendedVarintCases[] = { - 0, 1, -1, 1237894, -37895138 -}; - -TEST_2D(CodedStreamTest, WriteVarint32SignExtended, - kSignExtendedVarintCases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case); - EXPECT_FALSE(coded_output.HadError()); - - if (kSignExtendedVarintCases_case < 0) { - EXPECT_EQ(10, coded_output.ByteCount()); - } else { - EXPECT_LE(coded_output.ByteCount(), 5); - } - } - - if (kSignExtendedVarintCases_case < 0) { - EXPECT_EQ(10, output.ByteCount()); - } else { - EXPECT_LE(output.ByteCount(), 5); - } - - // Read value back in as a varint64 and insure it matches. - ArrayInputStream input(buffer_, sizeof(buffer_)); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadVarint64(&value)); - - EXPECT_EQ(kSignExtendedVarintCases_case, static_cast(value)); - } - - EXPECT_EQ(output.ByteCount(), input.ByteCount()); -} - -#endif - - -// ------------------------------------------------------------------- -// Varint failure test. - -struct VarintErrorCase { - uint8 bytes[12]; - int size; - bool can_parse; -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) { - return os << "size " << c.size; -} - -const VarintErrorCase kVarintErrorCases[] = { - // Control case. (Insures that there isn't something else wrong that - // makes parsing always fail.) - {{0x00}, 1, true}, - - // No input data. - {{}, 0, false}, - - // Input ends unexpectedly. - {{0xf0, 0xab}, 2, false}, - - // Input ends unexpectedly after 32 bits. - {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false}, - - // Longer than 10 bytes. - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, - 11, false}, -}; - -TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) { - memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); - ArrayInputStream input(buffer_, kVarintErrorCases_case.size, - kBlockSizes_case); - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); -} - -TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) { - memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); - ArrayInputStream input(buffer_, kVarintErrorCases_case.size, - kBlockSizes_case); - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); -} - -// ------------------------------------------------------------------- -// VarintSize - -struct VarintSizeCase { - uint64 value; - int size; -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) { - return os << c.value; -} - -VarintSizeCase kVarintSizeCases[] = { - {0u, 1}, - {1u, 1}, - {127u, 1}, - {128u, 2}, - {758923u, 3}, - {4000000000u, 5}, - {ULL(41256202580718336), 8}, - {ULL(11964378330978735131), 10}, -}; - -TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) { - if (kVarintSizeCases_case.value > 0xffffffffu) { - // Skip 64-bit values. - return; - } - - EXPECT_EQ(kVarintSizeCases_case.size, - CodedOutputStream::VarintSize32( - static_cast(kVarintSizeCases_case.value))); -} - -TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) { - EXPECT_EQ(kVarintSizeCases_case.size, - CodedOutputStream::VarintSize64(kVarintSizeCases_case.value)); -} - -// ------------------------------------------------------------------- -// Fixed-size int tests - -struct Fixed32Case { - uint8 bytes[sizeof(uint32)]; // Encoded bytes. - uint32 value; // Parsed value. -}; - -struct Fixed64Case { - uint8 bytes[sizeof(uint64)]; // Encoded bytes. - uint64 value; // Parsed value. -}; - -inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) { - return os << "0x" << hex << c.value << dec; -} - -inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) { - return os << "0x" << hex << c.value << dec; -} - -Fixed32Case kFixed32Cases[] = { - {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu}, - {{0x12, 0x34, 0x56, 0x78}, 0x78563412u}, -}; - -Fixed64Case kFixed64Cases[] = { - {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)}, - {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)}, -}; - -TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) { - memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(kFixed32Cases_case.value, value); - } - - EXPECT_EQ(sizeof(uint32), input.ByteCount()); -} - -TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) { - memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadLittleEndian64(&value)); - EXPECT_EQ(kFixed64Cases_case.value, value); - } - - EXPECT_EQ(sizeof(uint64), input.ByteCount()); -} - -TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteLittleEndian32(kFixed32Cases_case.value); - EXPECT_FALSE(coded_output.HadError()); - - EXPECT_EQ(sizeof(uint32), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(uint32), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32))); -} - -TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteLittleEndian64(kFixed64Cases_case.value); - EXPECT_FALSE(coded_output.HadError()); - - EXPECT_EQ(sizeof(uint64), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(uint64), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64))); -} - -// Tests using the static methods to read fixed-size values from raw arrays. - -TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) { - memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); - - uint32 value; - const uint8* end = CodedInputStream::ReadLittleEndian32FromArray( - buffer_, &value); - EXPECT_EQ(kFixed32Cases_case.value, value); - EXPECT_TRUE(end == buffer_ + sizeof(value)); -} - -TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) { - memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); - - uint64 value; - const uint8* end = CodedInputStream::ReadLittleEndian64FromArray( - buffer_, &value); - EXPECT_EQ(kFixed64Cases_case.value, value); - EXPECT_TRUE(end == buffer_ + sizeof(value)); -} - -// ------------------------------------------------------------------- -// Raw reads and writes - -const char kRawBytes[] = "Some bytes which will be written and read raw."; - -TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) { - memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - char read_buffer[sizeof(kRawBytes)]; - - { - CodedInputStream coded_input(&input); - - EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes))); - EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes))); - } - - EXPECT_EQ(sizeof(kRawBytes), input.ByteCount()); -} - -TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes)); - EXPECT_FALSE(coded_output.HadError()); - - EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(kRawBytes), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes))); -} - -TEST_1D(CodedStreamTest, ReadString, kBlockSizes) { - memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes))); - EXPECT_EQ(kRawBytes, str); - } - - EXPECT_EQ(strlen(kRawBytes), input.ByteCount()); -} - -// Check to make sure ReadString doesn't crash on impossibly large strings. -TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - // Try to read a gigabyte. - EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); - } -} - -TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) { - // Same test as above, except directly use a buffer. This used to cause - // crashes while the above did not. - uint8 buffer[8]; - CodedInputStream coded_input(buffer, 8); - string str; - EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); -} - -TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) { - scoped_array buffer(new uint8[8]); - CodedInputStream coded_input(buffer.get(), 8); - string str; - EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); -} - - -// ------------------------------------------------------------------- -// Skip - -const char kSkipTestBytes[] = - ""; -const char kSkipOutputTestBytes[] = - "---------------------------------"; - -TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) { - memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, strlen(""))); - EXPECT_EQ("", str); - EXPECT_TRUE(coded_input.Skip(strlen(""))); - EXPECT_TRUE(coded_input.ReadString(&str, strlen(""))); - EXPECT_EQ("", str); - } - - EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount()); -} - -// ------------------------------------------------------------------- -// GetDirectBufferPointer - -TEST_F(CodedStreamTest, GetDirectBufferPointerInput) { - ArrayInputStream input(buffer_, sizeof(buffer_), 8); - CodedInputStream coded_input(&input); - - const void* ptr; - int size; - - EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Peeking again should return the same pointer. - EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Skip forward in the same buffer then peek again. - EXPECT_TRUE(coded_input.Skip(3)); - EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_ + 3, ptr); - EXPECT_EQ(5, size); - - // Skip to end of buffer and peek -- should get next buffer. - EXPECT_TRUE(coded_input.Skip(5)); - EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_ + 8, ptr); - EXPECT_EQ(8, size); -} - -TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) { - ArrayInputStream input(buffer_, sizeof(buffer_), 8); - CodedInputStream coded_input(&input); - - const void* ptr; - int size; - - coded_input.GetDirectBufferPointerInline(&ptr, &size); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Peeking again should return the same pointer. - coded_input.GetDirectBufferPointerInline(&ptr, &size); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Skip forward in the same buffer then peek again. - EXPECT_TRUE(coded_input.Skip(3)); - coded_input.GetDirectBufferPointerInline(&ptr, &size); - EXPECT_EQ(buffer_ + 3, ptr); - EXPECT_EQ(5, size); - - // Skip to end of buffer and peek -- should return false and provide an empty - // buffer. It does not try to Refresh(). - EXPECT_TRUE(coded_input.Skip(5)); - coded_input.GetDirectBufferPointerInline(&ptr, &size); - EXPECT_EQ(buffer_ + 8, ptr); - EXPECT_EQ(0, size); -} - -TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) { - ArrayOutputStream output(buffer_, sizeof(buffer_), 8); - CodedOutputStream coded_output(&output); - - void* ptr; - int size; - - EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Peeking again should return the same pointer. - EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_, ptr); - EXPECT_EQ(8, size); - - // Skip forward in the same buffer then peek again. - EXPECT_TRUE(coded_output.Skip(3)); - EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_ + 3, ptr); - EXPECT_EQ(5, size); - - // Skip to end of buffer and peek -- should get next buffer. - EXPECT_TRUE(coded_output.Skip(5)); - EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_ + 8, ptr); - EXPECT_EQ(8, size); - - // Skip over multiple buffers. - EXPECT_TRUE(coded_output.Skip(22)); - EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); - EXPECT_EQ(buffer_ + 30, ptr); - EXPECT_EQ(2, size); -} - -// ------------------------------------------------------------------- -// Limits - -TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit = coded_input.PushLimit(8); - - // Read until we hit the limit. - uint32 value; - EXPECT_EQ(8, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(12, input.ByteCount()); -} - -// Test what happens when we push two limits where the second (top) one is -// shorter. -TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit1 = coded_input.PushLimit(8); - EXPECT_EQ(8, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit2 = coded_input.PushLimit(4); - - uint32 value; - - // Read until we hit limit2, the top and shortest limit. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit2); - - // Read until we hit limit1. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit1); - - // No more limits. - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(12, input.ByteCount()); -} - -// Test what happens when we push two limits where the second (top) one is -// longer. In this case, the top limit is shortened to match the previous -// limit. -TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit1 = coded_input.PushLimit(4); - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit2 = coded_input.PushLimit(8); - - uint32 value; - - // Read until we hit limit2. Except, wait! limit1 is shorter, so - // we end up hitting that first, despite having 4 bytes to go on - // limit2. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit2); - - // OK, popped limit2, now limit1 is on top, which we've already hit. - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit1); - - // No more limits. - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(8, input.ByteCount()); -} - -TEST_F(CodedStreamTest, ExpectAtEnd) { - // Test ExpectAtEnd(), which is based on limits. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - EXPECT_FALSE(coded_input.ExpectAtEnd()); - - CodedInputStream::Limit limit = coded_input.PushLimit(4); - - uint32 value; - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_TRUE(coded_input.ExpectAtEnd()); - - coded_input.PopLimit(limit); - EXPECT_FALSE(coded_input.ExpectAtEnd()); -} - -TEST_F(CodedStreamTest, NegativeLimit) { - // Check what happens when we push a negative limit. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - CodedInputStream::Limit limit = coded_input.PushLimit(-1234); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, NegativeLimitAfterReading) { - // Check what happens when we push a negative limit. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - ASSERT_TRUE(coded_input.Skip(128)); - - CodedInputStream::Limit limit = coded_input.PushLimit(-64); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, OverflowLimit) { - // Check what happens when we push a limit large enough that its absolute - // position is more than 2GB into the stream. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - ASSERT_TRUE(coded_input.Skip(128)); - - CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, TotalBytesLimit) { - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - coded_input.SetTotalBytesLimit(16, -1); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 16)); - - vector errors; - - { - ScopedMemoryLog error_log; - EXPECT_FALSE(coded_input.ReadString(&str, 1)); - errors = error_log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "A protocol message was rejected because it was too big", errors[0]); - - coded_input.SetTotalBytesLimit(32, -1); - EXPECT_TRUE(coded_input.ReadString(&str, 16)); -} - -TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) { - // total_bytes_limit_ is not a valid place for a message to end. - - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - // Set both total_bytes_limit and a regular limit at 16 bytes. - coded_input.SetTotalBytesLimit(16, -1); - CodedInputStream::Limit limit = coded_input.PushLimit(16); - - // Read 16 bytes. - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 16)); - - // Read a tag. Should fail, but report being a valid endpoint since it's - // a regular limit. - EXPECT_EQ(0, coded_input.ReadTag()); - EXPECT_TRUE(coded_input.ConsumedEntireMessage()); - - // Pop the limit. - coded_input.PopLimit(limit); - - // Read a tag. Should fail, and report *not* being a valid endpoint, since - // this time we're hitting the total bytes limit. - EXPECT_EQ(0, coded_input.ReadTag()); - EXPECT_FALSE(coded_input.ConsumedEntireMessage()); -} - -TEST_F(CodedStreamTest, RecursionLimit) { - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - coded_input.SetRecursionLimit(4); - - // This is way too much testing for a counter. - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 - coded_input.DecrementRecursionDepth(); // 5 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 - coded_input.DecrementRecursionDepth(); // 5 - coded_input.DecrementRecursionDepth(); // 4 - coded_input.DecrementRecursionDepth(); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - coded_input.DecrementRecursionDepth(); // 4 - coded_input.DecrementRecursionDepth(); // 3 - coded_input.DecrementRecursionDepth(); // 2 - coded_input.DecrementRecursionDepth(); // 1 - coded_input.DecrementRecursionDepth(); // 0 - coded_input.DecrementRecursionDepth(); // 0 - coded_input.DecrementRecursionDepth(); // 0 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - - coded_input.SetRecursionLimit(6); - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7 -} - -class ReallyBigInputStream : public ZeroCopyInputStream { - public: - ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {} - ~ReallyBigInputStream() {} - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size) { - // We only expect BackUp() to be called at the end. - EXPECT_EQ(0, backup_amount_); - - switch (buffer_count_++) { - case 0: - *data = buffer_; - *size = sizeof(buffer_); - return true; - case 1: - // Return an enormously large buffer that, when combined with the 1k - // returned already, should overflow the total_bytes_read_ counter in - // CodedInputStream. Note that we'll only read the first 1024 bytes - // of this buffer so it's OK that we have it point at buffer_. - *data = buffer_; - *size = INT_MAX; - return true; - default: - return false; - } - } - - void BackUp(int count) { - backup_amount_ = count; - } - - bool Skip(int count) { GOOGLE_LOG(FATAL) << "Not implemented."; return false; } - int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; } - - int backup_amount_; - - private: - char buffer_[1024]; - int64 buffer_count_; -}; - -TEST_F(CodedStreamTest, InputOver2G) { - // CodedInputStream should gracefully handle input over 2G and call - // input.BackUp() with the correct number of bytes on destruction. - ReallyBigInputStream input; - - vector errors; - - { - ScopedMemoryLog error_log; - CodedInputStream coded_input(&input); - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 512)); - EXPECT_TRUE(coded_input.ReadString(&str, 1024)); - errors = error_log.GetMessages(ERROR); - } - - EXPECT_EQ(INT_MAX - 512, input.backup_amount_); - EXPECT_EQ(0, errors.size()); -} - -// =================================================================== - - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/gzip_stream.cc b/Resources/NetHook/google/protobuf/io/gzip_stream.cc deleted file mode 100644 index 84d277f4..00000000 --- a/Resources/NetHook/google/protobuf/io/gzip_stream.cc +++ /dev/null @@ -1,320 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: brianolson@google.com (Brian Olson) -// -// This file contains the implementation of classes GzipInputStream and -// GzipOutputStream. - -#include "config.h" - -#if HAVE_ZLIB -#include - -#include - -namespace google { -namespace protobuf { -namespace io { - -static const int kDefaultBufferSize = 65536; - -GzipInputStream::GzipInputStream( - ZeroCopyInputStream* sub_stream, Format format, int buffer_size) - : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) { - zcontext_.zalloc = Z_NULL; - zcontext_.zfree = Z_NULL; - zcontext_.opaque = Z_NULL; - zcontext_.total_out = 0; - zcontext_.next_in = NULL; - zcontext_.avail_in = 0; - zcontext_.total_in = 0; - zcontext_.msg = NULL; - if (buffer_size == -1) { - output_buffer_length_ = kDefaultBufferSize; - } else { - output_buffer_length_ = buffer_size; - } - output_buffer_ = operator new(output_buffer_length_); - GOOGLE_CHECK(output_buffer_ != NULL); - zcontext_.next_out = static_cast(output_buffer_); - zcontext_.avail_out = output_buffer_length_; - output_position_ = output_buffer_; -} -GzipInputStream::~GzipInputStream() { - operator delete(output_buffer_); - zerror_ = inflateEnd(&zcontext_); -} - -int GzipInputStream::Inflate(int flush) { - if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) { - // previous inflate filled output buffer. don't change input params yet. - } else if (zcontext_.avail_in == 0) { - const void* in; - int in_size; - bool first = zcontext_.next_in == NULL; - bool ok = sub_stream_->Next(&in, &in_size); - if (!ok) { - zcontext_.next_out = NULL; - zcontext_.avail_out = 0; - return Z_STREAM_END; - } - zcontext_.next_in = static_cast(const_cast(in)); - zcontext_.avail_in = in_size; - if (first) { - int windowBitsFormat = 0; - switch (format_) { - case GZIP: windowBitsFormat = 16; break; - case AUTO: windowBitsFormat = 32; break; - case ZLIB: windowBitsFormat = 0; break; - } - int error = inflateInit2(&zcontext_, - /* windowBits */15 | windowBitsFormat); - if (error != Z_OK) { - return error; - } - } - } - zcontext_.next_out = static_cast(output_buffer_); - zcontext_.avail_out = output_buffer_length_; - output_position_ = output_buffer_; - int error = inflate(&zcontext_, flush); - return error; -} - -void GzipInputStream::DoNextOutput(const void** data, int* size) { - *data = output_position_; - *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_); - output_position_ = zcontext_.next_out; -} - -// implements ZeroCopyInputStream ---------------------------------- -bool GzipInputStream::Next(const void** data, int* size) { - bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) - || (zerror_ == Z_BUF_ERROR); - if ((!ok) || (zcontext_.next_out == NULL)) { - return false; - } - if (zcontext_.next_out != output_position_) { - DoNextOutput(data, size); - return true; - } - if (zerror_ == Z_STREAM_END) { - *data = NULL; - *size = 0; - return false; - } - zerror_ = Inflate(Z_NO_FLUSH); - if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) { - // The underlying stream's Next returned false inside Inflate. - return false; - } - ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) - || (zerror_ == Z_BUF_ERROR); - if (!ok) { - return false; - } - DoNextOutput(data, size); - return true; -} -void GzipInputStream::BackUp(int count) { - output_position_ = reinterpret_cast( - reinterpret_cast(output_position_) - count); -} -bool GzipInputStream::Skip(int count) { - const void* data; - int size; - bool ok = Next(&data, &size); - while (ok && (size < count)) { - count -= size; - ok = Next(&data, &size); - } - if (size > count) { - BackUp(size - count); - } - return ok; -} -int64 GzipInputStream::ByteCount() const { - return zcontext_.total_out + - (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_)); -} - -// ========================================================================= - -GzipOutputStream::Options::Options() - : format(GZIP), - buffer_size(kDefaultBufferSize), - compression_level(Z_DEFAULT_COMPRESSION), - compression_strategy(Z_DEFAULT_STRATEGY) {} - -GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) { - Init(sub_stream, Options()); -} - -GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream, - const Options& options) { - Init(sub_stream, options); -} - -GzipOutputStream::GzipOutputStream( - ZeroCopyOutputStream* sub_stream, Format format, int buffer_size) { - Options options; - options.format = format; - if (buffer_size != -1) { - options.buffer_size = buffer_size; - } - Init(sub_stream, options); -} - -void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream, - const Options& options) { - sub_stream_ = sub_stream; - sub_data_ = NULL; - sub_data_size_ = 0; - - input_buffer_length_ = options.buffer_size; - input_buffer_ = operator new(input_buffer_length_); - GOOGLE_CHECK(input_buffer_ != NULL); - - zcontext_.zalloc = Z_NULL; - zcontext_.zfree = Z_NULL; - zcontext_.opaque = Z_NULL; - zcontext_.next_out = NULL; - zcontext_.avail_out = 0; - zcontext_.total_out = 0; - zcontext_.next_in = NULL; - zcontext_.avail_in = 0; - zcontext_.total_in = 0; - zcontext_.msg = NULL; - // default to GZIP format - int windowBitsFormat = 16; - if (options.format == ZLIB) { - windowBitsFormat = 0; - } - zerror_ = deflateInit2( - &zcontext_, - options.compression_level, - Z_DEFLATED, - /* windowBits */15 | windowBitsFormat, - /* memLevel (default) */8, - options.compression_strategy); -} - -GzipOutputStream::~GzipOutputStream() { - Close(); - if (input_buffer_ != NULL) { - operator delete(input_buffer_); - } -} - -// private -int GzipOutputStream::Deflate(int flush) { - int error = Z_OK; - do { - if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) { - bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_); - if (!ok) { - sub_data_ = NULL; - sub_data_size_ = 0; - return Z_BUF_ERROR; - } - GOOGLE_CHECK_GT(sub_data_size_, 0); - zcontext_.next_out = static_cast(sub_data_); - zcontext_.avail_out = sub_data_size_; - } - error = deflate(&zcontext_, flush); - } while (error == Z_OK && zcontext_.avail_out == 0); - if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) - && (zcontext_.avail_out != sub_data_size_)) { - // Notify lower layer of data. - sub_stream_->BackUp(zcontext_.avail_out); - // We don't own the buffer anymore. - sub_data_ = NULL; - sub_data_size_ = 0; - } - return error; -} - -// implements ZeroCopyOutputStream --------------------------------- -bool GzipOutputStream::Next(void** data, int* size) { - if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { - return false; - } - if (zcontext_.avail_in != 0) { - zerror_ = Deflate(Z_NO_FLUSH); - if (zerror_ != Z_OK) { - return false; - } - } - if (zcontext_.avail_in == 0) { - // all input was consumed. reset the buffer. - zcontext_.next_in = static_cast(input_buffer_); - zcontext_.avail_in = input_buffer_length_; - *data = input_buffer_; - *size = input_buffer_length_; - } else { - // The loop in Deflate should consume all avail_in - GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed"; - } - return true; -} -void GzipOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(zcontext_.avail_in, count); - zcontext_.avail_in -= count; -} -int64 GzipOutputStream::ByteCount() const { - return zcontext_.total_in + zcontext_.avail_in; -} - -bool GzipOutputStream::Flush() { - do { - zerror_ = Deflate(Z_FULL_FLUSH); - } while (zerror_ == Z_OK); - return zerror_ == Z_OK; -} - -bool GzipOutputStream::Close() { - if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { - return false; - } - do { - zerror_ = Deflate(Z_FINISH); - } while (zerror_ == Z_OK); - zerror_ = deflateEnd(&zcontext_); - bool ok = zerror_ == Z_OK; - zerror_ = Z_STREAM_END; - return ok; -} - -} // namespace io -} // namespace protobuf -} // namespace google - -#endif // HAVE_ZLIB diff --git a/Resources/NetHook/google/protobuf/io/gzip_stream.h b/Resources/NetHook/google/protobuf/io/gzip_stream.h deleted file mode 100644 index 65dbc5b5..00000000 --- a/Resources/NetHook/google/protobuf/io/gzip_stream.h +++ /dev/null @@ -1,207 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: brianolson@google.com (Brian Olson) -// -// This file contains the definition for classes GzipInputStream and -// GzipOutputStream. -// -// GzipInputStream decompresses data from an underlying -// ZeroCopyInputStream and provides the decompressed data as a -// ZeroCopyInputStream. -// -// GzipOutputStream is an ZeroCopyOutputStream that compresses data to -// an underlying ZeroCopyOutputStream. - -#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ -#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ - -#include - -#include - -namespace google { -namespace protobuf { -namespace io { - -// A ZeroCopyInputStream that reads compressed data through zlib -class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream { - public: - // Format key for constructor - enum Format { - // zlib will autodetect gzip header or deflate stream - AUTO = 0, - - // GZIP streams have some extra header data for file attributes. - GZIP = 1, - - // Simpler zlib stream format. - ZLIB = 2, - }; - - // buffer_size and format may be -1 for default of 64kB and GZIP format - explicit GzipInputStream( - ZeroCopyInputStream* sub_stream, - Format format = AUTO, - int buffer_size = -1); - virtual ~GzipInputStream(); - - // Return last error message or NULL if no error. - inline const char* ZlibErrorMessage() const { - return zcontext_.msg; - } - inline int ZlibErrorCode() const { - return zerror_; - } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - Format format_; - - ZeroCopyInputStream* sub_stream_; - - z_stream zcontext_; - int zerror_; - - void* output_buffer_; - void* output_position_; - size_t output_buffer_length_; - - int Inflate(int flush); - void DoNextOutput(const void** data, int* size); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream); -}; - - -class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { - public: - // Format key for constructor - enum Format { - // GZIP streams have some extra header data for file attributes. - GZIP = 1, - - // Simpler zlib stream format. - ZLIB = 2, - }; - - struct Options { - // Defaults to GZIP. - Format format; - - // What size buffer to use internally. Defaults to 64kB. - int buffer_size; - - // A number between 0 and 9, where 0 is no compression and 9 is best - // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h). - int compression_level; - - // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED, - // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in - // zlib.h for definitions of these constants. - int compression_strategy; - - Options(); // Initializes with default values. - }; - - // Create a GzipOutputStream with default options. - explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream); - - // Create a GzipOutputStream with the given options. - GzipOutputStream( - ZeroCopyOutputStream* sub_stream, - const Options& options); - - // DEPRECATED: Use one of the above constructors instead. - GzipOutputStream( - ZeroCopyOutputStream* sub_stream, - Format format, - int buffer_size = -1) GOOGLE_ATTRIBUTE_DEPRECATED; - - virtual ~GzipOutputStream(); - - // Return last error message or NULL if no error. - inline const char* ZlibErrorMessage() const { - return zcontext_.msg; - } - inline int ZlibErrorCode() const { - return zerror_; - } - - // Flushes data written so far to zipped data in the underlying stream. - // It is the caller's responsibility to flush the underlying stream if - // necessary. - // Compression may be less efficient stopping and starting around flushes. - // Returns true if no error. - bool Flush(); - - // Writes out all data and closes the gzip stream. - // It is the caller's responsibility to close the underlying stream if - // necessary. - // Returns true if no error. - bool Close(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - ZeroCopyOutputStream* sub_stream_; - // Result from calling Next() on sub_stream_ - void* sub_data_; - int sub_data_size_; - - z_stream zcontext_; - int zerror_; - void* input_buffer_; - size_t input_buffer_length_; - - // Shared constructor code. - void Init(ZeroCopyOutputStream* sub_stream, const Options& options); - - // Do some compression. - // Takes zlib flush mode. - // Returns zlib error code. - int Deflate(int flush); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream); -}; - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ diff --git a/Resources/NetHook/google/protobuf/io/gzip_stream_unittest.sh b/Resources/NetHook/google/protobuf/io/gzip_stream_unittest.sh deleted file mode 100644 index 6e8a0943..00000000 --- a/Resources/NetHook/google/protobuf/io/gzip_stream_unittest.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh -x -# -# Protocol Buffers - Google's data interchange format -# Copyright 2009 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Author: brianolson@google.com (Brian Olson) -# -# Test compatibility between command line gzip/gunzip binaries and -# ZeroCopyStream versions. - -TESTFILE=Makefile - -(./zcgzip < ${TESTFILE} | gunzip | cmp - ${TESTFILE}) && \ -(gzip < ${TESTFILE} | ./zcgunzip | cmp - ${TESTFILE}) - -# Result of "(cmd) && (cmd)" implicitly becomes result of this script -# and thus the test. diff --git a/Resources/NetHook/google/protobuf/io/package_info.h b/Resources/NetHook/google/protobuf/io/package_info.h deleted file mode 100644 index 7a7a4e77..00000000 --- a/Resources/NetHook/google/protobuf/io/package_info.h +++ /dev/null @@ -1,54 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file exists solely to document the google::protobuf::io namespace. -// It is not compiled into anything, but it may be read by an automated -// documentation generator. - -namespace google { - -namespace protobuf { - -// Auxiliary classes used for I/O. -// -// The Protocol Buffer library uses the classes in this package to deal with -// I/O and encoding/decoding raw bytes. Most users will not need to -// deal with this package. However, users who want to adapt the system to -// work with their own I/O abstractions -- e.g., to allow Protocol Buffers -// to be read from a different kind of input stream without the need for a -// temporary buffer -- should take a closer look. -namespace io {} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/printer.cc b/Resources/NetHook/google/protobuf/io/printer.cc deleted file mode 100644 index c7d3074d..00000000 --- a/Resources/NetHook/google/protobuf/io/printer.cc +++ /dev/null @@ -1,188 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter) - : variable_delimiter_(variable_delimiter), - output_(output), - buffer_(NULL), - buffer_size_(0), - at_start_of_line_(true), - failed_(false) { -} - -Printer::~Printer() { - // Only BackUp() if we're sure we've successfully called Next() at least once. - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } -} - -void Printer::Print(const map& variables, const char* text) { - int size = strlen(text); - int pos = 0; // The number of bytes we've written so far. - - for (int i = 0; i < size; i++) { - if (text[i] == '\n') { - // Saw newline. If there is more text, we may need to insert an indent - // here. So, write what we have so far, including the '\n'. - WriteRaw(text + pos, i - pos + 1); - pos = i + 1; - - // Setting this true will cause the next WriteRaw() to insert an indent - // first. - at_start_of_line_ = true; - - } else if (text[i] == variable_delimiter_) { - // Saw the start of a variable name. - - // Write what we have so far. - WriteRaw(text + pos, i - pos); - pos = i + 1; - - // Find closing delimiter. - const char* end = strchr(text + pos, variable_delimiter_); - if (end == NULL) { - GOOGLE_LOG(DFATAL) << " Unclosed variable name."; - end = text + pos; - } - int endpos = end - text; - - string varname(text + pos, endpos - pos); - if (varname.empty()) { - // Two delimiters in a row reduce to a literal delimiter character. - WriteRaw(&variable_delimiter_, 1); - } else { - // Replace with the variable's value. - map::const_iterator iter = variables.find(varname); - if (iter == variables.end()) { - GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; - } else { - WriteRaw(iter->second.data(), iter->second.size()); - } - } - - // Advance past this variable. - i = endpos; - pos = endpos + 1; - } - } - - // Write the rest. - WriteRaw(text + pos, size - pos); -} - -void Printer::Print(const char* text) { - static map empty; - Print(empty, text); -} - -void Printer::Print(const char* text, - const char* variable, const string& value) { - map vars; - vars[variable] = value; - Print(vars, text); -} - -void Printer::Print(const char* text, - const char* variable1, const string& value1, - const char* variable2, const string& value2) { - map vars; - vars[variable1] = value1; - vars[variable2] = value2; - Print(vars, text); -} - -void Printer::Indent() { - indent_ += " "; -} - -void Printer::Outdent() { - if (indent_.empty()) { - GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; - return; - } - - indent_.resize(indent_.size() - 2); -} - -void Printer::PrintRaw(const string& data) { - WriteRaw(data.data(), data.size()); -} - -void Printer::PrintRaw(const char* data) { - if (failed_) return; - WriteRaw(data, strlen(data)); -} - -void Printer::WriteRaw(const char* data, int size) { - if (failed_) return; - if (size == 0) return; - - if (at_start_of_line_) { - // Insert an indent. - at_start_of_line_ = false; - WriteRaw(indent_.data(), indent_.size()); - if (failed_) return; - } - - while (size > buffer_size_) { - // Data exceeds space in the buffer. Copy what we can and request a - // new buffer. - memcpy(buffer_, data, buffer_size_); - data += buffer_size_; - size -= buffer_size_; - void* void_buffer; - failed_ = !output_->Next(&void_buffer, &buffer_size_); - if (failed_) return; - buffer_ = reinterpret_cast(void_buffer); - } - - // Buffer is big enough to receive the data; copy it. - memcpy(buffer_, data, size); - buffer_ += size; - buffer_size_ -= size; -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/printer.h b/Resources/NetHook/google/protobuf/io/printer.h deleted file mode 100644 index de085389..00000000 --- a/Resources/NetHook/google/protobuf/io/printer.h +++ /dev/null @@ -1,132 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Utility class for writing text to a ZeroCopyOutputStream. - -#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__ -#define GOOGLE_PROTOBUF_IO_PRINTER_H__ - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -class ZeroCopyOutputStream; // zero_copy_stream.h - -// This simple utility class assists in code generation. It basically -// allows the caller to define a set of variables and then output some -// text with variable substitutions. Example usage: -// -// Printer printer(output, '$'); -// map vars; -// vars["name"] = "Bob"; -// printer.Print(vars, "My name is $name$."); -// -// The above writes "My name is Bob." to the output stream. -// -// Printer aggressively enforces correct usage, crashing (with assert failures) -// in the case of undefined variables in debug builds. This helps greatly in -// debugging code which uses it. -class LIBPROTOBUF_EXPORT Printer { - public: - // Create a printer that writes text to the given output stream. Use the - // given character as the delimiter for variables. - Printer(ZeroCopyOutputStream* output, char variable_delimiter); - ~Printer(); - - // Print some text after applying variable substitutions. If a particular - // variable in the text is not defined, this will crash. Variables to be - // substituted are identified by their names surrounded by delimiter - // characters (as given to the constructor). The variable bindings are - // defined by the given map. - void Print(const map& variables, const char* text); - - // Like the first Print(), except the substitutions are given as parameters. - void Print(const char* text); - // Like the first Print(), except the substitutions are given as parameters. - void Print(const char* text, const char* variable, const string& value); - // Like the first Print(), except the substitutions are given as parameters. - void Print(const char* text, const char* variable1, const string& value1, - const char* variable2, const string& value2); - // TODO(kenton): Overloaded versions with more variables? Two seems - // to be enough. - - // Indent text by two spaces. After calling Indent(), two spaces will be - // inserted at the beginning of each line of text. Indent() may be called - // multiple times to produce deeper indents. - void Indent(); - - // Reduces the current indent level by two spaces, or crashes if the indent - // level is zero. - void Outdent(); - - // Write a string to the output buffer. - // This method does not look for newlines to add indentation. - void PrintRaw(const string& data); - - // Write a zero-delimited string to output buffer. - // This method does not look for newlines to add indentation. - void PrintRaw(const char* data); - - // Write some bytes to the output buffer. - // This method does not look for newlines to add indentation. - void WriteRaw(const char* data, int size); - - // True if any write to the underlying stream failed. (We don't just - // crash in this case because this is an I/O failure, not a programming - // error.) - bool failed() const { return failed_; } - - private: - const char variable_delimiter_; - - ZeroCopyOutputStream* const output_; - char* buffer_; - int buffer_size_; - - string indent_; - bool at_start_of_line_; - bool failed_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer); -}; - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__ diff --git a/Resources/NetHook/google/protobuf/io/printer_unittest.cc b/Resources/NetHook/google/protobuf/io/printer_unittest.cc deleted file mode 100644 index 580a53da..00000000 --- a/Resources/NetHook/google/protobuf/io/printer_unittest.cc +++ /dev/null @@ -1,261 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// Each test repeats over several block sizes in order to test both cases -// where particular writes cross a buffer boundary and cases where they do -// not. - -TEST(Printer, EmptyPrinter) { - char buffer[8192]; - const int block_size = 100; - ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size); - Printer printer(&output, '\0'); - EXPECT_TRUE(!printer.failed()); -} - -TEST(Printer, BasicPrinting) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '\0'); - - printer.Print("Hello World!"); - printer.Print(" This is the same line.\n"); - printer.Print("But this is a new one.\nAnd this is another one."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ("Hello World! This is the same line.\n" - "But this is a new one.\n" - "And this is another one.", - buffer); - } -} - -TEST(Printer, WriteRaw) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - string string_obj = "From an object\n"; - Printer printer(&output, '$'); - printer.WriteRaw("Hello World!", 12); - printer.PrintRaw(" This is the same line.\n"); - printer.PrintRaw("But this is a new one.\nAnd this is another one."); - printer.WriteRaw("\n", 1); - printer.PrintRaw(string_obj); - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ("Hello World! This is the same line.\n" - "But this is a new one.\n" - "And this is another one." - "\n" - "From an object\n", - buffer); - } -} - -TEST(Printer, VariableSubstitution) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '$'); - map vars; - - vars["foo"] = "World"; - vars["bar"] = "$foo$"; - vars["abcdefg"] = "1234"; - - printer.Print(vars, "Hello $foo$!\nbar = $bar$\n"); - printer.PrintRaw("RawBit\n"); - printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$"); - - vars["foo"] = "blah"; - printer.Print(vars, "\nNow foo = $foo$."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ("Hello World!\n" - "bar = $foo$\n" - "RawBit\n" - "1234\n" - "A literal dollar sign: $\n" - "Now foo = blah.", - buffer); - } -} - -TEST(Printer, InlineVariableSubstitution) { - char buffer[8192]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - - { - Printer printer(&output, '$'); - printer.Print("Hello $foo$!\n", "foo", "World"); - printer.PrintRaw("RawBit\n"); - printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two"); - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ("Hello World!\n" - "RawBit\n" - "one two\n", - buffer); -} - -TEST(Printer, Indenting) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '$'); - map vars; - - vars["newline"] = "\n"; - - printer.Print("This is not indented.\n"); - printer.Indent(); - printer.Print("This is indented\nAnd so is this\n"); - printer.Outdent(); - printer.Print("But this is not."); - printer.Indent(); - printer.Print(" And this is still the same line.\n" - "But this is indented.\n"); - printer.PrintRaw("RawBit has indent at start\n"); - printer.PrintRaw("but not after a raw newline\n"); - printer.Print(vars, "Note that a newline in a variable will break " - "indenting, as we see$newline$here.\n"); - printer.Indent(); - printer.Print("And this"); - printer.Outdent(); - printer.Outdent(); - printer.Print(" is double-indented\nBack to normal."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ( - "This is not indented.\n" - " This is indented\n" - " And so is this\n" - "But this is not. And this is still the same line.\n" - " But this is indented.\n" - " RawBit has indent at start\n" - "but not after a raw newline\n" - "Note that a newline in a variable will break indenting, as we see\n" - "here.\n" - " And this is double-indented\n" - "Back to normal.", - buffer); - } -} - -// Death tests do not work on Windows as of yet. -#ifdef GTEST_HAS_DEATH_TEST -TEST(Printer, Death) { - char buffer[8192]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - Printer printer(&output, '$'); - - EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable"); - EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name"); - EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent"); -} -#endif // GTEST_HAS_DEATH_TEST - -TEST(Printer, WriteFailure) { - char buffer[16]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - Printer printer(&output, '$'); - - // Print 16 bytes to fill the buffer exactly (should not fail). - printer.Print("0123456789abcdef"); - EXPECT_FALSE(printer.failed()); - - // Try to print one more byte (should fail). - printer.Print(" "); - EXPECT_TRUE(printer.failed()); - - // Should not crash - printer.Print("blah"); - EXPECT_TRUE(printer.failed()); - - // Buffer should contain the first 16 bytes written. - EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer))); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/tokenizer.cc b/Resources/NetHook/google/protobuf/io/tokenizer.cc deleted file mode 100644 index 38fa351c..00000000 --- a/Resources/NetHook/google/protobuf/io/tokenizer.cc +++ /dev/null @@ -1,691 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Here we have a hand-written lexer. At first you might ask yourself, -// "Hand-written text processing? Is Kenton crazy?!" Well, first of all, -// yes I am crazy, but that's beside the point. There are actually reasons -// why I ended up writing this this way. -// -// The traditional approach to lexing is to use lex to generate a lexer for -// you. Unfortunately, lex's output is ridiculously ugly and difficult to -// integrate cleanly with C++ code, especially abstract code or code meant -// as a library. Better parser-generators exist but would add dependencies -// which most users won't already have, which we'd like to avoid. (GNU flex -// has a C++ output option, but it's still ridiculously ugly, non-abstract, -// and not library-friendly.) -// -// The next approach that any good software engineer should look at is to -// use regular expressions. And, indeed, I did. I have code which -// implements this same class using regular expressions. It's about 200 -// lines shorter. However: -// - Rather than error messages telling you "This string has an invalid -// escape sequence at line 5, column 45", you get error messages like -// "Parse error on line 5". Giving more precise errors requires adding -// a lot of code that ends up basically as complex as the hand-coded -// version anyway. -// - The regular expression to match a string literal looks like this: -// kString = new RE("(\"([^\"\\\\]|" // non-escaped -// "\\\\[abfnrtv?\"'\\\\0-7]|" // normal escape -// "\\\\x[0-9a-fA-F])*\"|" // hex escape -// "\'([^\'\\\\]|" // Also support single-quotes. -// "\\\\[abfnrtv?\"'\\\\0-7]|" -// "\\\\x[0-9a-fA-F])*\')"); -// Verifying the correctness of this line noise is actually harder than -// verifying the correctness of ConsumeString(), defined below. I'm not -// even confident that the above is correct, after staring at it for some -// time. -// - PCRE is fast, but there's still more overhead involved than the code -// below. -// - Sadly, regular expressions are not part of the C standard library, so -// using them would require depending on some other library. For the -// open source release, this could be really annoying. Nobody likes -// downloading one piece of software just to find that they need to -// download something else to make it work, and in all likelihood -// people downloading Protocol Buffers will already be doing so just -// to make something else work. We could include a copy of PCRE with -// our code, but that obligates us to keep it up-to-date and just seems -// like a big waste just to save 200 lines of code. -// -// On a similar but unrelated note, I'm even scared to use ctype.h. -// Apparently functions like isalpha() are locale-dependent. So, if we used -// that, then if this code is being called from some program that doesn't -// have its locale set to "C", it would behave strangely. We can't just set -// the locale to "C" ourselves since we might break the calling program that -// way, particularly if it is multi-threaded. WTF? Someone please let me -// (Kenton) know if I'm missing something here... -// -// I'd love to hear about other alternatives, though, as this code isn't -// exactly pretty. - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// As mentioned above, I don't trust ctype.h due to the presence of "locales". -// So, I have written replacement functions here. Someone please smack me if -// this is a bad idea or if there is some way around this. -// -// These "character classes" are designed to be used in template methods. -// For instance, Tokenizer::ConsumeZeroOrMore() will eat -// whitespace. - -// Note: No class is allowed to contain '\0', since this is used to mark end- -// of-input and is handled specially. - -#define CHARACTER_CLASS(NAME, EXPRESSION) \ - class NAME { \ - public: \ - static inline bool InClass(char c) { \ - return EXPRESSION; \ - } \ - } - -CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || - c == '\r' || c == '\v' || c == '\f'); - -CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0'); - -CHARACTER_CLASS(Digit, '0' <= c && c <= '9'); -CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7'); -CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || - ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F')); - -CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - (c == '_')); - -CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || - (c == '_')); - -CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' || - c == 'r' || c == 't' || c == 'v' || c == '\\' || - c == '?' || c == '\'' || c == '\"'); - -#undef CHARACTER_CLASS - -// Given a char, interpret it as a numeric digit and return its value. -// This supports any number base up to 36. -inline int DigitValue(char digit) { - if ('0' <= digit && digit <= '9') return digit - '0'; - if ('a' <= digit && digit <= 'z') return digit - 'a' + 10; - if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10; - return -1; -} - -// Inline because it's only used in one place. -inline char TranslateEscape(char c) { - switch (c) { - case 'a': return '\a'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - case '\\': return '\\'; - case '?': return '\?'; // Trigraphs = :( - case '\'': return '\''; - case '"': return '\"'; - - // We expect escape sequences to have been validated separately. - default: return '?'; - } -} - -} // anonymous namespace - -ErrorCollector::~ErrorCollector() {} - -// =================================================================== - -Tokenizer::Tokenizer(ZeroCopyInputStream* input, - ErrorCollector* error_collector) - : input_(input), - error_collector_(error_collector), - buffer_(NULL), - buffer_size_(0), - buffer_pos_(0), - read_error_(false), - line_(0), - column_(0), - token_start_(-1), - allow_f_after_float_(false), - comment_style_(CPP_COMMENT_STYLE) { - - current_.line = 0; - current_.column = 0; - current_.type = TYPE_START; - - Refresh(); -} - -Tokenizer::~Tokenizer() { - // If we had any buffer left unread, return it to the underlying stream - // so that someone else can read it. - if (buffer_size_ > buffer_pos_) { - input_->BackUp(buffer_size_ - buffer_pos_); - } -} - -// ------------------------------------------------------------------- -// Internal helpers. - -void Tokenizer::NextChar() { - // Update our line and column counters based on the character being - // consumed. - if (current_char_ == '\n') { - ++line_; - column_ = 0; - } else if (current_char_ == '\t') { - column_ += kTabWidth - column_ % kTabWidth; - } else { - ++column_; - } - - // Advance to the next character. - ++buffer_pos_; - if (buffer_pos_ < buffer_size_) { - current_char_ = buffer_[buffer_pos_]; - } else { - Refresh(); - } -} - -void Tokenizer::Refresh() { - if (read_error_) { - current_char_ = '\0'; - return; - } - - // If we're in a token, append the rest of the buffer to it. - if (token_start_ >= 0 && token_start_ < buffer_size_) { - current_.text.append(buffer_ + token_start_, buffer_size_ - token_start_); - token_start_ = 0; - } - - const void* data = NULL; - buffer_ = NULL; - buffer_pos_ = 0; - do { - if (!input_->Next(&data, &buffer_size_)) { - // end of stream (or read error) - buffer_size_ = 0; - read_error_ = true; - current_char_ = '\0'; - return; - } - } while (buffer_size_ == 0); - - buffer_ = static_cast(data); - - current_char_ = buffer_[0]; -} - -inline void Tokenizer::StartToken() { - token_start_ = buffer_pos_; - current_.type = TYPE_START; // Just for the sake of initializing it. - current_.text.clear(); - current_.line = line_; - current_.column = column_; -} - -inline void Tokenizer::EndToken() { - // Note: The if() is necessary because some STL implementations crash when - // you call string::append(NULL, 0), presumably because they are trying to - // be helpful by detecting the NULL pointer, even though there's nothing - // wrong with reading zero bytes from NULL. - if (buffer_pos_ != token_start_) { - current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_); - } - token_start_ = -1; -} - -// ------------------------------------------------------------------- -// Helper methods that consume characters. - -template -inline bool Tokenizer::LookingAt() { - return CharacterClass::InClass(current_char_); -} - -template -inline bool Tokenizer::TryConsumeOne() { - if (CharacterClass::InClass(current_char_)) { - NextChar(); - return true; - } else { - return false; - } -} - -inline bool Tokenizer::TryConsume(char c) { - if (current_char_ == c) { - NextChar(); - return true; - } else { - return false; - } -} - -template -inline void Tokenizer::ConsumeZeroOrMore() { - while (CharacterClass::InClass(current_char_)) { - NextChar(); - } -} - -template -inline void Tokenizer::ConsumeOneOrMore(const char* error) { - if (!CharacterClass::InClass(current_char_)) { - AddError(error); - } else { - do { - NextChar(); - } while (CharacterClass::InClass(current_char_)); - } -} - -// ------------------------------------------------------------------- -// Methods that read whole patterns matching certain kinds of tokens -// or comments. - -void Tokenizer::ConsumeString(char delimiter) { - while (true) { - switch (current_char_) { - case '\0': - case '\n': { - AddError("String literals cannot cross line boundaries."); - return; - } - - case '\\': { - // An escape sequence. - NextChar(); - if (TryConsumeOne()) { - // Valid escape sequence. - } else if (TryConsumeOne()) { - // Possibly followed by two more octal digits, but these will - // just be consumed by the main loop anyway so we don't need - // to do so explicitly here. - } else if (TryConsume('x') || TryConsume('X')) { - if (!TryConsumeOne()) { - AddError("Expected hex digits for escape sequence."); - } - // Possibly followed by another hex digit, but again we don't care. - } else { - AddError("Invalid escape sequence in string literal."); - } - break; - } - - default: { - if (current_char_ == delimiter) { - NextChar(); - return; - } - NextChar(); - break; - } - } - } -} - -Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero, - bool started_with_dot) { - bool is_float = false; - - if (started_with_zero && (TryConsume('x') || TryConsume('X'))) { - // A hex number (started with "0x"). - ConsumeOneOrMore("\"0x\" must be followed by hex digits."); - - } else if (started_with_zero && LookingAt()) { - // An octal number (had a leading zero). - ConsumeZeroOrMore(); - if (LookingAt()) { - AddError("Numbers starting with leading zero must be in octal."); - ConsumeZeroOrMore(); - } - - } else { - // A decimal number. - if (started_with_dot) { - is_float = true; - ConsumeZeroOrMore(); - } else { - ConsumeZeroOrMore(); - - if (TryConsume('.')) { - is_float = true; - ConsumeZeroOrMore(); - } - } - - if (TryConsume('e') || TryConsume('E')) { - is_float = true; - TryConsume('-') || TryConsume('+'); - ConsumeOneOrMore("\"e\" must be followed by exponent."); - } - - if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) { - is_float = true; - } - } - - if (LookingAt()) { - AddError("Need space between number and identifier."); - } else if (current_char_ == '.') { - if (is_float) { - AddError( - "Already saw decimal point or exponent; can't have another one."); - } else { - AddError("Hex and octal numbers must be integers."); - } - } - - return is_float ? TYPE_FLOAT : TYPE_INTEGER; -} - -void Tokenizer::ConsumeLineComment() { - while (current_char_ != '\0' && current_char_ != '\n') { - NextChar(); - } - TryConsume('\n'); -} - -void Tokenizer::ConsumeBlockComment() { - int start_line = line_; - int start_column = column_ - 2; - - while (true) { - while (current_char_ != '\0' && - current_char_ != '*' && - current_char_ != '/') { - NextChar(); - } - - if (TryConsume('*') && TryConsume('/')) { - // End of comment. - break; - } else if (TryConsume('/') && current_char_ == '*') { - // Note: We didn't consume the '*' because if there is a '/' after it - // we want to interpret that as the end of the comment. - AddError( - "\"/*\" inside block comment. Block comments cannot be nested."); - } else if (current_char_ == '\0') { - AddError("End-of-file inside block comment."); - error_collector_->AddError( - start_line, start_column, " Comment started here."); - break; - } - } -} - -// ------------------------------------------------------------------- - -bool Tokenizer::Next() { - TokenType last_token_type = current_.type; - - // Did we skip any characters after the last token? - bool skipped_stuff = false; - - while (!read_error_) { - if (TryConsumeOne()) { - ConsumeZeroOrMore(); - - } else if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) { - // Starting a comment? - if (TryConsume('/')) { - ConsumeLineComment(); - } else if (TryConsume('*')) { - ConsumeBlockComment(); - } else { - // Oops, it was just a slash. Return it. - current_.type = TYPE_SYMBOL; - current_.text = "/"; - current_.line = line_; - current_.column = column_ - 1; - return true; - } - - } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) { - ConsumeLineComment(); - - } else if (LookingAt() || current_char_ == '\0') { - AddError("Invalid control characters encountered in text."); - NextChar(); - // Skip more unprintable characters, too. But, remember that '\0' is - // also what current_char_ is set to after EOF / read error. We have - // to be careful not to go into an infinite loop of trying to consume - // it, so make sure to check read_error_ explicitly before consuming - // '\0'. - while (TryConsumeOne() || - (!read_error_ && TryConsume('\0'))) { - // Ignore. - } - - } else { - // Reading some sort of token. - StartToken(); - - if (TryConsumeOne()) { - ConsumeZeroOrMore(); - current_.type = TYPE_IDENTIFIER; - } else if (TryConsume('0')) { - current_.type = ConsumeNumber(true, false); - } else if (TryConsume('.')) { - // This could be the beginning of a floating-point number, or it could - // just be a '.' symbol. - - if (TryConsumeOne()) { - // It's a floating-point number. - if (last_token_type == TYPE_IDENTIFIER && !skipped_stuff) { - // We don't accept syntax like "blah.123". - error_collector_->AddError(line_, column_ - 2, - "Need space between identifier and decimal point."); - } - current_.type = ConsumeNumber(false, true); - } else { - current_.type = TYPE_SYMBOL; - } - } else if (TryConsumeOne()) { - current_.type = ConsumeNumber(false, false); - } else if (TryConsume('\"')) { - ConsumeString('\"'); - current_.type = TYPE_STRING; - } else if (TryConsume('\'')) { - ConsumeString('\''); - current_.type = TYPE_STRING; - } else { - NextChar(); - current_.type = TYPE_SYMBOL; - } - - EndToken(); - return true; - } - - skipped_stuff = true; - } - - // EOF - current_.type = TYPE_END; - current_.text.clear(); - current_.line = line_; - current_.column = column_; - return false; -} - -// ------------------------------------------------------------------- -// Token-parsing helpers. Remember that these don't need to report -// errors since any errors should already have been reported while -// tokenizing. Also, these can assume that whatever text they -// are given is text that the tokenizer actually parsed as a token -// of the given type. - -bool Tokenizer::ParseInteger(const string& text, uint64 max_value, - uint64* output) { - // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull() - // is non-standard. I hate the C standard library. :( - -// return strtoull(text.c_str(), NULL, 0); - - const char* ptr = text.c_str(); - int base = 10; - if (ptr[0] == '0') { - if (ptr[1] == 'x' || ptr[1] == 'X') { - // This is hex. - base = 16; - ptr += 2; - } else { - // This is octal. - base = 8; - } - } - - uint64 result = 0; - for (; *ptr != '\0'; ptr++) { - int digit = DigitValue(*ptr); - GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base) - << " Tokenizer::ParseInteger() passed text that could not have been" - " tokenized as an integer: " << CEscape(text); - if (digit > max_value || result > (max_value - digit) / base) { - // Overflow. - return false; - } - result = result * base + digit; - } - - *output = result; - return true; -} - -double Tokenizer::ParseFloat(const string& text) { - const char* start = text.c_str(); - char* end; - double result = NoLocaleStrtod(start, &end); - - // "1e" is not a valid float, but if the tokenizer reads it, it will - // report an error but still return it as a valid token. We need to - // accept anything the tokenizer could possibly return, error or not. - if (*end == 'e' || *end == 'E') { - ++end; - if (*end == '-' || *end == '+') ++end; - } - - // If the Tokenizer had allow_f_after_float_ enabled, the float may be - // suffixed with the letter 'f'. - if (*end == 'f' || *end == 'F') { - ++end; - } - - GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-') - << " Tokenizer::ParseFloat() passed text that could not have been" - " tokenized as a float: " << CEscape(text); - return result; -} - -void Tokenizer::ParseStringAppend(const string& text, string* output) { - // Reminder: text[0] is always the quote character. (If text is - // empty, it's invalid, so we'll just return.) - if (text.empty()) { - GOOGLE_LOG(DFATAL) - << " Tokenizer::ParseStringAppend() passed text that could not" - " have been tokenized as a string: " << CEscape(text); - return; - } - - output->reserve(output->size() + text.size()); - - // Loop through the string copying characters to "output" and - // interpreting escape sequences. Note that any invalid escape - // sequences or other errors were already reported while tokenizing. - // In this case we do not need to produce valid results. - for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) { - if (*ptr == '\\' && ptr[1] != '\0') { - // An escape sequence. - ++ptr; - - if (OctalDigit::InClass(*ptr)) { - // An octal escape. May one, two, or three digits. - int code = DigitValue(*ptr); - if (OctalDigit::InClass(ptr[1])) { - ++ptr; - code = code * 8 + DigitValue(*ptr); - } - if (OctalDigit::InClass(ptr[1])) { - ++ptr; - code = code * 8 + DigitValue(*ptr); - } - output->push_back(static_cast(code)); - - } else if (*ptr == 'x') { - // A hex escape. May zero, one, or two digits. (The zero case - // will have been caught as an error earlier.) - int code = 0; - if (HexDigit::InClass(ptr[1])) { - ++ptr; - code = DigitValue(*ptr); - } - if (HexDigit::InClass(ptr[1])) { - ++ptr; - code = code * 16 + DigitValue(*ptr); - } - output->push_back(static_cast(code)); - - } else { - // Some other escape code. - output->push_back(TranslateEscape(*ptr)); - } - - } else if (*ptr == text[0]) { - // Ignore quote matching the starting quote. - } else { - output->push_back(*ptr); - } - } - - return; -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/tokenizer.h b/Resources/NetHook/google/protobuf/io/tokenizer.h deleted file mode 100644 index d115161f..00000000 --- a/Resources/NetHook/google/protobuf/io/tokenizer.h +++ /dev/null @@ -1,303 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Class for parsing tokenized text from a ZeroCopyInputStream. - -#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__ -#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__ - -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -class ZeroCopyInputStream; // zero_copy_stream.h - -// Defined in this file. -class ErrorCollector; -class Tokenizer; - -// Abstract interface for an object which collects the errors that occur -// during parsing. A typical implementation might simply print the errors -// to stdout. -class LIBPROTOBUF_EXPORT ErrorCollector { - public: - inline ErrorCollector() {} - virtual ~ErrorCollector(); - - // Indicates that there was an error in the input at the given line and - // column numbers. The numbers are zero-based, so you may want to add - // 1 to each before printing them. - virtual void AddError(int line, int column, const string& message) = 0; - - // Indicates that there was a warning in the input at the given line and - // column numbers. The numbers are zero-based, so you may want to add - // 1 to each before printing them. - virtual void AddWarning(int line, int column, const string& message) { } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); -}; - -// This class converts a stream of raw text into a stream of tokens for -// the protocol definition parser to parse. The tokens recognized are -// similar to those that make up the C language; see the TokenType enum for -// precise descriptions. Whitespace and comments are skipped. By default, -// C- and C++-style comments are recognized, but other styles can be used by -// calling set_comment_style(). -class LIBPROTOBUF_EXPORT Tokenizer { - public: - // Construct a Tokenizer that reads and tokenizes text from the given - // input stream and writes errors to the given error_collector. - // The caller keeps ownership of input and error_collector. - Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector); - ~Tokenizer(); - - enum TokenType { - TYPE_START, // Next() has not yet been called. - TYPE_END, // End of input reached. "text" is empty. - - TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not - // starting with a digit. It is an error for a number - // to be followed by an identifier with no space in - // between. - TYPE_INTEGER, // A sequence of digits representing an integer. Normally - // the digits are decimal, but a prefix of "0x" indicates - // a hex number and a leading zero indicates octal, just - // like with C numeric literals. A leading negative sign - // is NOT included in the token; it's up to the parser to - // interpret the unary minus operator on its own. - TYPE_FLOAT, // A floating point literal, with a fractional part and/or - // an exponent. Always in decimal. Again, never - // negative. - TYPE_STRING, // A quoted sequence of escaped characters. Either single - // or double quotes can be used, but they must match. - // A string literal cannot cross a line break. - TYPE_SYMBOL, // Any other printable character, like '!' or '+'. - // Symbols are always a single character, so "!+$%" is - // four tokens. - }; - - // Structure representing a token read from the token stream. - struct Token { - TokenType type; - string text; // The exact text of the token as it appeared in - // the input. e.g. tokens of TYPE_STRING will still - // be escaped and in quotes. - - // "line" and "column" specify the position of the first character of - // the token within the input stream. They are zero-based. - int line; - int column; - }; - - // Get the current token. This is updated when Next() is called. Before - // the first call to Next(), current() has type TYPE_START and no contents. - const Token& current(); - - // Advance to the next token. Returns false if the end of the input is - // reached. - bool Next(); - - // Parse helpers --------------------------------------------------- - - // Parses a TYPE_FLOAT token. This never fails, so long as the text actually - // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the - // result is undefined (possibly an assert failure). - static double ParseFloat(const string& text); - - // Parses a TYPE_STRING token. This never fails, so long as the text actually - // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the - // result is undefined (possibly an assert failure). - static void ParseString(const string& text, string* output); - - // Identical to ParseString, but appends to output. - static void ParseStringAppend(const string& text, string* output); - - // Parses a TYPE_INTEGER token. Returns false if the result would be - // greater than max_value. Otherwise, returns true and sets *output to the - // result. If the text is not from a Token of type TYPE_INTEGER originally - // parsed by a Tokenizer, the result is undefined (possibly an assert - // failure). - static bool ParseInteger(const string& text, uint64 max_value, - uint64* output); - - // Options --------------------------------------------------------- - - // Set true to allow floats to be suffixed with the letter 'f'. Tokens - // which would otherwise be integers but which have the 'f' suffix will be - // forced to be interpreted as floats. For all other purposes, the 'f' is - // ignored. - void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; } - - // Valid values for set_comment_style(). - enum CommentStyle { - // Line comments begin with "//", block comments are delimited by "/*" and - // "*/". - CPP_COMMENT_STYLE, - // Line comments begin with "#". No way to write block comments. - SH_COMMENT_STYLE - }; - - // Sets the comment style. - void set_comment_style(CommentStyle style) { comment_style_ = style; } - - // ----------------------------------------------------------------- - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); - - Token current_; // Returned by current(). - - ZeroCopyInputStream* input_; - ErrorCollector* error_collector_; - - char current_char_; // == buffer_[buffer_pos_], updated by NextChar(). - const char* buffer_; // Current buffer returned from input_. - int buffer_size_; // Size of buffer_. - int buffer_pos_; // Current position within the buffer. - bool read_error_; // Did we previously encounter a read error? - - // Line and column number of current_char_ within the whole input stream. - int line_; - int column_; - - // Position in buffer_ where StartToken() was called. If the token - // started in the previous buffer, this is zero, and current_.text already - // contains the part of the token from the previous buffer. If not - // currently parsing a token, this is -1. - int token_start_; - - // Options. - bool allow_f_after_float_; - CommentStyle comment_style_; - - // Since we count columns we need to interpret tabs somehow. We'll take - // the standard 8-character definition for lack of any way to do better. - static const int kTabWidth = 8; - - // ----------------------------------------------------------------- - // Helper methods. - - // Consume this character and advance to the next one. - void NextChar(); - - // Read a new buffer from the input. - void Refresh(); - - // Called when the current character is the first character of a new - // token (not including whitespace or comments). - inline void StartToken(); - // Called when the current character is the first character after the - // end of the last token. After this returns, current_.text will - // contain all text consumed since StartToken() was called. - inline void EndToken(); - - // Convenience method to add an error at the current line and column. - void AddError(const string& message) { - error_collector_->AddError(line_, column_, message); - } - - // ----------------------------------------------------------------- - // The following four methods are used to consume tokens of specific - // types. They are actually used to consume all characters *after* - // the first, since the calling function consumes the first character - // in order to decide what kind of token is being read. - - // Read and consume a string, ending when the given delimiter is - // consumed. - void ConsumeString(char delimiter); - - // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER - // depending on what was read. This needs to know if the first - // character was a zero in order to correctly recognize hex and octal - // numbers. - // It also needs to know if the first characted was a . to parse floating - // point correctly. - TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot); - - // Consume the rest of a line. - void ConsumeLineComment(); - // Consume until "*/". - void ConsumeBlockComment(); - - // ----------------------------------------------------------------- - // These helper methods make the parsing code more readable. The - // "character classes" refered to are defined at the top of the .cc file. - // Basically it is a C++ class with one method: - // static bool InClass(char c); - // The method returns true if c is a member of this "class", like "Letter" - // or "Digit". - - // Returns true if the current character is of the given character - // class, but does not consume anything. - template - inline bool LookingAt(); - - // If the current character is in the given class, consume it and return - // true. Otherwise return false. - // e.g. TryConsumeOne() - template - inline bool TryConsumeOne(); - - // Like above, but try to consume the specific character indicated. - inline bool TryConsume(char c); - - // Consume zero or more of the given character class. - template - inline void ConsumeZeroOrMore(); - - // Consume one or more of the given character class or log the given - // error message. - // e.g. ConsumeOneOrMore("Expected digits."); - template - inline void ConsumeOneOrMore(const char* error); -}; - -// inline methods ==================================================== -inline const Tokenizer::Token& Tokenizer::current() { - return current_; -} - -inline void Tokenizer::ParseString(const string& text, string* output) { - output->clear(); - ParseStringAppend(text, output); -} - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__ diff --git a/Resources/NetHook/google/protobuf/io/tokenizer_unittest.cc b/Resources/NetHook/google/protobuf/io/tokenizer_unittest.cc deleted file mode 100644 index 358ec567..00000000 --- a/Resources/NetHook/google/protobuf/io/tokenizer_unittest.cc +++ /dev/null @@ -1,743 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// =================================================================== -// Data-Driven Test Infrastructure - -// TODO(kenton): This is copied from coded_stream_unittest. This is -// temporary until these fetaures are integrated into gTest itself. - -// TEST_1D and TEST_2D are macros I'd eventually like to see added to -// gTest. These macros can be used to declare tests which should be -// run multiple times, once for each item in some input array. TEST_1D -// tests all cases in a single input array. TEST_2D tests all -// combinations of cases from two arrays. The arrays must be statically -// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: -// -// int kCases[] = {1, 2, 3, 4} -// TEST_1D(MyFixture, MyTest, kCases) { -// EXPECT_GT(kCases_case, 0); -// } -// -// This test iterates through the numbers 1, 2, 3, and 4 and tests that -// they are all grater than zero. In case of failure, the exact case -// which failed will be printed. The case type must be printable using -// ostream::operator<<. - -#define TEST_1D(FIXTURE, NAME, CASES) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template \ - void DoSingleCase(const CaseType& CASES##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES " case #" << i << ": " << CASES[i]); \ - DoSingleCase(CASES[i]); \ - } \ - } \ - \ - template \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) - -#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template \ - void DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ - for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ - << #CASES2 " case #" << j << ": " << CASES2[j]); \ - DoSingleCase(CASES1[i], CASES2[j]); \ - } \ - } \ - } \ - \ - template \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case) - -// ------------------------------------------------------------------- - -// An input stream that is basically like an ArrayInputStream but sometimes -// returns empty buffers, just to throw us off. -class TestInputStream : public ZeroCopyInputStream { - public: - TestInputStream(const void* data, int size, int block_size) - : array_stream_(data, size, block_size), counter_(0) {} - ~TestInputStream() {} - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size) { - // We'll return empty buffers starting with the first buffer, and every - // 3 and 5 buffers after that. - if (counter_ % 3 == 0 || counter_ % 5 == 0) { - *data = NULL; - *size = 0; - ++counter_; - return true; - } else { - ++counter_; - return array_stream_.Next(data, size); - } - } - - void BackUp(int count) { return array_stream_.BackUp(count); } - bool Skip(int count) { return array_stream_.Skip(count); } - int64 ByteCount() const { return array_stream_.ByteCount(); } - - private: - ArrayInputStream array_stream_; - int counter_; -}; - -// ------------------------------------------------------------------- - -// An error collector which simply concatenates all its errors into a big -// block of text which can be checked. -class TestErrorCollector : public ErrorCollector { - public: - TestErrorCollector() {} - ~TestErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(int line, int column, const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", - line, column, message); - } -}; - -// ------------------------------------------------------------------- - -// We test each operation over a variety of block sizes to insure that -// we test cases where reads cross buffer boundaries as well as cases -// where they don't. This is sort of a brute-force approach to this, -// but it's easy to write and easy to understand. -const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; - -class TokenizerTest : public testing::Test { - protected: - // For easy testing. - uint64 ParseInteger(const string& text) { - uint64 result; - EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result)); - return result; - } -}; - -// =================================================================== - -// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -// In each test case, the entire input text should parse as a single token -// of the given type. -struct SimpleTokenCase { - string input; - Tokenizer::TokenType type; -}; - -inline ostream& operator<<(ostream& out, - const SimpleTokenCase& test_case) { - return out << CEscape(test_case.input); -} - -SimpleTokenCase kSimpleTokenCases[] = { - // Test identifiers. - { "hello", Tokenizer::TYPE_IDENTIFIER }, - - // Test integers. - { "123", Tokenizer::TYPE_INTEGER }, - { "0xab6", Tokenizer::TYPE_INTEGER }, - { "0XAB6", Tokenizer::TYPE_INTEGER }, - { "0X1234567", Tokenizer::TYPE_INTEGER }, - { "0x89abcdef", Tokenizer::TYPE_INTEGER }, - { "0x89ABCDEF", Tokenizer::TYPE_INTEGER }, - { "01234567", Tokenizer::TYPE_INTEGER }, - - // Test floats. - { "123.45", Tokenizer::TYPE_FLOAT }, - { "1.", Tokenizer::TYPE_FLOAT }, - { "1e3", Tokenizer::TYPE_FLOAT }, - { "1E3", Tokenizer::TYPE_FLOAT }, - { "1e-3", Tokenizer::TYPE_FLOAT }, - { "1e+3", Tokenizer::TYPE_FLOAT }, - { "1.e3", Tokenizer::TYPE_FLOAT }, - { "1.2e3", Tokenizer::TYPE_FLOAT }, - { ".1", Tokenizer::TYPE_FLOAT }, - { ".1e3", Tokenizer::TYPE_FLOAT }, - { ".1e-3", Tokenizer::TYPE_FLOAT }, - { ".1e+3", Tokenizer::TYPE_FLOAT }, - - // Test strings. - { "'hello'", Tokenizer::TYPE_STRING }, - { "\"foo\"", Tokenizer::TYPE_STRING }, - { "'a\"b'", Tokenizer::TYPE_STRING }, - { "\"a'b\"", Tokenizer::TYPE_STRING }, - { "'a\\'b'", Tokenizer::TYPE_STRING }, - { "\"a\\\"b\"", Tokenizer::TYPE_STRING }, - { "'\\xf'", Tokenizer::TYPE_STRING }, - { "'\\0'", Tokenizer::TYPE_STRING }, - - // Test symbols. - { "+", Tokenizer::TYPE_SYMBOL }, - { ".", Tokenizer::TYPE_SYMBOL }, -}; - -TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kSimpleTokenCases_case.input.data(), - kSimpleTokenCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Before Next() is called, the initial token should always be TYPE_START. - EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // Parse the token. - ASSERT_TRUE(tokenizer.Next()); - - // Check that it has the right type. - EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type); - // Check that it contains the complete input text. - EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text); - // Check that it is located at the beginning of the input - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - - // After Next() returns false, the token should have type TYPE_END. - EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column); - - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) { - // Test the "allow_f_after_float" option. - - // Set up the tokenizer. - const char* text = "1f 2.5f 6e3f 7F"; - TestInputStream input(text, strlen(text), kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - tokenizer.set_allow_f_after_float(true); - - // Advance through tokens and check that they are parsed as expected. - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "1f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "2.5f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "6e3f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "7F"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -#endif - -// ------------------------------------------------------------------- - -// In each case, the input is parsed to produce a list of tokens. The -// last token in "output" must have type TYPE_END. -struct MultiTokenCase { - string input; - Tokenizer::Token output[10]; // The compiler wants a constant array - // size for initialization to work. There - // is no reason this can't be increased if - // needed. -}; - -inline ostream& operator<<(ostream& out, - const MultiTokenCase& test_case) { - return out << CEscape(test_case.input); -} - -MultiTokenCase kMultiTokenCases[] = { - // Test empty input. - { "", { - { Tokenizer::TYPE_END , "" , 0, 0 }, - }}, - - // Test all token types at the same time. - { "foo 1 1.2 + 'bar'", { - { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0 }, - { Tokenizer::TYPE_INTEGER , "1" , 0, 4 }, - { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6 }, - { Tokenizer::TYPE_SYMBOL , "+" , 0, 10 }, - { Tokenizer::TYPE_STRING , "'bar'", 0, 12 }, - { Tokenizer::TYPE_END , "" , 0, 17 }, - }}, - - // Test that consecutive symbols are parsed as separate tokens. - { "!@+%", { - { Tokenizer::TYPE_SYMBOL , "!" , 0, 0 }, - { Tokenizer::TYPE_SYMBOL , "@" , 0, 1 }, - { Tokenizer::TYPE_SYMBOL , "+" , 0, 2 }, - { Tokenizer::TYPE_SYMBOL , "%" , 0, 3 }, - { Tokenizer::TYPE_END , "" , 0, 4 }, - }}, - - // Test that newlines affect line numbers correctly. - { "foo bar\nrab oof", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4 }, - { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4 }, - { Tokenizer::TYPE_END , "" , 1, 7 }, - }}, - - // Test that tabs affect column numbers correctly. - { "foo\tbar \tbaz", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8 }, - { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16 }, - { Tokenizer::TYPE_END , "" , 0, 19 }, - }}, - - // Test that line comments are ignored. - { "foo // This is a comment\n" - "bar // This is another comment", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0 }, - { Tokenizer::TYPE_END , "" , 1, 30 }, - }}, - - // Test that block comments are ignored. - { "foo /* This is a block comment */ bar", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34 }, - { Tokenizer::TYPE_END , "" , 0, 37 }, - }}, - - // Test that sh-style comments are not ignored by default. - { "foo # bar\n" - "baz", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_SYMBOL , "#" , 0, 4 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6 }, - { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0 }, - { Tokenizer::TYPE_END , "" , 1, 3 }, - }}, - - // Bytes with the high-order bit set should not be seen as control characters. - { "\300", { - { Tokenizer::TYPE_SYMBOL, "\300", 0, 0 }, - { Tokenizer::TYPE_END , "" , 0, 1 }, - }}, - - // Test all whitespace chars - { "foo\n\t\r\v\fbar", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11 }, - { Tokenizer::TYPE_END , "" , 1, 14 }, - }}, -}; - -TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kMultiTokenCases_case.input.data(), - kMultiTokenCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Before Next() is called, the initial token should always be TYPE_START. - EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // Loop through all expected tokens. - int i = 0; - Tokenizer::Token token; - do { - token = kMultiTokenCases_case.output[i++]; - - SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text); - - // Next() should only return false when it hits the end token. - if (token.type != Tokenizer::TYPE_END) { - ASSERT_TRUE(tokenizer.Next()); - } else { - ASSERT_FALSE(tokenizer.Next()); - } - - // Check that the token matches the expected one. - EXPECT_EQ(token.type, tokenizer.current().type); - EXPECT_EQ(token.text, tokenizer.current().text); - EXPECT_EQ(token.line, tokenizer.current().line); - EXPECT_EQ(token.column, tokenizer.current().column); - - } while (token.type != Tokenizer::TYPE_END); - - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) { - // Test the "comment_style" option. - - const char* text = "foo # bar\n" - "baz // qux\n" - "corge /* grault */\n" - "garply"; - const char* const kTokens[] = {"foo", // "# bar" is ignored - "baz", "/", "/", "qux", - "corge", "/", "*", "grault", "*", "/", - "garply"}; - - // Set up the tokenizer. - TestInputStream input(text, strlen(text), kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE); - - // Advance through tokens and check that they are parsed as expected. - for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) { - EXPECT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, kTokens[i]); - } - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -#endif - -// ------------------------------------------------------------------- - -// Test parse helpers. It's not really worth setting up a full data-driven -// test here. -TEST_F(TokenizerTest, ParseInteger) { - EXPECT_EQ(0, ParseInteger("0")); - EXPECT_EQ(123, ParseInteger("123")); - EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12")); - EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); - EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); - EXPECT_EQ(01234567, ParseInteger("01234567")); - EXPECT_EQ(0X123, ParseInteger("0X123")); - - // Test invalid integers that may still be tokenized as integers. - EXPECT_EQ(0, ParseInteger("0x")); - - uint64 i; -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - // Test invalid integers that will never be tokenized as integers. - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); -#endif // GTEST_HAS_DEATH_TEST - - // Test overflows. - EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i)); -} - -TEST_F(TokenizerTest, ParseFloat) { - EXPECT_DOUBLE_EQ(1 , Tokenizer::ParseFloat("1.")); - EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1e3")); - EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1E3")); - EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3")); - EXPECT_DOUBLE_EQ(.1 , Tokenizer::ParseFloat(".1")); - EXPECT_DOUBLE_EQ(.25 , Tokenizer::ParseFloat(".25")); - EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3")); - EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3")); - EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3")); - EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3")); - EXPECT_DOUBLE_EQ(5 , Tokenizer::ParseFloat("5")); - EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12")); - EXPECT_DOUBLE_EQ(1.2 , Tokenizer::ParseFloat("1.2")); - EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2")); - - // Test invalid integers that may still be tokenized as integers. - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e")); - - // Test 'f' suffix. - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F")); - - // These should parse successfully even though they are out of range. - // Overflows become infinity and underflows become zero. - EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999")); - EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999")); - -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - // Test invalid integers that will never be tokenized as integers. - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"), - "passed text that could not have been tokenized as a float"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"), - "passed text that could not have been tokenized as a float"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"), - "passed text that could not have been tokenized as a float"); -#endif // GTEST_HAS_DEATH_TEST -} - -TEST_F(TokenizerTest, ParseString) { - string output; - Tokenizer::ParseString("'hello'", &output); - EXPECT_EQ("hello", output); - Tokenizer::ParseString("\"blah\\nblah2\"", &output); - EXPECT_EQ("blah\nblah2", output); - Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output); - EXPECT_EQ("\1x\1\123\739\52\334n\3", output); - Tokenizer::ParseString("'\\x20\\x4'", &output); - EXPECT_EQ("\x20\x4", output); - - // Test invalid strings that may still be tokenized as strings. - Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid - EXPECT_EQ("\a?\v\t", output); - Tokenizer::ParseString("'", &output); - EXPECT_EQ("", output); - Tokenizer::ParseString("'\\", &output); - EXPECT_EQ("\\", output); - - // Test invalid strings that will never be tokenized as strings. -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output), - "passed text that could not have been tokenized as a string"); -#endif // GTEST_HAS_DEATH_TEST -} - -TEST_F(TokenizerTest, ParseStringAppend) { - // Check that ParseString and ParseStringAppend differ. - string output("stuff+"); - Tokenizer::ParseStringAppend("'hello'", &output); - EXPECT_EQ("stuff+hello", output); - Tokenizer::ParseString("'hello'", &output); - EXPECT_EQ("hello", output); -} - -// ------------------------------------------------------------------- - -// Each case parses some input text, ignoring the tokens produced, and -// checks that the error output matches what is expected. -struct ErrorCase { - string input; - bool recoverable; // True if the tokenizer should be able to recover and - // parse more tokens after seeing this error. Cases - // for which this is true must end with "foo" as - // the last token, which the test will check for. - const char* errors; -}; - -inline ostream& operator<<(ostream& out, - const ErrorCase& test_case) { - return out << CEscape(test_case.input); -} - -ErrorCase kErrorCases[] = { - // String errors. - { "'\\l' foo", true, - "0:2: Invalid escape sequence in string literal.\n" }, - { "'\\x' foo", true, - "0:3: Expected hex digits for escape sequence.\n" }, - { "'foo", false, - "0:4: String literals cannot cross line boundaries.\n" }, - { "'bar\nfoo", true, - "0:4: String literals cannot cross line boundaries.\n" }, - - // Integer errors. - { "123foo", true, - "0:3: Need space between number and identifier.\n" }, - - // Hex/octal errors. - { "0x foo", true, - "0:2: \"0x\" must be followed by hex digits.\n" }, - { "0541823 foo", true, - "0:4: Numbers starting with leading zero must be in octal.\n" }, - { "0x123z foo", true, - "0:5: Need space between number and identifier.\n" }, - { "0x123.4 foo", true, - "0:5: Hex and octal numbers must be integers.\n" }, - { "0123.4 foo", true, - "0:4: Hex and octal numbers must be integers.\n" }, - - // Float errors. - { "1e foo", true, - "0:2: \"e\" must be followed by exponent.\n" }, - { "1e- foo", true, - "0:3: \"e\" must be followed by exponent.\n" }, - { "1.2.3 foo", true, - "0:3: Already saw decimal point or exponent; can't have another one.\n" }, - { "1e2.3 foo", true, - "0:3: Already saw decimal point or exponent; can't have another one.\n" }, - { "a.1 foo", true, - "0:1: Need space between identifier and decimal point.\n" }, - // allow_f_after_float not enabled, so this should be an error. - { "1.0f foo", true, - "0:3: Need space between number and identifier.\n" }, - - // Block comment errors. - { "/*", false, - "0:2: End-of-file inside block comment.\n" - "0:0: Comment started here.\n"}, - { "/*/*/ foo", true, - "0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"}, - - // Control characters. Multiple consecutive control characters should only - // produce one error. - { "\b foo", true, - "0:0: Invalid control characters encountered in text.\n" }, - { "\b\b foo", true, - "0:0: Invalid control characters encountered in text.\n" }, - - // Check that control characters at end of input don't result in an - // infinite loop. - { "\b", false, - "0:0: Invalid control characters encountered in text.\n" }, - - // Check recovery from '\0'. We have to explicitly specify the length of - // these strings because otherwise the string constructor will just call - // strlen() which will see the first '\0' and think that is the end of the - // string. - { string("\0foo", 4), true, - "0:0: Invalid control characters encountered in text.\n" }, - { string("\0\0foo", 5), true, - "0:0: Invalid control characters encountered in text.\n" }, -}; - -TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kErrorCases_case.input.data(), - kErrorCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Ignore all input, except remember if the last token was "foo". - bool last_was_foo = false; - while (tokenizer.Next()) { - last_was_foo = tokenizer.current().text == "foo"; - } - - // Check that the errors match what was expected. - EXPECT_EQ(error_collector.text_, kErrorCases_case.errors); - - // If the error was recoverable, make sure we saw "foo" after it. - if (kErrorCases_case.recoverable) { - EXPECT_TRUE(last_was_foo); - } -} - -// ------------------------------------------------------------------- - -TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) { - string text = "foo bar"; - TestInputStream input(text.data(), text.size(), kBlockSizes_case); - - // Create a tokenizer, read one token, then destroy it. - { - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - tokenizer.Next(); - } - - // Only "foo" should have been read. - EXPECT_EQ(strlen("foo"), input.ByteCount()); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream.cc b/Resources/NetHook/google/protobuf/io/zero_copy_stream.cc deleted file mode 100644 index dad6ff14..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - - -namespace google { -namespace protobuf { -namespace io { - -ZeroCopyInputStream::~ZeroCopyInputStream() {} -ZeroCopyOutputStream::~ZeroCopyOutputStream() {} - - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream.h b/Resources/NetHook/google/protobuf/io/zero_copy_stream.h deleted file mode 100644 index db5326f7..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream.h +++ /dev/null @@ -1,238 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream -// interfaces, which represent abstract I/O streams to and from which -// protocol buffers can be read and written. For a few simple -// implementations of these interfaces, see zero_copy_stream_impl.h. -// -// These interfaces are different from classic I/O streams in that they -// try to minimize the amount of data copying that needs to be done. -// To accomplish this, responsibility for allocating buffers is moved to -// the stream object, rather than being the responsibility of the caller. -// So, the stream can return a buffer which actually points directly into -// the final data structure where the bytes are to be stored, and the caller -// can interact directly with that buffer, eliminating an intermediate copy -// operation. -// -// As an example, consider the common case in which you are reading bytes -// from an array that is already in memory (or perhaps an mmap()ed file). -// With classic I/O streams, you would do something like: -// char buffer[BUFFER_SIZE]; -// input->Read(buffer, BUFFER_SIZE); -// DoSomething(buffer, BUFFER_SIZE); -// Then, the stream basically just calls memcpy() to copy the data from -// the array into your buffer. With a ZeroCopyInputStream, you would do -// this instead: -// const void* buffer; -// int size; -// input->Next(&buffer, &size); -// DoSomething(buffer, size); -// Here, no copy is performed. The input stream returns a pointer directly -// into the backing array, and the caller ends up reading directly from it. -// -// If you want to be able to read the old-fashion way, you can create -// a CodedInputStream or CodedOutputStream wrapping these objects and use -// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy -// step, but Coded*Stream will handle buffering so at least it will be -// reasonably efficient. -// -// ZeroCopyInputStream example: -// // Read in a file and print its contents to stdout. -// int fd = open("myfile", O_RDONLY); -// ZeroCopyInputStream* input = new FileInputStream(fd); -// -// const void* buffer; -// int size; -// while (input->Next(&buffer, &size)) { -// cout.write(buffer, size); -// } -// -// delete input; -// close(fd); -// -// ZeroCopyOutputStream example: -// // Copy the contents of "infile" to "outfile", using plain read() for -// // "infile" but a ZeroCopyOutputStream for "outfile". -// int infd = open("infile", O_RDONLY); -// int outfd = open("outfile", O_WRONLY); -// ZeroCopyOutputStream* output = new FileOutputStream(outfd); -// -// void* buffer; -// int size; -// while (output->Next(&buffer, &size)) { -// int bytes = read(infd, buffer, size); -// if (bytes < size) { -// // Reached EOF. -// output->BackUp(size - bytes); -// break; -// } -// } -// -// delete output; -// close(infd); -// close(outfd); - -#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ -#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ - -#include -#include - -namespace google { - -namespace protobuf { -namespace io { - -// Defined in this file. -class ZeroCopyInputStream; -class ZeroCopyOutputStream; - -// Abstract interface similar to an input stream but designed to minimize -// copying. -class LIBPROTOBUF_EXPORT ZeroCopyInputStream { - public: - inline ZeroCopyInputStream() {} - virtual ~ZeroCopyInputStream(); - - // Obtains a chunk of data from the stream. - // - // Preconditions: - // * "size" and "data" are not NULL. - // - // Postconditions: - // * If the returned value is false, there is no more data to return or - // an error occurred. All errors are permanent. - // * Otherwise, "size" points to the actual number of bytes read and "data" - // points to a pointer to a buffer containing these bytes. - // * Ownership of this buffer remains with the stream, and the buffer - // remains valid only until some other method of the stream is called - // or the stream is destroyed. - // * It is legal for the returned buffer to have zero size, as long - // as repeatedly calling Next() eventually yields a buffer with non-zero - // size. - virtual bool Next(const void** data, int* size) = 0; - - // Backs up a number of bytes, so that the next call to Next() returns - // data again that was already returned by the last call to Next(). This - // is useful when writing procedures that are only supposed to read up - // to a certain point in the input, then return. If Next() returns a - // buffer that goes beyond what you wanted to read, you can use BackUp() - // to return to the point where you intended to finish. - // - // Preconditions: - // * The last method called must have been Next(). - // * count must be less than or equal to the size of the last buffer - // returned by Next(). - // - // Postconditions: - // * The last "count" bytes of the last buffer returned by Next() will be - // pushed back into the stream. Subsequent calls to Next() will return - // the same data again before producing new data. - virtual void BackUp(int count) = 0; - - // Skips a number of bytes. Returns false if the end of the stream is - // reached or some input error occurred. In the end-of-stream case, the - // stream is advanced to the end of the stream (so ByteCount() will return - // the total size of the stream). - virtual bool Skip(int count) = 0; - - // Returns the total number of bytes read since this object was created. - virtual int64 ByteCount() const = 0; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); -}; - -// Abstract interface similar to an output stream but designed to minimize -// copying. -class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { - public: - inline ZeroCopyOutputStream() {} - virtual ~ZeroCopyOutputStream(); - - // Obtains a buffer into which data can be written. Any data written - // into this buffer will eventually (maybe instantly, maybe later on) - // be written to the output. - // - // Preconditions: - // * "size" and "data" are not NULL. - // - // Postconditions: - // * If the returned value is false, an error occurred. All errors are - // permanent. - // * Otherwise, "size" points to the actual number of bytes in the buffer - // and "data" points to the buffer. - // * Ownership of this buffer remains with the stream, and the buffer - // remains valid only until some other method of the stream is called - // or the stream is destroyed. - // * Any data which the caller stores in this buffer will eventually be - // written to the output (unless BackUp() is called). - // * It is legal for the returned buffer to have zero size, as long - // as repeatedly calling Next() eventually yields a buffer with non-zero - // size. - virtual bool Next(void** data, int* size) = 0; - - // Backs up a number of bytes, so that the end of the last buffer returned - // by Next() is not actually written. This is needed when you finish - // writing all the data you want to write, but the last buffer was bigger - // than you needed. You don't want to write a bunch of garbage after the - // end of your data, so you use BackUp() to back up. - // - // Preconditions: - // * The last method called must have been Next(). - // * count must be less than or equal to the size of the last buffer - // returned by Next(). - // * The caller must not have written anything to the last "count" bytes - // of that buffer. - // - // Postconditions: - // * The last "count" bytes of the last buffer returned by Next() will be - // ignored. - virtual void BackUp(int count) = 0; - - // Returns the total number of bytes written since this object was created. - virtual int64 ByteCount() const = 0; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); -}; - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.cc b/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.cc deleted file mode 100644 index 1384c746..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.cc +++ /dev/null @@ -1,470 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifdef _MSC_VER -#include -#else -#include -#include -#include -#include -#endif -#include -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -#ifdef _WIN32 -// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its -// return value is undefined. We re-define it to always produce an error. -#define lseek(fd, offset, origin) ((off_t)-1) -#endif - -namespace { - -// EINTR sucks. -int close_no_eintr(int fd) { - int result; - do { - result = close(fd); - } while (result < 0 && errno == EINTR); - return result; -} - -} // namespace - - -// =================================================================== - -FileInputStream::FileInputStream(int file_descriptor, int block_size) - : copying_input_(file_descriptor), - impl_(©ing_input_, block_size) { -} - -FileInputStream::~FileInputStream() {} - -bool FileInputStream::Close() { - return copying_input_.Close(); -} - -bool FileInputStream::Next(const void** data, int* size) { - return impl_.Next(data, size); -} - -void FileInputStream::BackUp(int count) { - impl_.BackUp(count); -} - -bool FileInputStream::Skip(int count) { - return impl_.Skip(count); -} - -int64 FileInputStream::ByteCount() const { - return impl_.ByteCount(); -} - -FileInputStream::CopyingFileInputStream::CopyingFileInputStream( - int file_descriptor) - : file_(file_descriptor), - close_on_delete_(false), - is_closed_(false), - errno_(0), - previous_seek_failed_(false) { -} - -FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { - if (close_on_delete_) { - if (!Close()) { - GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); - } - } -} - -bool FileInputStream::CopyingFileInputStream::Close() { - GOOGLE_CHECK(!is_closed_); - - is_closed_ = true; - if (close_no_eintr(file_) != 0) { - // The docs on close() do not specify whether a file descriptor is still - // open after close() fails with EIO. However, the glibc source code - // seems to indicate that it is not. - errno_ = errno; - return false; - } - - return true; -} - -int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) { - GOOGLE_CHECK(!is_closed_); - - int result; - do { - result = read(file_, buffer, size); - } while (result < 0 && errno == EINTR); - - if (result < 0) { - // Read error (not EOF). - errno_ = errno; - } - - return result; -} - -int FileInputStream::CopyingFileInputStream::Skip(int count) { - GOOGLE_CHECK(!is_closed_); - - if (!previous_seek_failed_ && - lseek(file_, count, SEEK_CUR) != (off_t)-1) { - // Seek succeeded. - return count; - } else { - // Failed to seek. - - // Note to self: Don't seek again. This file descriptor doesn't - // support it. - previous_seek_failed_ = true; - - // Use the default implementation. - return CopyingInputStream::Skip(count); - } -} - -// =================================================================== - -FileOutputStream::FileOutputStream(int file_descriptor, int block_size) - : copying_output_(file_descriptor), - impl_(©ing_output_, block_size) { -} - -FileOutputStream::~FileOutputStream() { - impl_.Flush(); -} - -bool FileOutputStream::Close() { - bool flush_succeeded = impl_.Flush(); - return copying_output_.Close() && flush_succeeded; -} - -bool FileOutputStream::Flush() { - return impl_.Flush(); -} - -bool FileOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void FileOutputStream::BackUp(int count) { - impl_.BackUp(count); -} - -int64 FileOutputStream::ByteCount() const { - return impl_.ByteCount(); -} - -FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( - int file_descriptor) - : file_(file_descriptor), - close_on_delete_(false), - is_closed_(false), - errno_(0) { -} - -FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { - if (close_on_delete_) { - if (!Close()) { - GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); - } - } -} - -bool FileOutputStream::CopyingFileOutputStream::Close() { - GOOGLE_CHECK(!is_closed_); - - is_closed_ = true; - if (close_no_eintr(file_) != 0) { - // The docs on close() do not specify whether a file descriptor is still - // open after close() fails with EIO. However, the glibc source code - // seems to indicate that it is not. - errno_ = errno; - return false; - } - - return true; -} - -bool FileOutputStream::CopyingFileOutputStream::Write( - const void* buffer, int size) { - GOOGLE_CHECK(!is_closed_); - int total_written = 0; - - const uint8* buffer_base = reinterpret_cast(buffer); - - while (total_written < size) { - int bytes; - do { - bytes = write(file_, buffer_base + total_written, size - total_written); - } while (bytes < 0 && errno == EINTR); - - if (bytes <= 0) { - // Write error. - - // FIXME(kenton): According to the man page, if write() returns zero, - // there was no error; write() simply did not write anything. It's - // unclear under what circumstances this might happen, but presumably - // errno won't be set in this case. I am confused as to how such an - // event should be handled. For now I'm treating it as an error, since - // retrying seems like it could lead to an infinite loop. I suspect - // this never actually happens anyway. - - if (bytes < 0) { - errno_ = errno; - } - return false; - } - total_written += bytes; - } - - return true; -} - -// =================================================================== - -IstreamInputStream::IstreamInputStream(istream* input, int block_size) - : copying_input_(input), - impl_(©ing_input_, block_size) { -} - -IstreamInputStream::~IstreamInputStream() {} - -bool IstreamInputStream::Next(const void** data, int* size) { - return impl_.Next(data, size); -} - -void IstreamInputStream::BackUp(int count) { - impl_.BackUp(count); -} - -bool IstreamInputStream::Skip(int count) { - return impl_.Skip(count); -} - -int64 IstreamInputStream::ByteCount() const { - return impl_.ByteCount(); -} - -IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream( - istream* input) - : input_(input) { -} - -IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {} - -int IstreamInputStream::CopyingIstreamInputStream::Read( - void* buffer, int size) { - input_->read(reinterpret_cast(buffer), size); - int result = input_->gcount(); - if (result == 0 && input_->fail() && !input_->eof()) { - return -1; - } - return result; -} - -// =================================================================== - -OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size) - : copying_output_(output), - impl_(©ing_output_, block_size) { -} - -OstreamOutputStream::~OstreamOutputStream() { - impl_.Flush(); -} - -bool OstreamOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void OstreamOutputStream::BackUp(int count) { - impl_.BackUp(count); -} - -int64 OstreamOutputStream::ByteCount() const { - return impl_.ByteCount(); -} - -OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream( - ostream* output) - : output_(output) { -} - -OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() { -} - -bool OstreamOutputStream::CopyingOstreamOutputStream::Write( - const void* buffer, int size) { - output_->write(reinterpret_cast(buffer), size); - return output_->good(); -} - -// =================================================================== - -ConcatenatingInputStream::ConcatenatingInputStream( - ZeroCopyInputStream* const streams[], int count) - : streams_(streams), stream_count_(count), bytes_retired_(0) { -} - -ConcatenatingInputStream::~ConcatenatingInputStream() { -} - -bool ConcatenatingInputStream::Next(const void** data, int* size) { - while (stream_count_ > 0) { - if (streams_[0]->Next(data, size)) return true; - - // That stream is done. Advance to the next one. - bytes_retired_ += streams_[0]->ByteCount(); - ++streams_; - --stream_count_; - } - - // No more streams. - return false; -} - -void ConcatenatingInputStream::BackUp(int count) { - if (stream_count_ > 0) { - streams_[0]->BackUp(count); - } else { - GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next()."; - } -} - -bool ConcatenatingInputStream::Skip(int count) { - while (stream_count_ > 0) { - // Assume that ByteCount() can be used to find out how much we actually - // skipped when Skip() fails. - int64 target_byte_count = streams_[0]->ByteCount() + count; - if (streams_[0]->Skip(count)) return true; - - // Hit the end of the stream. Figure out how many more bytes we still have - // to skip. - int64 final_byte_count = streams_[0]->ByteCount(); - GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); - count = target_byte_count - final_byte_count; - - // That stream is done. Advance to the next one. - bytes_retired_ += final_byte_count; - ++streams_; - --stream_count_; - } - - return false; -} - -int64 ConcatenatingInputStream::ByteCount() const { - if (stream_count_ == 0) { - return bytes_retired_; - } else { - return bytes_retired_ + streams_[0]->ByteCount(); - } -} - - -// =================================================================== - -LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, - int64 limit) - : input_(input), limit_(limit) {} - -LimitingInputStream::~LimitingInputStream() { - // If we overshot the limit, back up. - if (limit_ < 0) input_->BackUp(-limit_); -} - -bool LimitingInputStream::Next(const void** data, int* size) { - if (limit_ <= 0) return false; - if (!input_->Next(data, size)) return false; - - limit_ -= *size; - if (limit_ < 0) { - // We overshot the limit. Reduce *size to hide the rest of the buffer. - *size += limit_; - } - return true; -} - -void LimitingInputStream::BackUp(int count) { - if (limit_ < 0) { - input_->BackUp(count - limit_); - limit_ = count; - } else { - input_->BackUp(count); - limit_ += count; - } -} - -bool LimitingInputStream::Skip(int count) { - if (count > limit_) { - if (limit_ < 0) return false; - input_->Skip(limit_); - limit_ = 0; - return false; - } else { - if (!input_->Skip(count)) return false; - limit_ -= count; - return true; - } -} - -int64 LimitingInputStream::ByteCount() const { - if (limit_ < 0) { - return input_->ByteCount() + limit_; - } else { - return input_->ByteCount(); - } -} - - -// =================================================================== - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.h b/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.h deleted file mode 100644 index 9fedb005..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl.h +++ /dev/null @@ -1,357 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains common implementations of the interfaces defined in -// zero_copy_stream.h which are only included in the full (non-lite) -// protobuf library. These implementations include Unix file descriptors -// and C++ iostreams. See also: zero_copy_stream_impl_lite.h - -#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ -#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ - -#include -#include -#include -#include -#include - - -namespace google { -namespace protobuf { -namespace io { - - -// =================================================================== - -// A ZeroCopyInputStream which reads from a file descriptor. -// -// FileInputStream is preferred over using an ifstream with IstreamInputStream. -// The latter will introduce an extra layer of buffering, harming performance. -// Also, it's conceivable that FileInputStream could someday be enhanced -// to use zero-copy file descriptors on OSs which support them. -class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given Unix file descriptor. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. - explicit FileInputStream(int file_descriptor, int block_size = -1); - ~FileInputStream(); - - // Flushes any buffers and closes the underlying file. Returns false if - // an error occurs during the process; use GetErrno() to examine the error. - // Even if an error occurs, the file descriptor is closed when this returns. - bool Close(); - - // By default, the file descriptor is not closed when the stream is - // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: - // This leaves no way for the caller to detect if close() fails. If - // detecting close() errors is important to you, you should arrange - // to close the descriptor yourself. - void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } - - // If an I/O error has occurred on this file descriptor, this is the - // errno from that error. Otherwise, this is zero. Once an error - // occurs, the stream is broken and all subsequent operations will - // fail. - int GetErrno() { return copying_input_.GetErrno(); } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { - public: - CopyingFileInputStream(int file_descriptor); - ~CopyingFileInputStream(); - - bool Close(); - void SetCloseOnDelete(bool value) { close_on_delete_ = value; } - int GetErrno() { return errno_; } - - // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); - int Skip(int count); - - private: - // The file descriptor. - const int file_; - bool close_on_delete_; - bool is_closed_; - - // The errno of the I/O error, if one has occurred. Otherwise, zero. - int errno_; - - // Did we try to seek once and fail? If so, we assume this file descriptor - // doesn't support seeking and won't try again. - bool previous_seek_failed_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); - }; - - CopyingFileInputStream copying_input_; - CopyingInputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which writes to a file descriptor. -// -// FileOutputStream is preferred over using an ofstream with -// OstreamOutputStream. The latter will introduce an extra layer of buffering, -// harming performance. Also, it's conceivable that FileOutputStream could -// someday be enhanced to use zero-copy file descriptors on OSs which -// support them. -class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given Unix file descriptor. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit FileOutputStream(int file_descriptor, int block_size = -1); - ~FileOutputStream(); - - // Flushes any buffers and closes the underlying file. Returns false if - // an error occurs during the process; use GetErrno() to examine the error. - // Even if an error occurs, the file descriptor is closed when this returns. - bool Close(); - - // Flushes FileOutputStream's buffers but does not close the - // underlying file. No special measures are taken to ensure that - // underlying operating system file object is synchronized to disk. - bool Flush(); - - // By default, the file descriptor is not closed when the stream is - // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: - // This leaves no way for the caller to detect if close() fails. If - // detecting close() errors is important to you, you should arrange - // to close the descriptor yourself. - void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } - - // If an I/O error has occurred on this file descriptor, this is the - // errno from that error. Otherwise, this is zero. Once an error - // occurs, the stream is broken and all subsequent operations will - // fail. - int GetErrno() { return copying_output_.GetErrno(); } - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { - public: - CopyingFileOutputStream(int file_descriptor); - ~CopyingFileOutputStream(); - - bool Close(); - void SetCloseOnDelete(bool value) { close_on_delete_ = value; } - int GetErrno() { return errno_; } - - // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); - - private: - // The file descriptor. - const int file_; - bool close_on_delete_; - bool is_closed_; - - // The errno of the I/O error, if one has occurred. Otherwise, zero. - int errno_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); - }; - - CopyingFileOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which reads from a C++ istream. -// -// Note that for reading files (or anything represented by a file descriptor), -// FileInputStream is more efficient. -class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given C++ istream. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. - explicit IstreamInputStream(istream* stream, int block_size = -1); - ~IstreamInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { - public: - CopyingIstreamInputStream(istream* input); - ~CopyingIstreamInputStream(); - - // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); - // (We use the default implementation of Skip().) - - private: - // The stream. - istream* input_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); - }; - - CopyingIstreamInputStream copying_input_; - CopyingInputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which writes to a C++ ostream. -// -// Note that for writing files (or anything represented by a file descriptor), -// FileOutputStream is more efficient. -class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given C++ ostream. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit OstreamOutputStream(ostream* stream, int block_size = -1); - ~OstreamOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { - public: - CopyingOstreamOutputStream(ostream* output); - ~CopyingOstreamOutputStream(); - - // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); - - private: - // The stream. - ostream* output_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); - }; - - CopyingOstreamOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which reads from several other streams in sequence. -// ConcatenatingInputStream is unable to distinguish between end-of-stream -// and read errors in the underlying streams, so it assumes any errors mean -// end-of-stream. So, if the underlying streams fail for any other reason, -// ConcatenatingInputStream may do odd things. It is suggested that you do -// not use ConcatenatingInputStream on streams that might produce read errors -// other than end-of-stream. -class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { - public: - // All streams passed in as well as the array itself must remain valid - // until the ConcatenatingInputStream is destroyed. - ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); - ~ConcatenatingInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - // As streams are retired, streams_ is incremented and count_ is - // decremented. - ZeroCopyInputStream* const* streams_; - int stream_count_; - int64 bytes_retired_; // Bytes read from previous streams. - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which wraps some other stream and limits it to -// a particular byte count. -class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { - public: - LimitingInputStream(ZeroCopyInputStream* input, int64 limit); - ~LimitingInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - ZeroCopyInputStream* input_; - int64 limit_; // Decreases as we go, becomes negative if we overshoot. - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); -}; - -// =================================================================== - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.cc b/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.cc deleted file mode 100644 index e8012510..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ /dev/null @@ -1,393 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { - -namespace { - -// Default block size for Copying{In,Out}putStreamAdaptor. -static const int kDefaultBlockSize = 8192; - -} // namespace - -// =================================================================== - -ArrayInputStream::ArrayInputStream(const void* data, int size, - int block_size) - : data_(reinterpret_cast(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayInputStream::~ArrayInputStream() { -} - -bool ArrayInputStream::Next(const void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayInputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -bool ArrayInputStream::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - last_returned_size_ = 0; // Don't let caller back up. - if (count > size_ - position_) { - position_ = size_; - return false; - } else { - position_ += count; - return true; - } -} - -int64 ArrayInputStream::ByteCount() const { - return position_; -} - - -// =================================================================== - -ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) - : data_(reinterpret_cast(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayOutputStream::~ArrayOutputStream() { -} - -bool ArrayOutputStream::Next(void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayOutputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -int64 ArrayOutputStream::ByteCount() const { - return position_; -} - -// =================================================================== - -StringOutputStream::StringOutputStream(string* target) - : target_(target) { -} - -StringOutputStream::~StringOutputStream() { -} - -bool StringOutputStream::Next(void** data, int* size) { - int old_size = target_->size(); - - // Grow the string. - if (old_size < target_->capacity()) { - // Resize the string to match its capacity, since we can get away - // without a memory allocation this way. - STLStringResizeUninitialized(target_, target_->capacity()); - } else { - // Size has reached capacity, so double the size. Also make sure - // that the new size is at least kMinimumSize. - STLStringResizeUninitialized( - target_, - max(old_size * 2, - kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. - } - - *data = string_as_array(target_) + old_size; - *size = target_->size() - old_size; - return true; -} - -void StringOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_LE(count, target_->size()); - target_->resize(target_->size() - count); -} - -int64 StringOutputStream::ByteCount() const { - return target_->size(); -} - -// =================================================================== - -CopyingInputStream::~CopyingInputStream() {} - -int CopyingInputStream::Skip(int count) { - char junk[4096]; - int skipped = 0; - while (skipped < count) { - int bytes = Read(junk, min(count - skipped, - implicit_cast(sizeof(junk)))); - if (bytes <= 0) { - // EOF or read error. - return skipped; - } - skipped += bytes; - } - return skipped; -} - -CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( - CopyingInputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0), - backup_bytes_(0) { -} - -CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { - if (failed_) { - // Already failed on a previous read. - return false; - } - - AllocateBufferIfNeeded(); - - if (backup_bytes_ > 0) { - // We have data left over from a previous BackUp(), so just return that. - *data = buffer_.get() + buffer_used_ - backup_bytes_; - *size = backup_bytes_; - backup_bytes_ = 0; - return true; - } - - // Read new data into the buffer. - buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); - if (buffer_used_ <= 0) { - // EOF or read error. We don't need the buffer anymore. - if (buffer_used_ < 0) { - // Read error (not EOF). - failed_ = true; - } - FreeBuffer(); - return false; - } - position_ += buffer_used_; - - *size = buffer_used_; - *data = buffer_.get(); - return true; -} - -void CopyingInputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - GOOGLE_CHECK_GE(count, 0) - << " Parameter to BackUp() can't be negative."; - - backup_bytes_ = count; -} - -bool CopyingInputStreamAdaptor::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - - if (failed_) { - // Already failed on a previous read. - return false; - } - - // First skip any bytes left over from a previous BackUp(). - if (backup_bytes_ >= count) { - // We have more data left over than we're trying to skip. Just chop it. - backup_bytes_ -= count; - return true; - } - - count -= backup_bytes_; - backup_bytes_ = 0; - - int skipped = copying_stream_->Skip(count); - position_ += skipped; - return skipped == count; -} - -int64 CopyingInputStreamAdaptor::ByteCount() const { - return position_ - backup_bytes_; -} - -void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_.get() == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingInputStreamAdaptor::FreeBuffer() { - GOOGLE_CHECK_EQ(backup_bytes_, 0); - buffer_used_ = 0; - buffer_.reset(); -} - -// =================================================================== - -CopyingOutputStream::~CopyingOutputStream() {} - -CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( - CopyingOutputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0) { -} - -CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { - WriteBuffer(); - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingOutputStreamAdaptor::Flush() { - return WriteBuffer(); -} - -bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { - if (buffer_used_ == buffer_size_) { - if (!WriteBuffer()) return false; - } - - AllocateBufferIfNeeded(); - - *data = buffer_.get() + buffer_used_; - *size = buffer_size_ - buffer_used_; - buffer_used_ = buffer_size_; - return true; -} - -void CopyingOutputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - - buffer_used_ -= count; -} - -int64 CopyingOutputStreamAdaptor::ByteCount() const { - return position_ + buffer_used_; -} - -bool CopyingOutputStreamAdaptor::WriteBuffer() { - if (failed_) { - // Already failed on a previous write. - return false; - } - - if (buffer_used_ == 0) return true; - - if (copying_stream_->Write(buffer_.get(), buffer_used_)) { - position_ += buffer_used_; - buffer_used_ = 0; - return true; - } else { - failed_ = true; - FreeBuffer(); - return false; - } -} - -void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_ == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingOutputStreamAdaptor::FreeBuffer() { - buffer_used_ = 0; - buffer_.reset(); -} - -// =================================================================== - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.h b/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.h deleted file mode 100644 index 153f543e..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream_impl_lite.h +++ /dev/null @@ -1,340 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains common implementations of the interfaces defined in -// zero_copy_stream.h which are included in the "lite" protobuf library. -// These implementations cover I/O on raw arrays and strings, as well as -// adaptors which make it easy to implement streams based on traditional -// streams. Of course, many users will probably want to write their own -// implementations of these interfaces specific to the particular I/O -// abstractions they prefer to use, but these should cover the most common -// cases. - -#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ -#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ - -#include -#include -#include -#include - - -namespace google { -namespace protobuf { -namespace io { - -// =================================================================== - -// A ZeroCopyInputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { - public: - // Create an InputStream that returns the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayInputStream(const void* data, int size, int block_size = -1); - ~ArrayInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - const uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { - public: - // Create an OutputStream that writes to the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayOutputStream(void* data, int size, int block_size = -1); - ~ArrayOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which appends bytes to a string. -class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { - public: - // Create a StringOutputStream which appends bytes to the given string. - // The string remains property of the caller, but it MUST NOT be accessed - // in any way until the stream is destroyed. - // - // Hint: If you call target->reserve(n) before creating the stream, - // the first call to Next() will return at least n bytes of buffer - // space. - explicit StringOutputStream(string* target); - ~StringOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - static const int kMinimumSize = 16; - - string* target_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); -}; - -// Note: There is no StringInputStream. Instead, just create an -// ArrayInputStream as follows: -// ArrayInputStream input(str.data(), str.size()); - -// =================================================================== - -// A generic traditional input stream interface. -// -// Lots of traditional input streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every read -// involves copying bytes into a buffer. If you want to take such an -// interface and make a ZeroCopyInputStream based on it, simply implement -// CopyingInputStream and then use CopyingInputStreamAdaptor. -// -// CopyingInputStream implementations should avoid buffering if possible. -// CopyingInputStreamAdaptor does its own buffering and will read data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingInputStream { - public: - virtual ~CopyingInputStream(); - - // Reads up to "size" bytes into the given buffer. Returns the number of - // bytes read. Read() waits until at least one byte is available, or - // returns zero if no bytes will ever become available (EOF), or -1 if a - // permanent read error occurred. - virtual int Read(void* buffer, int size) = 0; - - // Skips the next "count" bytes of input. Returns the number of bytes - // actually skipped. This will always be exactly equal to "count" unless - // EOF was reached or a permanent read error occurred. - // - // The default implementation just repeatedly calls Read() into a scratch - // buffer. - virtual int Skip(int count); -}; - -// A ZeroCopyInputStream which reads from a CopyingInputStream. This is -// useful for implementing ZeroCopyInputStreams that read from traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to read from file descriptors or C++ istreams, this is -// already implemented for you: use FileInputStream or IstreamInputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given CopyingInputStream. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. The caller retains ownership of - // copying_stream unless SetOwnsCopyingStream(true) is called. - explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, - int block_size = -1); - ~CopyingInputStreamAdaptor(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to - // delete the underlying CopyingInputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer and resets buffer_used_. - void FreeBuffer(); - - // The underlying copying stream. - CopyingInputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started reading. - int64 position_; - - // Data is read into this buffer. It may be NULL if no buffer is currently - // in use. Otherwise, it points to an array of size buffer_size_. - scoped_array buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - // Number of bytes in the buffer which were backed up over by a call to - // BackUp(). These need to be returned again. - // 0 <= backup_bytes_ <= buffer_used_ - int backup_bytes_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); -}; - -// =================================================================== - -// A generic traditional output stream interface. -// -// Lots of traditional output streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every write -// involves copying bytes from a buffer. If you want to take such an -// interface and make a ZeroCopyOutputStream based on it, simply implement -// CopyingOutputStream and then use CopyingOutputStreamAdaptor. -// -// CopyingOutputStream implementations should avoid buffering if possible. -// CopyingOutputStreamAdaptor does its own buffering and will write data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingOutputStream { - public: - virtual ~CopyingOutputStream(); - - // Writes "size" bytes from the given buffer to the output. Returns true - // if successful, false on a write error. - virtual bool Write(const void* buffer, int size) = 0; -}; - -// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is -// useful for implementing ZeroCopyOutputStreams that write to traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to write to file descriptors or C++ ostreams, this is -// already implemented for you: use FileOutputStream or OstreamOutputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given Unix file descriptor. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, - int block_size = -1); - ~CopyingOutputStreamAdaptor(); - - // Writes all pending data to the underlying stream. Returns false if a - // write error occurred on the underlying stream. (The underlying - // stream itself is not necessarily flushed.) - bool Flush(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to - // delete the underlying CopyingOutputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - // Write the current buffer, if it is present. - bool WriteBuffer(); - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer. - void FreeBuffer(); - - // The underlying copying stream. - CopyingOutputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started writing. - int64 position_; - - // Data is written from this buffer. It may be NULL if no buffer is - // currently in use. Otherwise, it points to an array of size buffer_size_. - scoped_array buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). When BackUp() is called, we just reduce this. - // 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); -}; - -// =================================================================== - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ diff --git a/Resources/NetHook/google/protobuf/io/zero_copy_stream_unittest.cc b/Resources/NetHook/google/protobuf/io/zero_copy_stream_unittest.cc deleted file mode 100644 index 8229ee6d..00000000 --- a/Resources/NetHook/google/protobuf/io/zero_copy_stream_unittest.cc +++ /dev/null @@ -1,721 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Testing strategy: For each type of I/O (array, string, file, etc.) we -// create an output stream and write some data to it, then create a -// corresponding input stream to read the same data back and expect it to -// match. When the data is written, it is written in several small chunks -// of varying sizes, with a BackUp() after each chunk. It is read back -// similarly, but with chunks separated at different points. The whole -// process is run with a variety of block sizes for both the input and -// the output. -// -// TODO(kenton): Rewrite this test to bring it up to the standards of all -// the other proto2 tests. May want to wait for gTest to implement -// "parametized tests" so that one set of tests can be used on all the -// implementations. - -#include "config.h" - -#ifdef _MSC_VER -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include - -#include - -#if HAVE_ZLIB -#include -#endif - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace io { -namespace { - -#ifdef _WIN32 -#define pipe(fds) _pipe(fds, 4096, O_BINARY) -#endif - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -class IoTest : public testing::Test { - protected: - // Test helpers. - - // Helper to write an array of data to an output stream. - bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size); - // Helper to read a fixed-length array of data from an input stream. - int ReadFromInput(ZeroCopyInputStream* input, void* data, int size); - // Write a string to the output stream. - void WriteString(ZeroCopyOutputStream* output, const string& str); - // Read a number of bytes equal to the size of the given string and checks - // that it matches the string. - void ReadString(ZeroCopyInputStream* input, const string& str); - // Writes some text to the output stream in a particular order. Returns - // the number of bytes written, incase the caller needs that to set up an - // input stream. - int WriteStuff(ZeroCopyOutputStream* output); - // Reads text from an input stream and expects it to match what - // WriteStuff() writes. - void ReadStuff(ZeroCopyInputStream* input); - - // Similar to WriteStuff, but performs more sophisticated testing. - int WriteStuffLarge(ZeroCopyOutputStream* output); - // Reads and tests a stream that should have been written to - // via WriteStuffLarge(). - void ReadStuffLarge(ZeroCopyInputStream* input); - -#if HAVE_ZLIB - string Compress(const string& data, const GzipOutputStream::Options& options); - string Uncompress(const string& data); -#endif - - static const int kBlockSizes[]; - static const int kBlockSizeCount; -}; - -const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64}; -const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes); - -bool IoTest::WriteToOutput(ZeroCopyOutputStream* output, - const void* data, int size) { - const uint8* in = reinterpret_cast(data); - int in_size = size; - - void* out; - int out_size; - - while (true) { - if (!output->Next(&out, &out_size)) { - return false; - } - EXPECT_GT(out_size, 0); - - if (in_size <= out_size) { - memcpy(out, in, in_size); - output->BackUp(out_size - in_size); - return true; - } - - memcpy(out, in, out_size); - in += out_size; - in_size -= out_size; - } -} - -#define MAX_REPEATED_ZEROS 100 - -int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) { - uint8* out = reinterpret_cast(data); - int out_size = size; - - const void* in; - int in_size = 0; - - int repeated_zeros = 0; - - while (true) { - if (!input->Next(&in, &in_size)) { - return size - out_size; - } - EXPECT_GT(in_size, -1); - if (in_size == 0) { - repeated_zeros++; - } else { - repeated_zeros = 0; - } - EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS); - - if (out_size <= in_size) { - memcpy(out, in, out_size); - if (in_size > out_size) { - input->BackUp(in_size - out_size); - } - return size; // Copied all of it. - } - - memcpy(out, in, in_size); - out += in_size; - out_size -= in_size; - } -} - -void IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) { - EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size())); -} - -void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) { - scoped_array buffer(new char[str.size() + 1]); - buffer[str.size()] = '\0'; - EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size()); - EXPECT_STREQ(str.c_str(), buffer.get()); -} - -int IoTest::WriteStuff(ZeroCopyOutputStream* output) { - WriteString(output, "Hello world!\n"); - WriteString(output, "Some te"); - WriteString(output, "xt. Blah blah."); - WriteString(output, "abcdefg"); - WriteString(output, "01234567890123456789"); - WriteString(output, "foobar"); - - EXPECT_EQ(output->ByteCount(), 68); - - int result = output->ByteCount(); - return result; -} - -// Reads text from an input stream and expects it to match what WriteStuff() -// writes. -void IoTest::ReadStuff(ZeroCopyInputStream* input) { - ReadString(input, "Hello world!\n"); - ReadString(input, "Some text. "); - ReadString(input, "Blah "); - ReadString(input, "blah."); - ReadString(input, "abcdefg"); - EXPECT_TRUE(input->Skip(20)); - ReadString(input, "foo"); - ReadString(input, "bar"); - - EXPECT_EQ(input->ByteCount(), 68); - - uint8 byte; - EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); -} - -int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) { - WriteString(output, "Hello world!\n"); - WriteString(output, "Some te"); - WriteString(output, "xt. Blah blah."); - WriteString(output, string(100000, 'x')); // A very long string - WriteString(output, string(100000, 'y')); // A very long string - WriteString(output, "01234567890123456789"); - - EXPECT_EQ(output->ByteCount(), 200055); - - int result = output->ByteCount(); - return result; -} - -// Reads text from an input stream and expects it to match what WriteStuff() -// writes. -void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) { - ReadString(input, "Hello world!\nSome text. "); - EXPECT_TRUE(input->Skip(5)); - ReadString(input, "blah."); - EXPECT_TRUE(input->Skip(100000 - 10)); - ReadString(input, string(10, 'x') + string(100000 - 20000, 'y')); - EXPECT_TRUE(input->Skip(20000 - 10)); - ReadString(input, "yyyyyyyyyy01234567890123456789"); - - EXPECT_EQ(input->ByteCount(), 200055); - - uint8 byte; - EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); -} - -// =================================================================== - -TEST_F(IoTest, ArrayIo) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - int size; - { - ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - size = WriteStuff(&output); - } - { - ArrayInputStream input(buffer, size, kBlockSizes[j]); - ReadStuff(&input); - } - } - } -} - -#if HAVE_ZLIB -TEST_F(IoTest, GzipIo) { - const int kBufferSize = 2*1024; - uint8* buffer = new uint8[kBufferSize]; - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - for (int z = 0; z < kBlockSizeCount; z++) { - int gzip_buffer_size = kBlockSizes[z]; - int size; - { - ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - GzipOutputStream gzout( - &output, GzipOutputStream::GZIP, gzip_buffer_size); - WriteStuff(&gzout); - gzout.Close(); - size = output.ByteCount(); - } - { - ArrayInputStream input(buffer, size, kBlockSizes[j]); - GzipInputStream gzin( - &input, GzipInputStream::GZIP, gzip_buffer_size); - ReadStuff(&gzin); - } - } - } - } - delete [] buffer; -} - -TEST_F(IoTest, ZlibIo) { - const int kBufferSize = 2*1024; - uint8* buffer = new uint8[kBufferSize]; - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - for (int z = 0; z < kBlockSizeCount; z++) { - int gzip_buffer_size = kBlockSizes[z]; - int size; - { - ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - GzipOutputStream gzout( - &output, GzipOutputStream::ZLIB, gzip_buffer_size); - WriteStuff(&gzout); - gzout.Close(); - size = output.ByteCount(); - } - { - ArrayInputStream input(buffer, size, kBlockSizes[j]); - GzipInputStream gzin( - &input, GzipInputStream::ZLIB, gzip_buffer_size); - ReadStuff(&gzin); - } - } - } - } - delete [] buffer; -} - -TEST_F(IoTest, ZlibIoInputAutodetect) { - const int kBufferSize = 2*1024; - uint8* buffer = new uint8[kBufferSize]; - int size; - { - ArrayOutputStream output(buffer, kBufferSize); - GzipOutputStream gzout(&output, GzipOutputStream::ZLIB); - WriteStuff(&gzout); - gzout.Close(); - size = output.ByteCount(); - } - { - ArrayInputStream input(buffer, size); - GzipInputStream gzin(&input, GzipInputStream::AUTO); - ReadStuff(&gzin); - } - { - ArrayOutputStream output(buffer, kBufferSize); - GzipOutputStream gzout(&output, GzipOutputStream::GZIP); - WriteStuff(&gzout); - gzout.Close(); - size = output.ByteCount(); - } - { - ArrayInputStream input(buffer, size); - GzipInputStream gzin(&input, GzipInputStream::AUTO); - ReadStuff(&gzin); - } - delete [] buffer; -} - -string IoTest::Compress(const string& data, - const GzipOutputStream::Options& options) { - string result; - { - StringOutputStream output(&result); - GzipOutputStream gzout(&output, options); - WriteToOutput(&gzout, data.data(), data.size()); - } - return result; -} - -string IoTest::Uncompress(const string& data) { - string result; - { - ArrayInputStream input(data.data(), data.size()); - GzipInputStream gzin(&input); - const void* buffer; - int size; - while (gzin.Next(&buffer, &size)) { - result.append(reinterpret_cast(buffer), size); - } - } - return result; -} - -TEST_F(IoTest, CompressionOptions) { - // Some ad-hoc testing of compression options. - - string golden; - File::ReadFileToStringOrDie( - TestSourceDir() + "/google/protobuf/testdata/golden_message", - &golden); - - GzipOutputStream::Options options; - string gzip_compressed = Compress(golden, options); - - options.compression_level = 0; - string not_compressed = Compress(golden, options); - - // Try zlib compression for fun. - options = GzipOutputStream::Options(); - options.format = GzipOutputStream::ZLIB; - string zlib_compressed = Compress(golden, options); - - // Uncompressed should be bigger than the original since it should have some - // sort of header. - EXPECT_GT(not_compressed.size(), golden.size()); - - // Higher compression levels should result in smaller sizes. - EXPECT_LT(zlib_compressed.size(), not_compressed.size()); - - // ZLIB format should differ from GZIP format. - EXPECT_TRUE(zlib_compressed != gzip_compressed); - - // Everything should decompress correctly. - EXPECT_TRUE(Uncompress(not_compressed) == golden); - EXPECT_TRUE(Uncompress(gzip_compressed) == golden); - EXPECT_TRUE(Uncompress(zlib_compressed) == golden); -} -#endif - -// There is no string input, only string output. Also, it doesn't support -// explicit block sizes. So, we'll only run one test and we'll use -// ArrayInput to read back the results. -TEST_F(IoTest, StringIo) { - string str; - { - StringOutputStream output(&str); - WriteStuff(&output); - } - { - ArrayInputStream input(str.data(), str.size()); - ReadStuff(&input); - } -} - - -// To test files, we create a temporary file, write, read, truncate, repeat. -TEST_F(IoTest, FileIo) { - string filename = TestTempDir() + "/zero_copy_stream_test_file"; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - // Make a temporary file. - int file = - open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); - ASSERT_GE(file, 0); - - { - FileOutputStream output(file, kBlockSizes[i]); - WriteStuff(&output); - EXPECT_EQ(0, output.GetErrno()); - } - - // Rewind. - ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); - - { - FileInputStream input(file, kBlockSizes[j]); - ReadStuff(&input); - EXPECT_EQ(0, input.GetErrno()); - } - - close(file); - } - } -} - -#if HAVE_ZLIB -TEST_F(IoTest, GzipFileIo) { - string filename = TestTempDir() + "/zero_copy_stream_test_file"; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - // Make a temporary file. - int file = - open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); - ASSERT_GE(file, 0); - { - FileOutputStream output(file, kBlockSizes[i]); - GzipOutputStream gzout(&output); - WriteStuffLarge(&gzout); - gzout.Close(); - output.Flush(); - EXPECT_EQ(0, output.GetErrno()); - } - - // Rewind. - ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); - - { - FileInputStream input(file, kBlockSizes[j]); - GzipInputStream gzin(&input); - ReadStuffLarge(&gzin); - EXPECT_EQ(0, input.GetErrno()); - } - - close(file); - } - } -} -#endif - -// MSVC raises various debugging exceptions if we try to use a file -// descriptor of -1, defeating our tests below. This class will disable -// these debug assertions while in scope. -class MsvcDebugDisabler { - public: -#if defined(_MSC_VER) && _MSC_VER >= 1400 - MsvcDebugDisabler() { - old_handler_ = _set_invalid_parameter_handler(MyHandler); - old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); - } - ~MsvcDebugDisabler() { - old_handler_ = _set_invalid_parameter_handler(old_handler_); - old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_); - } - - static void MyHandler(const wchar_t *expr, - const wchar_t *func, - const wchar_t *file, - unsigned int line, - uintptr_t pReserved) { - // do nothing - } - - _invalid_parameter_handler old_handler_; - int old_mode_; -#else - // Dummy constructor and destructor to ensure that GCC doesn't complain - // that debug_disabler is an unused variable. - MsvcDebugDisabler() {} - ~MsvcDebugDisabler() {} -#endif -}; - -// Test that FileInputStreams report errors correctly. -TEST_F(IoTest, FileReadError) { - MsvcDebugDisabler debug_disabler; - - // -1 = invalid file descriptor. - FileInputStream input(-1); - - const void* buffer; - int size; - EXPECT_FALSE(input.Next(&buffer, &size)); - EXPECT_EQ(EBADF, input.GetErrno()); -} - -// Test that FileOutputStreams report errors correctly. -TEST_F(IoTest, FileWriteError) { - MsvcDebugDisabler debug_disabler; - - // -1 = invalid file descriptor. - FileOutputStream input(-1); - - void* buffer; - int size; - - // The first call to Next() succeeds because it doesn't have anything to - // write yet. - EXPECT_TRUE(input.Next(&buffer, &size)); - - // Second call fails. - EXPECT_FALSE(input.Next(&buffer, &size)); - - EXPECT_EQ(EBADF, input.GetErrno()); -} - -// Pipes are not seekable, so File{Input,Output}Stream ends up doing some -// different things to handle them. We'll test by writing to a pipe and -// reading back from it. -TEST_F(IoTest, PipeIo) { - int files[2]; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - // Need to create a new pipe each time because ReadStuff() expects - // to see EOF at the end. - ASSERT_EQ(pipe(files), 0); - - { - FileOutputStream output(files[1], kBlockSizes[i]); - WriteStuff(&output); - EXPECT_EQ(0, output.GetErrno()); - } - close(files[1]); // Send EOF. - - { - FileInputStream input(files[0], kBlockSizes[j]); - ReadStuff(&input); - EXPECT_EQ(0, input.GetErrno()); - } - close(files[0]); - } - } -} - -// Test using C++ iostreams. -TEST_F(IoTest, IostreamIo) { - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - { - stringstream stream; - - { - OstreamOutputStream output(&stream, kBlockSizes[i]); - WriteStuff(&output); - EXPECT_FALSE(stream.fail()); - } - - { - IstreamInputStream input(&stream, kBlockSizes[j]); - ReadStuff(&input); - EXPECT_TRUE(stream.eof()); - } - } - - { - stringstream stream; - - { - OstreamOutputStream output(&stream, kBlockSizes[i]); - WriteStuffLarge(&output); - EXPECT_FALSE(stream.fail()); - } - - { - IstreamInputStream input(&stream, kBlockSizes[j]); - ReadStuffLarge(&input); - EXPECT_TRUE(stream.eof()); - } - } - } - } -} - -// To test ConcatenatingInputStream, we create several ArrayInputStreams -// covering a buffer and then concatenate them. -TEST_F(IoTest, ConcatenatingInputStream) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - // Fill the buffer. - ArrayOutputStream output(buffer, kBufferSize); - WriteStuff(&output); - - // Now split it up into multiple streams of varying sizes. - ASSERT_EQ(68, output.ByteCount()); // Test depends on this. - ArrayInputStream input1(buffer , 12); - ArrayInputStream input2(buffer + 12, 7); - ArrayInputStream input3(buffer + 19, 6); - ArrayInputStream input4(buffer + 25, 15); - ArrayInputStream input5(buffer + 40, 0); - // Note: We want to make sure we have a stream boundary somewhere between - // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This - // tests that a bug that existed in the original code for Skip() is fixed. - ArrayInputStream input6(buffer + 40, 10); - ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes. - - ZeroCopyInputStream* streams[] = - {&input1, &input2, &input3, &input4, &input5, &input6, &input7}; - - // Create the concatenating stream and read. - ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams)); - ReadStuff(&input); -} - -// To test LimitingInputStream, we write our golden text to a buffer, then -// create an ArrayInputStream that contains the whole buffer (not just the -// bytes written), then use a LimitingInputStream to limit it just to the -// bytes written. -TEST_F(IoTest, LimitingInputStream) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - // Fill the buffer. - ArrayOutputStream output(buffer, kBufferSize); - WriteStuff(&output); - - // Set up input. - ArrayInputStream array_input(buffer, kBufferSize); - LimitingInputStream input(&array_input, output.ByteCount()); - - ReadStuff(&input); -} - -// Check that a zero-size array doesn't confuse the code. -TEST(ZeroSizeArray, Input) { - ArrayInputStream input(NULL, 0); - const void* data; - int size; - EXPECT_FALSE(input.Next(&data, &size)); -} - -TEST(ZeroSizeArray, Output) { - ArrayOutputStream output(NULL, 0); - void* data; - int size; - EXPECT_FALSE(output.Next(&data, &size)); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/lite_unittest.cc b/Resources/NetHook/google/protobuf/lite_unittest.cc deleted file mode 100644 index ffeec3c4..00000000 --- a/Resources/NetHook/google/protobuf/lite_unittest.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include -#include - -#include -#include - -using namespace std; - -int main(int argc, char* argv[]) { - string data, packed_data; - - { - protobuf_unittest::TestAllTypesLite message, message2, message3; - google::protobuf::TestUtilLite::ExpectClear(message); - google::protobuf::TestUtilLite::SetAllFields(&message); - message2.CopyFrom(message); - data = message.SerializeAsString(); - message3.ParseFromString(data); - google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); - google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); - google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); - google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); - google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); - message.Clear(); - google::protobuf::TestUtilLite::ExpectClear(message); - } - - { - protobuf_unittest::TestAllExtensionsLite message, message2, message3; - google::protobuf::TestUtilLite::ExpectExtensionsClear(message); - google::protobuf::TestUtilLite::SetAllExtensions(&message); - message2.CopyFrom(message); - string extensions_data = message.SerializeAsString(); - GOOGLE_CHECK(extensions_data == data); - message3.ParseFromString(extensions_data); - google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); - google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); - google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); - google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); - google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); - message.Clear(); - google::protobuf::TestUtilLite::ExpectExtensionsClear(message); - } - - { - protobuf_unittest::TestPackedTypesLite message, message2, message3; - google::protobuf::TestUtilLite::ExpectPackedClear(message); - google::protobuf::TestUtilLite::SetPackedFields(&message); - message2.CopyFrom(message); - packed_data = message.SerializeAsString(); - message3.ParseFromString(packed_data); - google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); - google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); - google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); - google::protobuf::TestUtilLite::ModifyPackedFields(&message); - google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); - message.Clear(); - google::protobuf::TestUtilLite::ExpectPackedClear(message); - } - - { - protobuf_unittest::TestPackedExtensionsLite message, message2, message3; - google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); - google::protobuf::TestUtilLite::SetPackedExtensions(&message); - message2.CopyFrom(message); - string packed_extensions_data = message.SerializeAsString(); - GOOGLE_CHECK(packed_extensions_data == packed_data); - message3.ParseFromString(packed_extensions_data); - google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); - google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); - google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); - google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); - google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); - message.Clear(); - google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); - } - - cout << "PASS" << endl; - return 0; -} diff --git a/Resources/NetHook/google/protobuf/message.cc b/Resources/NetHook/google/protobuf/message.cc deleted file mode 100644 index 91e6878e..00000000 --- a/Resources/NetHook/google/protobuf/message.cc +++ /dev/null @@ -1,318 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -using internal::WireFormat; -using internal::ReflectionOps; - -Message::~Message() {} - -void Message::MergeFrom(const Message& from) { - const Descriptor* descriptor = GetDescriptor(); - GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) - << ": Tried to merge from a message with a different type. " - "to: " << descriptor->full_name() << ", " - "from:" << from.GetDescriptor()->full_name(); - ReflectionOps::Merge(from, this); -} - -void Message::CheckTypeAndMergeFrom(const MessageLite& other) { - MergeFrom(*down_cast(&other)); -} - -void Message::CopyFrom(const Message& from) { - const Descriptor* descriptor = GetDescriptor(); - GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) - << ": Tried to copy from a message with a different type." - "to: " << descriptor->full_name() << ", " - "from:" << from.GetDescriptor()->full_name(); - ReflectionOps::Copy(from, this); -} - -string Message::GetTypeName() const { - return GetDescriptor()->full_name(); -} - -void Message::Clear() { - ReflectionOps::Clear(this); -} - -bool Message::IsInitialized() const { - return ReflectionOps::IsInitialized(*this); -} - -void Message::FindInitializationErrors(vector* errors) const { - return ReflectionOps::FindInitializationErrors(*this, "", errors); -} - -string Message::InitializationErrorString() const { - vector errors; - FindInitializationErrors(&errors); - return JoinStrings(errors, ", "); -} - -void Message::CheckInitialized() const { - GOOGLE_CHECK(IsInitialized()) - << "Message of type \"" << GetDescriptor()->full_name() - << "\" is missing required fields: " << InitializationErrorString(); -} - -void Message::DiscardUnknownFields() { - return ReflectionOps::DiscardUnknownFields(this); -} - -bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) { - return WireFormat::ParseAndMergePartial(input, this); -} - -bool Message::ParseFromFileDescriptor(int file_descriptor) { - io::FileInputStream input(file_descriptor); - return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; -} - -bool Message::ParsePartialFromFileDescriptor(int file_descriptor) { - io::FileInputStream input(file_descriptor); - return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0; -} - -bool Message::ParseFromIstream(istream* input) { - io::IstreamInputStream zero_copy_input(input); - return ParseFromZeroCopyStream(&zero_copy_input) && input->eof(); -} - -bool Message::ParsePartialFromIstream(istream* input) { - io::IstreamInputStream zero_copy_input(input); - return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof(); -} - - -void Message::SerializeWithCachedSizes( - io::CodedOutputStream* output) const { - WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); -} - -int Message::ByteSize() const { - int size = WireFormat::ByteSize(*this); - SetCachedSize(size); - return size; -} - -void Message::SetCachedSize(int size) const { - GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name() - << "\" implements neither SetCachedSize() nor ByteSize(). " - "Must implement one or the other."; -} - -int Message::SpaceUsed() const { - return GetReflection()->SpaceUsed(*this); -} - -bool Message::SerializeToFileDescriptor(int file_descriptor) const { - io::FileOutputStream output(file_descriptor); - return SerializeToZeroCopyStream(&output); -} - -bool Message::SerializePartialToFileDescriptor(int file_descriptor) const { - io::FileOutputStream output(file_descriptor); - return SerializePartialToZeroCopyStream(&output); -} - -bool Message::SerializeToOstream(ostream* output) const { - { - io::OstreamOutputStream zero_copy_output(output); - if (!SerializeToZeroCopyStream(&zero_copy_output)) return false; - } - return output->good(); -} - -bool Message::SerializePartialToOstream(ostream* output) const { - io::OstreamOutputStream zero_copy_output(output); - return SerializePartialToZeroCopyStream(&zero_copy_output); -} - - -Reflection::~Reflection() {} - -// =================================================================== -// MessageFactory - -MessageFactory::~MessageFactory() {} - -namespace { - -class GeneratedMessageFactory : public MessageFactory { - public: - GeneratedMessageFactory(); - ~GeneratedMessageFactory(); - - static GeneratedMessageFactory* singleton(); - - typedef void RegistrationFunc(const string&); - void RegisterFile(const char* file, RegistrationFunc* registration_func); - void RegisterType(const Descriptor* descriptor, const Message* prototype); - - // implements MessageFactory --------------------------------------- - const Message* GetPrototype(const Descriptor* type); - - private: - // Only written at static init time, so does not require locking. - hash_map, streq> file_map_; - - // Initialized lazily, so requires locking. - Mutex mutex_; - hash_map type_map_; -}; - -GeneratedMessageFactory* generated_message_factory_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_); - -void ShutdownGeneratedMessageFactory() { - delete generated_message_factory_; -} - -void InitGeneratedMessageFactory() { - generated_message_factory_ = new GeneratedMessageFactory; - internal::OnShutdown(&ShutdownGeneratedMessageFactory); -} - -GeneratedMessageFactory::GeneratedMessageFactory() {} -GeneratedMessageFactory::~GeneratedMessageFactory() {} - -GeneratedMessageFactory* GeneratedMessageFactory::singleton() { - ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_, - &InitGeneratedMessageFactory); - return generated_message_factory_; -} - -void GeneratedMessageFactory::RegisterFile( - const char* file, RegistrationFunc* registration_func) { - if (!InsertIfNotPresent(&file_map_, file, registration_func)) { - GOOGLE_LOG(FATAL) << "File is already registered: " << file; - } -} - -void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, - const Message* prototype) { - GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool()) - << "Tried to register a non-generated type with the generated " - "type registry."; - - // This should only be called as a result of calling a file registration - // function during GetPrototype(), in which case we already have locked - // the mutex. - mutex_.AssertHeld(); - if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) { - GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name(); - } -} - -const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { - { - ReaderMutexLock lock(&mutex_); - const Message* result = FindPtrOrNull(type_map_, type); - if (result != NULL) return result; - } - - // If the type is not in the generated pool, then we can't possibly handle - // it. - if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL; - - // Apparently the file hasn't been registered yet. Let's do that now. - RegistrationFunc* registration_func = - FindPtrOrNull(file_map_, type->file()->name().c_str()); - if (registration_func == NULL) { - GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't " - "registered: " << type->file()->name(); - return NULL; - } - - WriterMutexLock lock(&mutex_); - - // Check if another thread preempted us. - const Message* result = FindPtrOrNull(type_map_, type); - if (result == NULL) { - // Nope. OK, register everything. - registration_func(type->file()->name()); - // Should be here now. - result = FindPtrOrNull(type_map_, type); - } - - if (result == NULL) { - GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't " - << "registered: " << type->full_name(); - } - - return result; -} - -} // namespace - -MessageFactory* MessageFactory::generated_factory() { - return GeneratedMessageFactory::singleton(); -} - -void MessageFactory::InternalRegisterGeneratedFile( - const char* filename, void (*register_messages)(const string&)) { - GeneratedMessageFactory::singleton()->RegisterFile(filename, - register_messages); -} - -void MessageFactory::InternalRegisterGeneratedMessage( - const Descriptor* descriptor, const Message* prototype) { - GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype); -} - - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/message.h b/Resources/NetHook/google/protobuf/message.h deleted file mode 100644 index c0062f98..00000000 --- a/Resources/NetHook/google/protobuf/message.h +++ /dev/null @@ -1,710 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Defines Message, the abstract interface implemented by non-lite -// protocol message objects. Although it's possible to implement this -// interface manually, most users will use the protocol compiler to -// generate implementations. -// -// Example usage: -// -// Say you have a message defined as: -// -// message Foo { -// optional string text = 1; -// repeated int32 numbers = 2; -// } -// -// Then, if you used the protocol compiler to generate a class from the above -// definition, you could use it like so: -// -// string data; // Will store a serialized version of the message. -// -// { -// // Create a message and serialize it. -// Foo foo; -// foo.set_text("Hello World!"); -// foo.add_numbers(1); -// foo.add_numbers(5); -// foo.add_numbers(42); -// -// foo.SerializeToString(&data); -// } -// -// { -// // Parse the serialized message and check that it contains the -// // correct data. -// Foo foo; -// foo.ParseFromString(data); -// -// assert(foo.text() == "Hello World!"); -// assert(foo.numbers_size() == 3); -// assert(foo.numbers(0) == 1); -// assert(foo.numbers(1) == 5); -// assert(foo.numbers(2) == 42); -// } -// -// { -// // Same as the last block, but do it dynamically via the Message -// // reflection interface. -// Message* foo = new Foo; -// Descriptor* descriptor = foo->GetDescriptor(); -// -// // Get the descriptors for the fields we're interested in and verify -// // their types. -// FieldDescriptor* text_field = descriptor->FindFieldByName("text"); -// assert(text_field != NULL); -// assert(text_field->type() == FieldDescriptor::TYPE_STRING); -// assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL); -// FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers"); -// assert(numbers_field != NULL); -// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); -// assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED); -// -// // Parse the message. -// foo->ParseFromString(data); -// -// // Use the reflection interface to examine the contents. -// const Reflection* reflection = foo->GetReflection(); -// assert(reflection->GetString(foo, text_field) == "Hello World!"); -// assert(reflection->FieldSize(foo, numbers_field) == 3); -// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1); -// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5); -// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42); -// -// delete foo; -// } - -#ifndef GOOGLE_PROTOBUF_MESSAGE_H__ -#define GOOGLE_PROTOBUF_MESSAGE_H__ - -#include -#include - -#ifdef __DECCXX -// HP C++'s iosfwd doesn't work. -#include -#else -#include -#endif - -#include - -#include - -#if defined(_WIN32) && defined(GetMessage) -// windows.h defines GetMessage() as a macro. Let's re-define it as an inline -// function. This is necessary because Reflection has a method called -// GetMessage() which we don't want overridden. The inline function should be -// equivalent for C++ users. -inline BOOL GetMessage_Win32( - LPMSG lpMsg, HWND hWnd, - UINT wMsgFilterMin, UINT wMsgFilterMax) { - return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); -} -#undef GetMessage -inline BOOL GetMessage( - LPMSG lpMsg, HWND hWnd, - UINT wMsgFilterMin, UINT wMsgFilterMax) { - return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); -} -#endif - - -namespace google { -namespace protobuf { - -// Defined in this file. -class Message; -class Reflection; -class MessageFactory; - -// Defined in other files. -class Descriptor; // descriptor.h -class FieldDescriptor; // descriptor.h -class EnumDescriptor; // descriptor.h -class EnumValueDescriptor; // descriptor.h -namespace io { - class ZeroCopyInputStream; // zero_copy_stream.h - class ZeroCopyOutputStream; // zero_copy_stream.h - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h -} -class UnknownFieldSet; // unknown_field_set.h - -// A container to hold message metadata. -struct Metadata { - const Descriptor* descriptor; - const Reflection* reflection; -}; - -// Returns the EnumDescriptor for enum type E, which must be a -// proto-declared enum type. Code generated by the protocol compiler -// will include specializations of this template for each enum type declared. -template -const EnumDescriptor* GetEnumDescriptor(); - -// Abstract interface for protocol messages. -// -// See also MessageLite, which contains most every-day operations. Message -// adds descriptors and reflection on top of that. -// -// The methods of this class that are virtual but not pure-virtual have -// default implementations based on reflection. Message classes which are -// optimized for speed will want to override these with faster implementations, -// but classes optimized for code size may be happy with keeping them. See -// the optimize_for option in descriptor.proto. -class LIBPROTOBUF_EXPORT Message : public MessageLite { - public: - inline Message() {} - virtual ~Message(); - - // Basic Operations ------------------------------------------------ - - // Construct a new instance of the same type. Ownership is passed to the - // caller. (This is also defined in MessageLite, but is defined again here - // for return-type covariance.) - virtual Message* New() const = 0; - - // Make this message into a copy of the given message. The given message - // must have the same descriptor, but need not necessarily be the same class. - // By default this is just implemented as "Clear(); MergeFrom(from);". - virtual void CopyFrom(const Message& from); - - // Merge the fields from the given message into this message. Singular - // fields will be overwritten, except for embedded messages which will - // be merged. Repeated fields will be concatenated. The given message - // must be of the same type as this message (i.e. the exact same class). - virtual void MergeFrom(const Message& from); - - // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with - // a nice error message. - void CheckInitialized() const; - - // Slowly build a list of all required fields that are not set. - // This is much, much slower than IsInitialized() as it is implemented - // purely via reflection. Generally, you should not call this unless you - // have already determined that an error exists by calling IsInitialized(). - void FindInitializationErrors(vector* errors) const; - - // Like FindInitializationErrors, but joins all the strings, delimited by - // commas, and returns them. - string InitializationErrorString() const; - - // Clears all unknown fields from this message and all embedded messages. - // Normally, if unknown tag numbers are encountered when parsing a message, - // the tag and value are stored in the message's UnknownFieldSet and - // then written back out when the message is serialized. This allows servers - // which simply route messages to other servers to pass through messages - // that have new field definitions which they don't yet know about. However, - // this behavior can have security implications. To avoid it, call this - // method after parsing. - // - // See Reflection::GetUnknownFields() for more on unknown fields. - virtual void DiscardUnknownFields(); - - // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. The default implementation calls the - // Reflection object's SpaceUsed() method. - virtual int SpaceUsed() const; - - // Debugging & Testing---------------------------------------------- - - // Generates a human readable form of this message, useful for debugging - // and other purposes. - string DebugString() const; - // Like DebugString(), but with less whitespace. - string ShortDebugString() const; - // Like DebugString(), but do not escape UTF-8 byte sequences. - string Utf8DebugString() const; - // Convenience function useful in GDB. Prints DebugString() to stdout. - void PrintDebugString() const; - - // Heavy I/O ------------------------------------------------------- - // Additional parsing and serialization methods not implemented by - // MessageLite because they are not supported by the lite library. - - // Parse a protocol buffer from a file descriptor. If successful, the entire - // input will be consumed. - bool ParseFromFileDescriptor(int file_descriptor); - // Like ParseFromFileDescriptor(), but accepts messages that are missing - // required fields. - bool ParsePartialFromFileDescriptor(int file_descriptor); - // Parse a protocol buffer from a C++ istream. If successful, the entire - // input will be consumed. - bool ParseFromIstream(istream* input); - // Like ParseFromIstream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromIstream(istream* input); - - // Serialize the message and write it to the given file descriptor. All - // required fields must be set. - bool SerializeToFileDescriptor(int file_descriptor) const; - // Like SerializeToFileDescriptor(), but allows missing required fields. - bool SerializePartialToFileDescriptor(int file_descriptor) const; - // Serialize the message and write it to the given C++ ostream. All - // required fields must be set. - bool SerializeToOstream(ostream* output) const; - // Like SerializeToOstream(), but allows missing required fields. - bool SerializePartialToOstream(ostream* output) const; - - - // Reflection-based methods ---------------------------------------- - // These methods are pure-virtual in MessageLite, but Message provides - // reflection-based default implementations. - - virtual string GetTypeName() const; - virtual void Clear(); - virtual bool IsInitialized() const; - virtual void CheckTypeAndMergeFrom(const MessageLite& other); - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); - virtual int ByteSize() const; - virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; - - private: - // This is called only by the default implementation of ByteSize(), to - // update the cached size. If you override ByteSize(), you do not need - // to override this. If you do not override ByteSize(), you MUST override - // this; the default implementation will crash. - // - // The method is private because subclasses should never call it; only - // override it. Yes, C++ lets you do that. Crazy, huh? - virtual void SetCachedSize(int size) const; - - public: - - // Introspection --------------------------------------------------- - - // Typedef for backwards-compatibility. - typedef google::protobuf::Reflection Reflection; - - // Get a Descriptor for this message's type. This describes what - // fields the message contains, the types of those fields, etc. - const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } - - // Get the Reflection interface for this Message, which can be used to - // read and modify the fields of the Message dynamically (in other words, - // without knowing the message type at compile time). This object remains - // property of the Message. - // - // This method remains virtual in case a subclass does not implement - // reflection and wants to override the default behavior. - virtual const Reflection* GetReflection() const { - return GetMetadata().reflection; - } - - protected: - // Get a struct containing the metadata for the Message. Most subclasses only - // need to implement this method, rather than the GetDescriptor() and - // GetReflection() wrappers. - virtual Metadata GetMetadata() const = 0; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); -}; - -// This interface contains methods that can be used to dynamically access -// and modify the fields of a protocol message. Their semantics are -// similar to the accessors the protocol compiler generates. -// -// To get the Reflection for a given Message, call Message::GetReflection(). -// -// This interface is separate from Message only for efficiency reasons; -// the vast majority of implementations of Message will share the same -// implementation of Reflection (GeneratedMessageReflection, -// defined in generated_message.h), and all Messages of a particular class -// should share the same Reflection object (though you should not rely on -// the latter fact). -// -// There are several ways that these methods can be used incorrectly. For -// example, any of the following conditions will lead to undefined -// results (probably assertion failures): -// - The FieldDescriptor is not a field of this message type. -// - The method called is not appropriate for the field's type. For -// each field type in FieldDescriptor::TYPE_*, there is only one -// Get*() method, one Set*() method, and one Add*() method that is -// valid for that type. It should be obvious which (except maybe -// for TYPE_BYTES, which are represented using strings in C++). -// - A Get*() or Set*() method for singular fields is called on a repeated -// field. -// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated -// field. -// - The Message object passed to any method is not of the right type for -// this Reflection object (i.e. message.GetReflection() != reflection). -// -// You might wonder why there is not any abstract representation for a field -// of arbitrary type. E.g., why isn't there just a "GetField()" method that -// returns "const Field&", where "Field" is some class with accessors like -// "GetInt32Value()". The problem is that someone would have to deal with -// allocating these Field objects. For generated message classes, having to -// allocate space for an additional object to wrap every field would at least -// double the message's memory footprint, probably worse. Allocating the -// objects on-demand, on the other hand, would be expensive and prone to -// memory leaks. So, instead we ended up with this flat interface. -// -// TODO(kenton): Create a utility class which callers can use to read and -// write fields from a Reflection without paying attention to the type. -class LIBPROTOBUF_EXPORT Reflection { - public: - // TODO(kenton): Remove parameter. - inline Reflection() {} - virtual ~Reflection(); - - // Get the UnknownFieldSet for the message. This contains fields which - // were seen when the Message was parsed but were not recognized according - // to the Message's definition. - virtual const UnknownFieldSet& GetUnknownFields( - const Message& message) const = 0; - // Get a mutable pointer to the UnknownFieldSet for the message. This - // contains fields which were seen when the Message was parsed but were not - // recognized according to the Message's definition. - virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0; - - // Estimate the amount of memory used by the message object. - virtual int SpaceUsed(const Message& message) const = 0; - - // Check if the given non-repeated field is set. - virtual bool HasField(const Message& message, - const FieldDescriptor* field) const = 0; - - // Get the number of elements of a repeated field. - virtual int FieldSize(const Message& message, - const FieldDescriptor* field) const = 0; - - // Clear the value of a field, so that HasField() returns false or - // FieldSize() returns zero. - virtual void ClearField(Message* message, - const FieldDescriptor* field) const = 0; - - // Remove the last element of a repeated field. - // We don't provide a way to remove any element other than the last - // because it invites inefficient use, such as O(n^2) filtering loops - // that should have been O(n). If you want to remove an element other - // than the last, the best way to do it is to re-arrange the elements - // (using Swap()) so that the one you want removed is at the end, then - // call RemoveLast(). - virtual void RemoveLast(Message* message, - const FieldDescriptor* field) const = 0; - - // Swap the complete contents of two messages. - virtual void Swap(Message* message1, Message* message2) const = 0; - - // Swap two elements of a repeated field. - virtual void SwapElements(Message* message, - const FieldDescriptor* field, - int index1, - int index2) const = 0; - - // List all fields of the message which are currently set. This includes - // extensions. Singular fields will only be listed if HasField(field) would - // return true and repeated fields will only be listed if FieldSize(field) - // would return non-zero. Fields (both normal fields and extension fields) - // will be listed ordered by field number. - virtual void ListFields(const Message& message, - vector* output) const = 0; - - // Singular field getters ------------------------------------------ - // These get the value of a non-repeated field. They return the default - // value for fields that aren't set. - - virtual int32 GetInt32 (const Message& message, - const FieldDescriptor* field) const = 0; - virtual int64 GetInt64 (const Message& message, - const FieldDescriptor* field) const = 0; - virtual uint32 GetUInt32(const Message& message, - const FieldDescriptor* field) const = 0; - virtual uint64 GetUInt64(const Message& message, - const FieldDescriptor* field) const = 0; - virtual float GetFloat (const Message& message, - const FieldDescriptor* field) const = 0; - virtual double GetDouble(const Message& message, - const FieldDescriptor* field) const = 0; - virtual bool GetBool (const Message& message, - const FieldDescriptor* field) const = 0; - virtual string GetString(const Message& message, - const FieldDescriptor* field) const = 0; - virtual const EnumValueDescriptor* GetEnum( - const Message& message, const FieldDescriptor* field) const = 0; - // See MutableMessage() for the meaning of the "factory" parameter. - virtual const Message& GetMessage(const Message& message, - const FieldDescriptor* field, - MessageFactory* factory = NULL) const = 0; - - // Get a string value without copying, if possible. - // - // GetString() necessarily returns a copy of the string. This can be - // inefficient when the string is already stored in a string object in the - // underlying message. GetStringReference() will return a reference to the - // underlying string in this case. Otherwise, it will copy the string into - // *scratch and return that. - // - // Note: It is perfectly reasonable and useful to write code like: - // str = reflection->GetStringReference(field, &str); - // This line would ensure that only one copy of the string is made - // regardless of the field's underlying representation. When initializing - // a newly-constructed string, though, it's just as fast and more readable - // to use code like: - // string str = reflection->GetString(field); - virtual const string& GetStringReference(const Message& message, - const FieldDescriptor* field, - string* scratch) const = 0; - - - // Singular field mutators ----------------------------------------- - // These mutate the value of a non-repeated field. - - virtual void SetInt32 (Message* message, - const FieldDescriptor* field, int32 value) const = 0; - virtual void SetInt64 (Message* message, - const FieldDescriptor* field, int64 value) const = 0; - virtual void SetUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const = 0; - virtual void SetUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const = 0; - virtual void SetFloat (Message* message, - const FieldDescriptor* field, float value) const = 0; - virtual void SetDouble(Message* message, - const FieldDescriptor* field, double value) const = 0; - virtual void SetBool (Message* message, - const FieldDescriptor* field, bool value) const = 0; - virtual void SetString(Message* message, - const FieldDescriptor* field, - const string& value) const = 0; - virtual void SetEnum (Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const = 0; - // Get a mutable pointer to a field with a message type. If a MessageFactory - // is provided, it will be used to construct instances of the sub-message; - // otherwise, the default factory is used. If the field is an extension that - // does not live in the same pool as the containing message's descriptor (e.g. - // it lives in an overlay pool), then a MessageFactory must be provided. - // If you have no idea what that meant, then you probably don't need to worry - // about it (don't provide a MessageFactory). WARNING: If the - // FieldDescriptor is for a compiled-in extension, then - // factory->GetPrototype(field->message_type() MUST return an instance of the - // compiled-in class for this type, NOT DynamicMessage. - virtual Message* MutableMessage(Message* message, - const FieldDescriptor* field, - MessageFactory* factory = NULL) const = 0; - - - // Repeated field getters ------------------------------------------ - // These get the value of one element of a repeated field. - - virtual int32 GetRepeatedInt32 (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual int64 GetRepeatedInt64 (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual uint32 GetRepeatedUInt32(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual uint64 GetRepeatedUInt64(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual float GetRepeatedFloat (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual double GetRepeatedDouble(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual bool GetRepeatedBool (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual string GetRepeatedString(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual const EnumValueDescriptor* GetRepeatedEnum( - const Message& message, - const FieldDescriptor* field, int index) const = 0; - virtual const Message& GetRepeatedMessage( - const Message& message, - const FieldDescriptor* field, int index) const = 0; - - // See GetStringReference(), above. - virtual const string& GetRepeatedStringReference( - const Message& message, const FieldDescriptor* field, - int index, string* scratch) const = 0; - - - // Repeated field mutators ----------------------------------------- - // These mutate the value of one element of a repeated field. - - virtual void SetRepeatedInt32 (Message* message, - const FieldDescriptor* field, - int index, int32 value) const = 0; - virtual void SetRepeatedInt64 (Message* message, - const FieldDescriptor* field, - int index, int64 value) const = 0; - virtual void SetRepeatedUInt32(Message* message, - const FieldDescriptor* field, - int index, uint32 value) const = 0; - virtual void SetRepeatedUInt64(Message* message, - const FieldDescriptor* field, - int index, uint64 value) const = 0; - virtual void SetRepeatedFloat (Message* message, - const FieldDescriptor* field, - int index, float value) const = 0; - virtual void SetRepeatedDouble(Message* message, - const FieldDescriptor* field, - int index, double value) const = 0; - virtual void SetRepeatedBool (Message* message, - const FieldDescriptor* field, - int index, bool value) const = 0; - virtual void SetRepeatedString(Message* message, - const FieldDescriptor* field, - int index, const string& value) const = 0; - virtual void SetRepeatedEnum(Message* message, - const FieldDescriptor* field, int index, - const EnumValueDescriptor* value) const = 0; - // Get a mutable pointer to an element of a repeated field with a message - // type. - virtual Message* MutableRepeatedMessage( - Message* message, const FieldDescriptor* field, int index) const = 0; - - - // Repeated field adders ------------------------------------------- - // These add an element to a repeated field. - - virtual void AddInt32 (Message* message, - const FieldDescriptor* field, int32 value) const = 0; - virtual void AddInt64 (Message* message, - const FieldDescriptor* field, int64 value) const = 0; - virtual void AddUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const = 0; - virtual void AddUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const = 0; - virtual void AddFloat (Message* message, - const FieldDescriptor* field, float value) const = 0; - virtual void AddDouble(Message* message, - const FieldDescriptor* field, double value) const = 0; - virtual void AddBool (Message* message, - const FieldDescriptor* field, bool value) const = 0; - virtual void AddString(Message* message, - const FieldDescriptor* field, - const string& value) const = 0; - virtual void AddEnum (Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const = 0; - // See MutableMessage() for comments on the "factory" parameter. - virtual Message* AddMessage(Message* message, - const FieldDescriptor* field, - MessageFactory* factory = NULL) const = 0; - - - // Extensions ------------------------------------------------------ - - // Try to find an extension of this message type by fully-qualified field - // name. Returns NULL if no extension is known for this name or number. - virtual const FieldDescriptor* FindKnownExtensionByName( - const string& name) const = 0; - - // Try to find an extension of this message type by field number. - // Returns NULL if no extension is known for this name or number. - virtual const FieldDescriptor* FindKnownExtensionByNumber( - int number) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); -}; - -// Abstract interface for a factory for message objects. -class LIBPROTOBUF_EXPORT MessageFactory { - public: - inline MessageFactory() {} - virtual ~MessageFactory(); - - // Given a Descriptor, gets or constructs the default (prototype) Message - // of that type. You can then call that message's New() method to construct - // a mutable message of that type. - // - // Calling this method twice with the same Descriptor returns the same - // object. The returned object remains property of the factory. Also, any - // objects created by calling the prototype's New() method share some data - // with the prototype, so these must be destoyed before the MessageFactory - // is destroyed. - // - // The given descriptor must outlive the returned message, and hence must - // outlive the MessageFactory. - // - // Some implementations do not support all types. GetPrototype() will - // return NULL if the descriptor passed in is not supported. - // - // This method may or may not be thread-safe depending on the implementation. - // Each implementation should document its own degree thread-safety. - virtual const Message* GetPrototype(const Descriptor* type) = 0; - - // Gets a MessageFactory which supports all generated, compiled-in messages. - // In other words, for any compiled-in type FooMessage, the following is true: - // MessageFactory::generated_factory()->GetPrototype( - // FooMessage::descriptor()) == FooMessage::default_instance() - // This factory supports all types which are found in - // DescriptorPool::generated_pool(). If given a descriptor from any other - // pool, GetPrototype() will return NULL. (You can also check if a - // descriptor is for a generated message by checking if - // descriptor->file()->pool() == DescriptorPool::generated_pool().) - // - // This factory is 100% thread-safe; calling GetPrototype() does not modify - // any shared data. - // - // This factory is a singleton. The caller must not delete the object. - static MessageFactory* generated_factory(); - - // For internal use only: Registers a .proto file at static initialization - // time, to be placed in generated_factory. The first time GetPrototype() - // is called with a descriptor from this file, |register_messages| will be - // called, with the file name as the parameter. It must call - // InternalRegisterGeneratedMessage() (below) to register each message type - // in the file. This strange mechanism is necessary because descriptors are - // built lazily, so we can't register types by their descriptor until we - // know that the descriptor exists. |filename| must be a permanent string. - static void InternalRegisterGeneratedFile( - const char* filename, void (*register_messages)(const string&)); - - // For internal use only: Registers a message type. Called only by the - // functions which are registered with InternalRegisterGeneratedFile(), - // above. - static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, - const Message* prototype); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_MESSAGE_H__ diff --git a/Resources/NetHook/google/protobuf/message_lite.cc b/Resources/NetHook/google/protobuf/message_lite.cc deleted file mode 100644 index 7c8f37dc..00000000 --- a/Resources/NetHook/google/protobuf/message_lite.cc +++ /dev/null @@ -1,334 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Authors: wink@google.com (Wink Saville), -// kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -MessageLite::~MessageLite() {} - -string MessageLite::InitializationErrorString() const { - return "(cannot determine missing fields for lite message)"; -} - -namespace { - -// When serializing, we first compute the byte size, then serialize the message. -// If serialization produces a different number of bytes than expected, we -// call this function, which crashes. The problem could be due to a bug in the -// protobuf implementation but is more likely caused by concurrent modification -// of the message. This function attempts to distinguish between the two and -// provide a useful error message. -void ByteSizeConsistencyError(int byte_size_before_serialization, - int byte_size_after_serialization, - int bytes_produced_by_serialization) { - GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization) - << "Protocol message was modified concurrently during serialization."; - GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization) - << "Byte size calculation and serialization were inconsistent. This " - "may indicate a bug in protocol buffers or it may be caused by " - "concurrent modification of the message."; - GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal."; -} - -string InitializationErrorMessage(const char* action, - const MessageLite& message) { - // Note: We want to avoid depending on strutil in the lite library, otherwise - // we'd use: - // - // return strings::Substitute( - // "Can't $0 message of type \"$1\" because it is missing required " - // "fields: $2", - // action, message.GetTypeName(), - // message.InitializationErrorString()); - - string result; - result += "Can't "; - result += action; - result += " message of type \""; - result += message.GetTypeName(); - result += "\" because it is missing required fields: "; - result += message.InitializationErrorString(); - return result; -} - -// Several of the Parse methods below just do one thing and then call another -// method. In a naive implementation, we might have ParseFromString() call -// ParseFromArray() which would call ParseFromZeroCopyStream() which would call -// ParseFromCodedStream() which would call MergeFromCodedStream() which would -// call MergePartialFromCodedStream(). However, when parsing very small -// messages, every function call introduces significant overhead. To avoid -// this without reproducing code, we use these forced-inline helpers. -// -// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not -// definitions. -inline bool InlineMergeFromCodedStream(io::CodedInputStream* input, - MessageLite* message) - GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline bool InlineParseFromCodedStream(io::CodedInputStream* input, - MessageLite* message) - GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, - MessageLite* message) - GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline bool InlineParseFromArray(const void* data, int size, - MessageLite* message) - GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline bool InlineParsePartialFromArray(const void* data, int size, - MessageLite* message) - GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - -bool InlineMergeFromCodedStream(io::CodedInputStream* input, - MessageLite* message) { - if (!message->MergePartialFromCodedStream(input)) return false; - if (!message->IsInitialized()) { - GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message); - return false; - } - return true; -} - -bool InlineParseFromCodedStream(io::CodedInputStream* input, - MessageLite* message) { - message->Clear(); - return InlineMergeFromCodedStream(input, message); -} - -bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, - MessageLite* message) { - message->Clear(); - return message->MergePartialFromCodedStream(input); -} - -bool InlineParseFromArray(const void* data, int size, MessageLite* message) { - io::CodedInputStream input(reinterpret_cast(data), size); - return InlineParseFromCodedStream(&input, message) && - input.ConsumedEntireMessage(); -} - -bool InlineParsePartialFromArray(const void* data, int size, - MessageLite* message) { - io::CodedInputStream input(reinterpret_cast(data), size); - return InlineParsePartialFromCodedStream(&input, message) && - input.ConsumedEntireMessage(); -} - -} // namespace - -bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { - return InlineMergeFromCodedStream(input, this); -} - -bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { - return InlineParseFromCodedStream(input, this); -} - -bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { - return InlineParsePartialFromCodedStream(input, this); -} - -bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); -} - -bool MessageLite::ParsePartialFromZeroCopyStream( - io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParsePartialFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage(); -} - -bool MessageLite::ParseFromBoundedZeroCopyStream( - io::ZeroCopyInputStream* input, int size) { - io::CodedInputStream decoder(input); - decoder.PushLimit(size); - return ParseFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage() && - decoder.BytesUntilLimit() == 0; -} - -bool MessageLite::ParsePartialFromBoundedZeroCopyStream( - io::ZeroCopyInputStream* input, int size) { - io::CodedInputStream decoder(input); - decoder.PushLimit(size); - return ParsePartialFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage() && - decoder.BytesUntilLimit() == 0; -} - -bool MessageLite::ParseFromString(const string& data) { - return InlineParseFromArray(data.data(), data.size(), this); -} - -bool MessageLite::ParsePartialFromString(const string& data) { - return InlineParsePartialFromArray(data.data(), data.size(), this); -} - -bool MessageLite::ParseFromArray(const void* data, int size) { - return InlineParseFromArray(data, size, this); -} - -bool MessageLite::ParsePartialFromArray(const void* data, int size) { - return InlineParsePartialFromArray(data, size, this); -} - - -// =================================================================== - -uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { - // We only optimize this when using optimize_for = SPEED. In other cases - // we just use the CodedOutputStream path. - int size = GetCachedSize(); - io::ArrayOutputStream out(target, size); - io::CodedOutputStream coded_out(&out); - SerializeWithCachedSizes(&coded_out); - GOOGLE_CHECK(!coded_out.HadError()); - return target + size; -} - -bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return SerializePartialToCodedStream(output); -} - -bool MessageLite::SerializePartialToCodedStream( - io::CodedOutputStream* output) const { - const int size = ByteSize(); // Force size to be cached. - uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); - if (buffer != NULL) { - uint8* end = SerializeWithCachedSizesToArray(buffer); - if (end - buffer != size) { - ByteSizeConsistencyError(size, ByteSize(), end - buffer); - } - return true; - } else { - int original_byte_count = output->ByteCount(); - SerializeWithCachedSizes(output); - if (output->HadError()) { - return false; - } - int final_byte_count = output->ByteCount(); - - if (final_byte_count - original_byte_count != size) { - ByteSizeConsistencyError(size, ByteSize(), - final_byte_count - original_byte_count); - } - - return true; - } -} - -bool MessageLite::SerializeToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializeToCodedStream(&encoder); -} - -bool MessageLite::SerializePartialToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializePartialToCodedStream(&encoder); -} - -bool MessageLite::AppendToString(string* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return AppendPartialToString(output); -} - -bool MessageLite::AppendPartialToString(string* output) const { - int old_size = output->size(); - int byte_size = ByteSize(); - STLStringResizeUninitialized(output, old_size + byte_size); - uint8* start = reinterpret_cast(string_as_array(output) + old_size); - uint8* end = SerializeWithCachedSizesToArray(start); - if (end - start != byte_size) { - ByteSizeConsistencyError(byte_size, ByteSize(), end - start); - } - return true; -} - -bool MessageLite::SerializeToString(string* output) const { - output->clear(); - return AppendToString(output); -} - -bool MessageLite::SerializePartialToString(string* output) const { - output->clear(); - return AppendPartialToString(output); -} - -bool MessageLite::SerializeToArray(void* data, int size) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return SerializePartialToArray(data, size); -} - -bool MessageLite::SerializePartialToArray(void* data, int size) const { - int byte_size = ByteSize(); - if (size < byte_size) return false; - uint8* start = reinterpret_cast(data); - uint8* end = SerializeWithCachedSizesToArray(start); - if (end - start != byte_size) { - ByteSizeConsistencyError(byte_size, ByteSize(), end - start); - } - return true; -} - -string MessageLite::SerializeAsString() const { - // If the compiler implements the (Named) Return Value Optimization, - // the local variable 'result' will not actually reside on the stack - // of this function, but will be overlaid with the object that the - // caller supplied for the return value to be constructed in. - string output; - if (!AppendToString(&output)) - output.clear(); - return output; -} - -string MessageLite::SerializePartialAsString() const { - string output; - if (!AppendPartialToString(&output)) - output.clear(); - return output; -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/message_lite.h b/Resources/NetHook/google/protobuf/message_lite.h deleted file mode 100644 index ebf4ba3c..00000000 --- a/Resources/NetHook/google/protobuf/message_lite.h +++ /dev/null @@ -1,239 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Authors: wink@google.com (Wink Saville), -// kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Defines MessageLite, the abstract interface implemented by all (lite -// and non-lite) protocol message objects. - -#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ -#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ - -#include -#include - -namespace google { -namespace protobuf { - -// Interface to light weight protocol messages. -// -// This interface is implemented by all protocol message objects. Non-lite -// messages additionally implement the Message interface, which is a -// subclass of MessageLite. Use MessageLite instead when you only need -// the subset of features which it supports -- namely, nothing that uses -// descriptors or reflection. You can instruct the protocol compiler -// to generate classes which implement only MessageLite, not the full -// Message interface, by adding the following line to the .proto file: -// -// option optimize_for = LITE_RUNTIME; -// -// This is particularly useful on resource-constrained systems where -// the full protocol buffers runtime library is too big. -// -// Note that on non-constrained systems (e.g. servers) when you need -// to link in lots of protocol definitions, a better way to reduce -// total code footprint is to use optimize_for = CODE_SIZE. This -// will make the generated code smaller while still supporting all the -// same features (at the expense of speed). optimize_for = LITE_RUNTIME -// is best when you only have a small number of message types linked -// into your binary, in which case the size of the protocol buffers -// runtime itself is the biggest problem. -class LIBPROTOBUF_EXPORT MessageLite { - public: - inline MessageLite() {} - virtual ~MessageLite(); - - // Basic Operations ------------------------------------------------ - - // Get the name of this message type, e.g. "foo.bar.BazProto". - virtual string GetTypeName() const = 0; - - // Construct a new instance of the same type. Ownership is passed to the - // caller. - virtual MessageLite* New() const = 0; - - // Clear all fields of the message and set them to their default values. - // Clear() avoids freeing memory, assuming that any memory allocated - // to hold parts of the message will be needed again to hold the next - // message. If you actually want to free the memory used by a Message, - // you must delete it. - virtual void Clear() = 0; - - // Quickly check if all required fields have values set. - virtual bool IsInitialized() const = 0; - - // This is not implemented for Lite messages -- it just returns "(cannot - // determine missing fields for lite message)". However, it is implemented - // for full messages. See message.h. - virtual string InitializationErrorString() const; - - // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, - // results are undefined (probably crash). - virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; - - // Parsing --------------------------------------------------------- - // Methods for parsing in protocol buffer format. Most of these are - // just simple wrappers around MergeFromCodedStream(). - - // Fill the message with a protocol buffer parsed from the given input - // stream. Returns false on a read error or if the input is in the - // wrong format. - bool ParseFromCodedStream(io::CodedInputStream* input); - // Like ParseFromCodedStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromCodedStream(io::CodedInputStream* input); - // Read a protocol buffer from the given zero-copy input stream. If - // successful, the entire input will be consumed. - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Like ParseFromZeroCopyStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Read a protocol buffer from the given zero-copy input stream, expecting - // the message to be exactly "size" bytes long. If successful, exactly - // this many bytes will have been consumed from the input. - bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); - // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are - // missing required fields. - bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, - int size); - // Parse a protocol buffer contained in a string. - bool ParseFromString(const string& data); - // Like ParseFromString(), but accepts messages that are missing - // required fields. - bool ParsePartialFromString(const string& data); - // Parse a protocol buffer contained in an array of bytes. - bool ParseFromArray(const void* data, int size); - // Like ParseFromArray(), but accepts messages that are missing - // required fields. - bool ParsePartialFromArray(const void* data, int size); - - - // Reads a protocol buffer from the stream and merges it into this - // Message. Singular fields read from the input overwrite what is - // already in the Message and repeated fields are appended to those - // already present. - // - // It is the responsibility of the caller to call input->LastTagWas() - // (for groups) or input->ConsumedEntireMessage() (for non-groups) after - // this returns to verify that the message's end was delimited correctly. - // - // ParsefromCodedStream() is implemented as Clear() followed by - // MergeFromCodedStream(). - bool MergeFromCodedStream(io::CodedInputStream* input); - - // Like MergeFromCodedStream(), but succeeds even if required fields are - // missing in the input. - // - // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() - // followed by IsInitialized(). - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0; - - // Serialization --------------------------------------------------- - // Methods for serializing in protocol buffer format. Most of these - // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). - - // Write a protocol buffer of this message to the given output. Returns - // false on a write error. If the message is missing required fields, - // this may GOOGLE_CHECK-fail. - bool SerializeToCodedStream(io::CodedOutputStream* output) const; - // Like SerializeToCodedStream(), but allows missing required fields. - bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; - // Write the message to the given zero-copy output stream. All required - // fields must be set. - bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Like SerializeToZeroCopyStream(), but allows missing required fields. - bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Serialize the message and store it in the given string. All required - // fields must be set. - bool SerializeToString(string* output) const; - // Like SerializeToString(), but allows missing required fields. - bool SerializePartialToString(string* output) const; - // Serialize the message and store it in the given byte array. All required - // fields must be set. - bool SerializeToArray(void* data, int size) const; - // Like SerializeToArray(), but allows missing required fields. - bool SerializePartialToArray(void* data, int size) const; - - // Make a string encoding the message. Is equivalent to calling - // SerializeToString() on a string and using that. Returns the empty - // string if SerializeToString() would have returned an error. - // Note: If you intend to generate many such strings, you may - // reduce heap fragmentation by instead re-using the same string - // object with calls to SerializeToString(). - string SerializeAsString() const; - // Like SerializeAsString(), but allows missing required fields. - string SerializePartialAsString() const; - - // Like SerializeToString(), but appends to the data to the string's existing - // contents. All required fields must be set. - bool AppendToString(string* output) const; - // Like AppendToString(), but allows missing required fields. - bool AppendPartialToString(string* output) const; - - // Computes the serialized size of the message. This recursively calls - // ByteSize() on all embedded messages. If a subclass does not override - // this, it MUST override SetCachedSize(). - virtual int ByteSize() const = 0; - - // Serializes the message without recomputing the size. The message must - // not have changed since the last call to ByteSize(); if it has, the results - // are undefined. - virtual void SerializeWithCachedSizes( - io::CodedOutputStream* output) const = 0; - - // Like SerializeWithCachedSizes, but writes directly to *target, returning - // a pointer to the byte immediately after the last byte written. "target" - // must point at a byte array of at least ByteSize() bytes. - virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const; - - // Returns the result of the last call to ByteSize(). An embedded message's - // size is needed both to serialize it (because embedded messages are - // length-delimited) and to compute the outer message's size. Caching - // the size avoids computing it multiple times. - // - // ByteSize() does not automatically use the cached size when available - // because this would require invalidating it every time the message was - // modified, which would be too hard and expensive. (E.g. if a deeply-nested - // sub-message is changed, all of its parents' cached sizes would need to be - // invalidated, which is too much work for an otherwise inlined setter - // method.) - virtual int GetCachedSize() const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__ diff --git a/Resources/NetHook/google/protobuf/message_unittest.cc b/Resources/NetHook/google/protobuf/message_unittest.cc deleted file mode 100644 index 33b9e77c..00000000 --- a/Resources/NetHook/google/protobuf/message_unittest.cc +++ /dev/null @@ -1,281 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -#include -#include -#include -#ifdef _MSC_VER -#include -#else -#include -#endif -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace google { -namespace protobuf { - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -TEST(MessageTest, SerializeHelpers) { - // TODO(kenton): Test more helpers? They're all two-liners so it seems - // like a waste of time. - - protobuf_unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - stringstream stream; - - string str1("foo"); - string str2("bar"); - - EXPECT_TRUE(message.SerializeToString(&str1)); - EXPECT_TRUE(message.AppendToString(&str2)); - EXPECT_TRUE(message.SerializeToOstream(&stream)); - - EXPECT_EQ(str1.size() + 3, str2.size()); - EXPECT_EQ("bar", str2.substr(0, 3)); - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(str2.substr(3) == str1); - - // GCC gives some sort of error if we try to just do stream.str() == str1. - string temp = stream.str(); - EXPECT_TRUE(temp == str1); - - EXPECT_TRUE(message.SerializeAsString() == str1); - -} - -TEST(MessageTest, SerializeToBrokenOstream) { - ofstream out; - protobuf_unittest::TestAllTypes message; - message.set_optional_int32(123); - - EXPECT_FALSE(message.SerializeToOstream(&out)); -} - -TEST(MessageTest, ParseFromFileDescriptor) { - string filename = TestSourceDir() + - "/google/protobuf/testdata/golden_message"; - int file = open(filename.c_str(), O_RDONLY | O_BINARY); - - unittest::TestAllTypes message; - EXPECT_TRUE(message.ParseFromFileDescriptor(file)); - TestUtil::ExpectAllFieldsSet(message); - - EXPECT_GE(close(file), 0); -} - -TEST(MessageTest, ParsePackedFromFileDescriptor) { - string filename = - TestSourceDir() + - "/google/protobuf/testdata/golden_packed_fields_message"; - int file = open(filename.c_str(), O_RDONLY | O_BINARY); - - unittest::TestPackedTypes message; - EXPECT_TRUE(message.ParseFromFileDescriptor(file)); - TestUtil::ExpectPackedFieldsSet(message); - - EXPECT_GE(close(file), 0); -} - -TEST(MessageTest, ParseHelpers) { - // TODO(kenton): Test more helpers? They're all two-liners so it seems - // like a waste of time. - string data; - - { - // Set up. - protobuf_unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - message.SerializeToString(&data); - } - - { - // Test ParseFromString. - protobuf_unittest::TestAllTypes message; - EXPECT_TRUE(message.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(message); - } - - { - // Test ParseFromIstream. - protobuf_unittest::TestAllTypes message; - stringstream stream(data); - EXPECT_TRUE(message.ParseFromIstream(&stream)); - EXPECT_TRUE(stream.eof()); - TestUtil::ExpectAllFieldsSet(message); - } - - { - // Test ParseFromBoundedZeroCopyStream. - string data_with_junk(data); - data_with_junk.append("some junk on the end"); - io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size()); - protobuf_unittest::TestAllTypes message; - EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size())); - TestUtil::ExpectAllFieldsSet(message); - } - - { - // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if - // EOF is reached before the expected number of bytes. - io::ArrayInputStream stream(data.data(), data.size()); - protobuf_unittest::TestAllTypes message; - EXPECT_FALSE( - message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1)); - } -} - -TEST(MessageTest, ParseFailsIfNotInitialized) { - unittest::TestRequired message; - vector errors; - - { - ScopedMemoryLog log; - EXPECT_FALSE(message.ParseFromString("")); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" " - "because it is missing required fields: a, b, c", - errors[0]); -} - -TEST(MessageTest, BypassInitializationCheckOnParse) { - unittest::TestRequired message; - io::ArrayInputStream raw_input(NULL, 0); - io::CodedInputStream input(&raw_input); - EXPECT_TRUE(message.MergePartialFromCodedStream(&input)); -} - -TEST(MessageTest, InitializationErrorString) { - unittest::TestRequired message; - EXPECT_EQ("a, b, c", message.InitializationErrorString()); -} - -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet. - -TEST(MessageTest, SerializeFailsIfNotInitialized) { - unittest::TestRequired message; - string data; - EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)), - "Can't serialize message of type \"protobuf_unittest.TestRequired\" because " - "it is missing required fields: a, b, c"); -} - -TEST(MessageTest, CheckInitialized) { - unittest::TestRequired message; - EXPECT_DEATH(message.CheckInitialized(), - "Message of type \"protobuf_unittest.TestRequired\" is missing required " - "fields: a, b, c"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(MessageTest, BypassInitializationCheckOnSerialize) { - unittest::TestRequired message; - io::ArrayOutputStream raw_output(NULL, 0); - io::CodedOutputStream output(&raw_output); - EXPECT_TRUE(message.SerializePartialToCodedStream(&output)); -} - -TEST(MessageTest, FindInitializationErrors) { - unittest::TestRequired message; - vector errors; - message.FindInitializationErrors(&errors); - ASSERT_EQ(3, errors.size()); - EXPECT_EQ("a", errors[0]); - EXPECT_EQ("b", errors[1]); - EXPECT_EQ("c", errors[2]); -} - -TEST(MessageTest, ParseFailsOnInvalidMessageEnd) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromArray("", 0)); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromArray("\0", 1)); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromArray("\200", 1)); - - // The byte is an endgroup tag, but we aren't parsing a group. - EXPECT_FALSE(message.ParseFromArray("\014", 1)); -} - -TEST(MessageFactoryTest, GeneratedFactoryLookup) { - EXPECT_EQ( - MessageFactory::generated_factory()->GetPrototype( - protobuf_unittest::TestAllTypes::descriptor()), - &protobuf_unittest::TestAllTypes::default_instance()); -} - -TEST(MessageFactoryTest, GeneratedFactoryUnknownType) { - // Construct a new descriptor. - DescriptorPool pool; - FileDescriptorProto file; - file.set_name("foo.proto"); - file.add_message_type()->set_name("Foo"); - const Descriptor* descriptor = pool.BuildFile(file)->message_type(0); - - // Trying to construct it should return NULL. - EXPECT_TRUE( - MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL); -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/package_info.h b/Resources/NetHook/google/protobuf/package_info.h deleted file mode 100644 index 60cd3994..00000000 --- a/Resources/NetHook/google/protobuf/package_info.h +++ /dev/null @@ -1,64 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file exists solely to document the google::protobuf namespace. -// It is not compiled into anything, but it may be read by an automated -// documentation generator. - -namespace google { - -// Core components of the Protocol Buffers runtime library. -// -// The files in this package represent the core of the Protocol Buffer -// system. All of them are part of the libprotobuf library. -// -// A note on thread-safety: -// -// Thread-safety in the Protocol Buffer library follows a simple rule: -// unless explicitly noted otherwise, it is always safe to use an object -// from multiple threads simultaneously as long as the object is declared -// const in all threads (or, it is only used in ways that would be allowed -// if it were declared const). However, if an object is accessed in one -// thread in a way that would not be allowed if it were const, then it is -// not safe to access that object in any other thread simultaneously. -// -// Put simply, read-only access to an object can happen in multiple threads -// simultaneously, but write access can only happen in a single thread at -// a time. -// -// The implementation does contain some "const" methods which actually modify -// the object behind the scenes -- e.g., to cache results -- but in these cases -// mutex locking is used to make the access thread-safe. -namespace protobuf {} -} // namespace google diff --git a/Resources/NetHook/google/protobuf/reflection_ops.cc b/Resources/NetHook/google/protobuf/reflection_ops.cc deleted file mode 100644 index 897c0d7c..00000000 --- a/Resources/NetHook/google/protobuf/reflection_ops.cc +++ /dev/null @@ -1,262 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -void ReflectionOps::Copy(const Message& from, Message* to) { - if (&from == to) return; - Clear(to); - Merge(from, to); -} - -void ReflectionOps::Merge(const Message& from, Message* to) { - GOOGLE_CHECK_NE(&from, to); - - const Descriptor* descriptor = from.GetDescriptor(); - GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor) - << "Tried to merge messages of different types."; - - const Reflection* from_reflection = from.GetReflection(); - const Reflection* to_reflection = to->GetReflection(); - - vector fields; - from_reflection->ListFields(from, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - - if (field->is_repeated()) { - int count = from_reflection->FieldSize(from, field); - for (int j = 0; j < count; j++) { - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, METHOD) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - to_reflection->Add##METHOD(to, field, \ - from_reflection->GetRepeated##METHOD(from, field, j)); \ - break; - - HANDLE_TYPE(INT32 , Int32 ); - HANDLE_TYPE(INT64 , Int64 ); - HANDLE_TYPE(UINT32, UInt32); - HANDLE_TYPE(UINT64, UInt64); - HANDLE_TYPE(FLOAT , Float ); - HANDLE_TYPE(DOUBLE, Double); - HANDLE_TYPE(BOOL , Bool ); - HANDLE_TYPE(STRING, String); - HANDLE_TYPE(ENUM , Enum ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->AddMessage(to, field)->MergeFrom( - from_reflection->GetRepeatedMessage(from, field, j)); - break; - } - } - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, METHOD) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - to_reflection->Set##METHOD(to, field, \ - from_reflection->Get##METHOD(from, field)); \ - break; - - HANDLE_TYPE(INT32 , Int32 ); - HANDLE_TYPE(INT64 , Int64 ); - HANDLE_TYPE(UINT32, UInt32); - HANDLE_TYPE(UINT64, UInt64); - HANDLE_TYPE(FLOAT , Float ); - HANDLE_TYPE(DOUBLE, Double); - HANDLE_TYPE(BOOL , Bool ); - HANDLE_TYPE(STRING, String); - HANDLE_TYPE(ENUM , Enum ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->MutableMessage(to, field)->MergeFrom( - from_reflection->GetMessage(from, field)); - break; - } - } - } - - to_reflection->MutableUnknownFields(to)->MergeFrom( - from_reflection->GetUnknownFields(from)); -} - -void ReflectionOps::Clear(Message* message) { - const Reflection* reflection = message->GetReflection(); - - vector fields; - reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - reflection->ClearField(message, fields[i]); - } - - reflection->MutableUnknownFields(message)->Clear(); -} - -bool ReflectionOps::IsInitialized(const Message& message) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* reflection = message.GetReflection(); - - // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - return false; - } - } - } - - // Check that sub-messages are initialized. - vector fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (field->is_repeated()) { - int size = reflection->FieldSize(message, field); - - for (int i = 0; i < size; i++) { - if (!reflection->GetRepeatedMessage(message, field, i) - .IsInitialized()) { - return false; - } - } - } else { - if (!reflection->GetMessage(message, field).IsInitialized()) { - return false; - } - } - } - } - - return true; -} - -void ReflectionOps::DiscardUnknownFields(Message* message) { - const Reflection* reflection = message->GetReflection(); - - reflection->MutableUnknownFields(message)->Clear(); - - vector fields; - reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (field->is_repeated()) { - int size = reflection->FieldSize(*message, field); - for (int i = 0; i < size; i++) { - reflection->MutableRepeatedMessage(message, field, i) - ->DiscardUnknownFields(); - } - } else { - reflection->MutableMessage(message, field)->DiscardUnknownFields(); - } - } - } -} - -static string SubMessagePrefix(const string& prefix, - const FieldDescriptor* field, - int index) { - string result(prefix); - if (field->is_extension()) { - result.append("("); - result.append(field->full_name()); - result.append(")"); - } else { - result.append(field->name()); - } - if (index != -1) { - result.append("["); - result.append(SimpleItoa(index)); - result.append("]"); - } - result.append("."); - return result; -} - -void ReflectionOps::FindInitializationErrors( - const Message& message, - const string& prefix, - vector* errors) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* reflection = message.GetReflection(); - - // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - errors->push_back(prefix + descriptor->field(i)->name()); - } - } - } - - // Check sub-messages. - vector fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - - if (field->is_repeated()) { - int size = reflection->FieldSize(message, field); - - for (int i = 0; i < size; i++) { - const Message& sub_message = - reflection->GetRepeatedMessage(message, field, i); - FindInitializationErrors(sub_message, - SubMessagePrefix(prefix, field, i), - errors); - } - } else { - const Message& sub_message = reflection->GetMessage(message, field); - FindInitializationErrors(sub_message, - SubMessagePrefix(prefix, field, -1), - errors); - } - } - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/reflection_ops.h b/Resources/NetHook/google/protobuf/reflection_ops.h deleted file mode 100644 index 355a0a5d..00000000 --- a/Resources/NetHook/google/protobuf/reflection_ops.h +++ /dev/null @@ -1,80 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ -#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ - -#include - -namespace google { -namespace protobuf { -namespace internal { - -// Basic operations that can be performed using reflection. -// These can be used as a cheap way to implement the corresponding -// methods of the Message interface, though they are likely to be -// slower than implementations tailored for the specific message type. -// -// This class should stay limited to operations needed to implement -// the Message interface. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT ReflectionOps { - public: - static void Copy(const Message& from, Message* to); - static void Merge(const Message& from, Message* to); - static void Clear(Message* message); - static bool IsInitialized(const Message& message); - static void DiscardUnknownFields(Message* message); - - // Finds all unset required fields in the message and adds their full - // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to - // the front of each name. - static void FindInitializationErrors(const Message& message, - const string& prefix, - vector* errors); - - private: - // All methods are static. No need to construct. - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); -}; - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ diff --git a/Resources/NetHook/google/protobuf/reflection_ops_unittest.cc b/Resources/NetHook/google/protobuf/reflection_ops_unittest.cc deleted file mode 100644 index 1cd56f1e..00000000 --- a/Resources/NetHook/google/protobuf/reflection_ops_unittest.cc +++ /dev/null @@ -1,405 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -TEST(ReflectionOpsTest, SanityCheck) { - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(ReflectionOpsTest, Copy) { - unittest::TestAllTypes message, message2; - - TestUtil::SetAllFields(&message); - - ReflectionOps::Copy(message, &message2); - - TestUtil::ExpectAllFieldsSet(message2); - - // Copying from self should be a no-op. - ReflectionOps::Copy(message2, &message2); - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(ReflectionOpsTest, CopyExtensions) { - unittest::TestAllExtensions message, message2; - - TestUtil::SetAllExtensions(&message); - - ReflectionOps::Copy(message, &message2); - - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(ReflectionOpsTest, Merge) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllTypes message, message2; - - TestUtil::SetAllFields(&message); - - // This field will test merging into an empty spot. - message2.set_optional_int32(message.optional_int32()); - message.clear_optional_int32(); - - // This tests overwriting. - message2.set_optional_string(message.optional_string()); - message.set_optional_string("something else"); - - // This tests concatenating. - message2.add_repeated_int32(message.repeated_int32(1)); - int32 i = message.repeated_int32(0); - message.clear_repeated_int32(); - message.add_repeated_int32(i); - - ReflectionOps::Merge(message2, &message); - - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(ReflectionOpsTest, MergeExtensions) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllExtensions message, message2; - - TestUtil::SetAllExtensions(&message); - - // This field will test merging into an empty spot. - message2.SetExtension(unittest::optional_int32_extension, - message.GetExtension(unittest::optional_int32_extension)); - message.ClearExtension(unittest::optional_int32_extension); - - // This tests overwriting. - message2.SetExtension(unittest::optional_string_extension, - message.GetExtension(unittest::optional_string_extension)); - message.SetExtension(unittest::optional_string_extension, "something else"); - - // This tests concatenating. - message2.AddExtension(unittest::repeated_int32_extension, - message.GetExtension(unittest::repeated_int32_extension, 1)); - int32 i = message.GetExtension(unittest::repeated_int32_extension, 0); - message.ClearExtension(unittest::repeated_int32_extension); - message.AddExtension(unittest::repeated_int32_extension, i); - - ReflectionOps::Merge(message2, &message); - - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ReflectionOpsTest, MergeUnknown) { - // Test that the messages' UnknownFieldSets are correctly merged. - unittest::TestEmptyMessage message1, message2; - message1.mutable_unknown_fields()->AddVarint(1234, 1); - message2.mutable_unknown_fields()->AddVarint(1234, 2); - - ReflectionOps::Merge(message2, &message1); - - ASSERT_EQ(2, message1.unknown_fields().field_count()); - ASSERT_EQ(UnknownField::TYPE_VARINT, - message1.unknown_fields().field(0).type()); - EXPECT_EQ(1, message1.unknown_fields().field(0).varint()); - ASSERT_EQ(UnknownField::TYPE_VARINT, - message1.unknown_fields().field(1).type()); - EXPECT_EQ(2, message1.unknown_fields().field(1).varint()); -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(ReflectionOpsTest, MergeFromSelf) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllTypes message; - - EXPECT_DEATH( - ReflectionOps::Merge(message, &message), - "&from"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(ReflectionOpsTest, Clear) { - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - - ReflectionOps::Clear(&message); - - TestUtil::ExpectClear(message); - - // Check that getting embedded messages returns the objects created during - // SetAllFields() rather than default instances. - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -TEST(ReflectionOpsTest, ClearExtensions) { - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - - ReflectionOps::Clear(&message); - - TestUtil::ExpectExtensionsClear(message); - - // Check that getting embedded messages returns the objects created during - // SetAllExtensions() rather than default instances. - EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); -} - -TEST(ReflectionOpsTest, ClearUnknown) { - // Test that the message's UnknownFieldSet is correctly cleared. - unittest::TestEmptyMessage message; - message.mutable_unknown_fields()->AddVarint(1234, 1); - - ReflectionOps::Clear(&message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, DiscardUnknownFields) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - - // Set some unknown fields in message. - message.mutable_unknown_fields() - ->AddVarint(123456, 654321); - message.mutable_optional_nested_message() - ->mutable_unknown_fields() - ->AddVarint(123456, 654321); - message.mutable_repeated_nested_message(0) - ->mutable_unknown_fields() - ->AddVarint(123456, 654321); - - EXPECT_EQ(1, message.unknown_fields().field_count()); - EXPECT_EQ(1, message.optional_nested_message() - .unknown_fields().field_count()); - EXPECT_EQ(1, message.repeated_nested_message(0) - .unknown_fields().field_count()); - - // Discard them. - ReflectionOps::DiscardUnknownFields(&message); - TestUtil::ExpectAllFieldsSet(message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); - EXPECT_EQ(0, message.optional_nested_message() - .unknown_fields().field_count()); - EXPECT_EQ(0, message.repeated_nested_message(0) - .unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, DiscardUnknownExtensions) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - // Set some unknown fields. - message.mutable_unknown_fields() - ->AddVarint(123456, 654321); - message.MutableExtension(unittest::optional_nested_message_extension) - ->mutable_unknown_fields() - ->AddVarint(123456, 654321); - message.MutableExtension(unittest::repeated_nested_message_extension, 0) - ->mutable_unknown_fields() - ->AddVarint(123456, 654321); - - EXPECT_EQ(1, message.unknown_fields().field_count()); - EXPECT_EQ(1, - message.GetExtension(unittest::optional_nested_message_extension) - .unknown_fields().field_count()); - EXPECT_EQ(1, - message.GetExtension(unittest::repeated_nested_message_extension, 0) - .unknown_fields().field_count()); - - // Discard them. - ReflectionOps::DiscardUnknownFields(&message); - TestUtil::ExpectAllExtensionsSet(message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); - EXPECT_EQ(0, - message.GetExtension(unittest::optional_nested_message_extension) - .unknown_fields().field_count()); - EXPECT_EQ(0, - message.GetExtension(unittest::repeated_nested_message_extension, 0) - .unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, IsInitialized) { - unittest::TestRequired message; - - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_a(1); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_b(2); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -TEST(ReflectionOpsTest, ForeignIsInitialized) { - unittest::TestRequiredForeign message; - - // Starts out initialized because the foreign message is itself an optional - // field. - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Once we create that field, the message is no longer initialized. - message.mutable_optional_message(); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize it. Now we're initialized. - message.mutable_optional_message()->set_a(1); - message.mutable_optional_message()->set_b(2); - message.mutable_optional_message()->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Add a repeated version of the message. No longer initialized. - unittest::TestRequired* sub_message = message.add_repeated_message(); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize that repeated version. - sub_message->set_a(1); - sub_message->set_b(2); - sub_message->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -TEST(ReflectionOpsTest, ExtensionIsInitialized) { - unittest::TestAllExtensions message; - - // Starts out initialized because the foreign message is itself an optional - // field. - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Once we create that field, the message is no longer initialized. - message.MutableExtension(unittest::TestRequired::single); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize it. Now we're initialized. - message.MutableExtension(unittest::TestRequired::single)->set_a(1); - message.MutableExtension(unittest::TestRequired::single)->set_b(2); - message.MutableExtension(unittest::TestRequired::single)->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Add a repeated version of the message. No longer initialized. - message.AddExtension(unittest::TestRequired::multi); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize that repeated version. - message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -static string FindInitializationErrors(const Message& message) { - vector errors; - ReflectionOps::FindInitializationErrors(message, "", &errors); - return JoinStrings(errors, ","); -} - -TEST(ReflectionOpsTest, FindInitializationErrors) { - unittest::TestRequired message; - EXPECT_EQ("a,b,c", FindInitializationErrors(message)); -} - -TEST(ReflectionOpsTest, FindForeignInitializationErrors) { - unittest::TestRequiredForeign message; - message.mutable_optional_message(); - message.add_repeated_message(); - message.add_repeated_message(); - EXPECT_EQ("optional_message.a," - "optional_message.b," - "optional_message.c," - "repeated_message[0].a," - "repeated_message[0].b," - "repeated_message[0].c," - "repeated_message[1].a," - "repeated_message[1].b," - "repeated_message[1].c", - FindInitializationErrors(message)); -} - -TEST(ReflectionOpsTest, FindExtensionInitializationErrors) { - unittest::TestAllExtensions message; - message.MutableExtension(unittest::TestRequired::single); - message.AddExtension(unittest::TestRequired::multi); - message.AddExtension(unittest::TestRequired::multi); - EXPECT_EQ("(protobuf_unittest.TestRequired.single).a," - "(protobuf_unittest.TestRequired.single).b," - "(protobuf_unittest.TestRequired.single).c," - "(protobuf_unittest.TestRequired.multi)[0].a," - "(protobuf_unittest.TestRequired.multi)[0].b," - "(protobuf_unittest.TestRequired.multi)[0].c," - "(protobuf_unittest.TestRequired.multi)[1].a," - "(protobuf_unittest.TestRequired.multi)[1].b," - "(protobuf_unittest.TestRequired.multi)[1].c", - FindInitializationErrors(message)); -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/repeated_field.cc b/Resources/NetHook/google/protobuf/repeated_field.cc deleted file mode 100644 index f7beb110..00000000 --- a/Resources/NetHook/google/protobuf/repeated_field.cc +++ /dev/null @@ -1,95 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -void RepeatedPtrFieldBase::Reserve(int new_size) { - if (total_size_ >= new_size) return; - - void** old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new void*[total_size_]; - memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); - if (old_elements != initial_space_) { - delete [] old_elements; - } -} - -void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { - void** swap_elements = elements_; - int swap_current_size = current_size_; - int swap_allocated_size = allocated_size_; - int swap_total_size = total_size_; - // We may not be using initial_space_ but it's not worth checking. Just - // copy it anyway. - void* swap_initial_space[kInitialSize]; - memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); - - elements_ = other->elements_; - current_size_ = other->current_size_; - allocated_size_ = other->allocated_size_; - total_size_ = other->total_size_; - memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); - - other->elements_ = swap_elements; - other->current_size_ = swap_current_size; - other->allocated_size_ = swap_allocated_size; - other->total_size_ = swap_total_size; - memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); - - if (elements_ == other->initial_space_) { - elements_ = initial_space_; - } - if (other->elements_ == initial_space_) { - other->elements_ = other->initial_space_; - } -} - -string* StringTypeHandlerBase::New() { - return new string; -} -void StringTypeHandlerBase::Delete(string* value) { - delete value; -} - - -} // namespace internal - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/repeated_field.h b/Resources/NetHook/google/protobuf/repeated_field.h deleted file mode 100644 index defdefe0..00000000 --- a/Resources/NetHook/google/protobuf/repeated_field.h +++ /dev/null @@ -1,1248 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// RepeatedField and RepeatedPtrField are used by generated protocol message -// classes to manipulate repeated fields. These classes are very similar to -// STL's vector, but include a number of optimizations found to be useful -// specifically in the case of Protocol Buffers. RepeatedPtrField is -// particularly different from STL vector as it manages ownership of the -// pointers that it contains. -// -// Typically, clients should not need to access RepeatedField objects directly, -// but should instead use the accessor functions generated automatically by the -// protocol compiler. - -#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__ -#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__ - -#include -#include -#include -#include - -namespace google { - -namespace protobuf { - -class Message; - -namespace internal { - -// We need this (from generated_message_reflection.cc). -LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); - -} // namespace internal - -// RepeatedField is used to represent repeated fields of a primitive type (in -// other words, everything except strings and nested Messages). Most users will -// not ever use a RepeatedField directly; they will use the get-by-index, -// set-by-index, and add accessors that are generated for all repeated fields. -template -class RepeatedField { - public: - RepeatedField(); - ~RepeatedField(); - - int size() const; - - const Element& Get(int index) const; - Element* Mutable(int index); - void Set(int index, const Element& value); - void Add(const Element& value); - Element* Add(); - // Remove the last element in the array. - // We don't provide a way to remove any element other than the last - // because it invites inefficient use, such as O(n^2) filtering loops - // that should have been O(n). If you want to remove an element other - // than the last, the best way to do it is to re-arrange the elements - // so that the one you want removed is at the end, then call RemoveLast(). - void RemoveLast(); - void Clear(); - void MergeFrom(const RepeatedField& other); - - // Reserve space to expand the field to at least the given size. If the - // array is grown, it will always be at least doubled in size. - void Reserve(int new_size); - - // Resize the RepeatedField to a new, smaller size. This is O(1). - void Truncate(int new_size); - - void AddAlreadyReserved(const Element& value); - Element* AddAlreadyReserved(); - int Capacity() const; - - // Gets the underlying array. This pointer is possibly invalidated by - // any add or remove operation. - Element* mutable_data(); - const Element* data() const; - - // Swap entire contents with "other". - void Swap(RepeatedField* other); - - // Swap two elements. - void SwapElements(int index1, int index2); - - // STL-like iterator support - typedef Element* iterator; - typedef const Element* const_iterator; - - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - - // Returns the number of bytes used by the repeated field, excluding - // sizeof(*this) - int SpaceUsedExcludingSelf() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField); - - static const int kInitialSize = 4; - - Element* elements_; - int current_size_; - int total_size_; - - Element initial_space_[kInitialSize]; - - // Move the contents of |from| into |to|, possibly clobbering |from| in the - // process. For primitive types this is just a memcpy(), but it could be - // specialized for non-primitive types to, say, swap each element instead. - void MoveArray(Element to[], Element from[], int size); - - // Copy the elements of |from| into |to|. - void CopyArray(Element to[], const Element from[], int size); -}; - -namespace internal { -template class RepeatedPtrIterator; -template class RepeatedPtrOverPtrsIterator; -} // namespace internal - -namespace internal { - -// This is the common base class for RepeatedPtrFields. It deals only in void* -// pointers. Users should not use this interface directly. -// -// The methods of this interface correspond to the methods of RepeatedPtrField, -// but may have a template argument called TypeHandler. Its signature is: -// class TypeHandler { -// public: -// typedef MyType Type; -// static Type* New(); -// static void Delete(Type*); -// static void Clear(Type*); -// static void Merge(const Type& from, Type* to); -// -// // Only needs to be implemented if SpaceUsedExcludingSelf() is called. -// static int SpaceUsed(const Type&); -// }; -class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { - protected: - // The reflection implementation needs to call protected methods directly, - // reinterpreting pointers as being to Message instead of a specific Message - // subclass. - friend class GeneratedMessageReflection; - - // ExtensionSet stores repeated message extensions as - // RepeatedPtrField, but non-lite ExtensionSets need to - // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf() - // reinterpreting MessageLite as Message. ExtensionSet also needs to make - // use of AddFromCleared(), which is not part of the public interface. - friend class ExtensionSet; - - RepeatedPtrFieldBase(); - - // Must be called from destructor. - template - void Destroy(); - - int size() const; - - template - const typename TypeHandler::Type& Get(int index) const; - template - typename TypeHandler::Type* Mutable(int index); - template - typename TypeHandler::Type* Add(); - template - void RemoveLast(); - template - void Clear(); - template - void MergeFrom(const RepeatedPtrFieldBase& other); - - void Reserve(int new_size); - - int Capacity() const; - - // Used for constructing iterators. - void* const* raw_data() const; - void** raw_mutable_data() const; - - template - typename TypeHandler::Type** mutable_data(); - template - const typename TypeHandler::Type* const* data() const; - - void Swap(RepeatedPtrFieldBase* other); - - void SwapElements(int index1, int index2); - - template - int SpaceUsedExcludingSelf() const; - - - // Advanced memory management -------------------------------------- - - // Like Add(), but if there are no cleared objects to use, returns NULL. - template - typename TypeHandler::Type* AddFromCleared(); - - template - void AddAllocated(typename TypeHandler::Type* value); - template - typename TypeHandler::Type* ReleaseLast(); - - int ClearedCount() const; - template - void AddCleared(typename TypeHandler::Type* value); - template - typename TypeHandler::Type* ReleaseCleared(); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); - - static const int kInitialSize = 4; - - void** elements_; - int current_size_; - int allocated_size_; - int total_size_; - - void* initial_space_[kInitialSize]; - - template - static inline typename TypeHandler::Type* cast(void* element) { - return reinterpret_cast(element); - } - template - static inline const typename TypeHandler::Type* cast(const void* element) { - return reinterpret_cast(element); - } -}; - -template -class GenericTypeHandler { - public: - typedef GenericType Type; - static GenericType* New() { return new GenericType; } - static void Delete(GenericType* value) { delete value; } - static void Clear(GenericType* value) { value->Clear(); } - static void Merge(const GenericType& from, GenericType* to) { - to->MergeFrom(from); - } - static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); } -}; - -template <> -inline void GenericTypeHandler::Merge( - const MessageLite& from, MessageLite* to) { - to->CheckTypeAndMergeFrom(from); -} - -// HACK: If a class is declared as DLL-exported in MSVC, it insists on -// generating copies of all its methods -- even inline ones -- to include -// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which -// isn't in the lite library, therefore the lite library cannot link if -// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase, -// export that, then make StringTypeHandler be a subclass which is NOT -// exported. -// TODO(kenton): There has to be a better way. -class LIBPROTOBUF_EXPORT StringTypeHandlerBase { - public: - typedef string Type; - static string* New(); - static void Delete(string* value); - static void Clear(string* value) { value->clear(); } - static void Merge(const string& from, string* to) { *to = from; } -}; - -class StringTypeHandler : public StringTypeHandlerBase { - public: - static int SpaceUsed(const string& value) { - return sizeof(value) + StringSpaceUsedExcludingSelf(value); - } -}; - - -} // namespace internal - -// RepeatedPtrField is like RepeatedField, but used for repeated strings or -// Messages. -template -class RepeatedPtrField : public internal::RepeatedPtrFieldBase { - public: - RepeatedPtrField(); - - ~RepeatedPtrField(); - - int size() const; - - const Element& Get(int index) const; - Element* Mutable(int index); - Element* Add(); - void RemoveLast(); // Remove the last element in the array. - void Clear(); - void MergeFrom(const RepeatedPtrField& other); - - // Reserve space to expand the field to at least the given size. This only - // resizes the pointer array; it doesn't allocate any objects. If the - // array is grown, it will always be at least doubled in size. - void Reserve(int new_size); - - int Capacity() const; - - // Gets the underlying array. This pointer is possibly invalidated by - // any add or remove operation. - Element** mutable_data(); - const Element* const* data() const; - - // Swap entire contents with "other". - void Swap(RepeatedPtrField* other); - - // Swap two elements. - void SwapElements(int index1, int index2); - - // STL-like iterator support - typedef internal::RepeatedPtrIterator iterator; - typedef internal::RepeatedPtrIterator const_iterator; - - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - - // Custom STL-like iterator that iterates over and returns the underlying - // pointers to Element rather than Element itself. - typedef internal::RepeatedPtrOverPtrsIterator pointer_iterator; - pointer_iterator pointer_begin(); - pointer_iterator pointer_end(); - - // Returns (an estimate of) the number of bytes used by the repeated field, - // excluding sizeof(*this). - int SpaceUsedExcludingSelf() const; - - // The spaced used just by the pointer array, not counting the objects pointed - // at. Returns zero if the array is inlined (i.e. initial_space_ is being - // used). - int SpaceUsedByArray() const; - - // Advanced memory management -------------------------------------- - // When hardcore memory management becomes necessary -- as it often - // does here at Google -- the following methods may be useful. - - // Add an already-allocated object, passing ownership to the - // RepeatedPtrField. - void AddAllocated(Element* value); - // Remove the last element and return it, passing ownership to the - // caller. - // Requires: size() > 0 - Element* ReleaseLast(); - - // When elements are removed by calls to RemoveLast() or Clear(), they - // are not actually freed. Instead, they are cleared and kept so that - // they can be reused later. This can save lots of CPU time when - // repeatedly reusing a protocol message for similar purposes. - // - // Really, extremely hardcore programs may actually want to manipulate - // these objects to better-optimize memory management. These methods - // allow that. - - // Get the number of cleared objects that are currently being kept - // around for reuse. - int ClearedCount() const; - // Add an element to the pool of cleared objects, passing ownership to - // the RepeatedPtrField. The element must be cleared prior to calling - // this method. - void AddCleared(Element* value); - // Remove a single element from the cleared pool and return it, passing - // ownership to the caller. The element is guaranteed to be cleared. - // Requires: ClearedCount() > 0 - Element* ReleaseCleared(); - - protected: - // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only - // subclass it in one place as a hack for compatibility with proto1. The - // subclass needs to know about TypeHandler in order to call protected - // methods on RepeatedPtrFieldBase. - class TypeHandler; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); -}; - -// implementation ==================================================== - -template -inline RepeatedField::RepeatedField() - : elements_(initial_space_), - current_size_(0), - total_size_(kInitialSize) { -} - -template -RepeatedField::~RepeatedField() { - if (elements_ != initial_space_) { - delete [] elements_; - } -} - -template -inline int RepeatedField::size() const { - return current_size_; -} - -template -inline int RepeatedField::Capacity() const { - return total_size_; -} - -template -inline void RepeatedField::AddAlreadyReserved(const Element& value) { - GOOGLE_DCHECK_LT(size(), Capacity()); - elements_[current_size_++] = value; -} - -template -inline Element* RepeatedField::AddAlreadyReserved() { - GOOGLE_DCHECK_LT(size(), Capacity()); - return &elements_[current_size_++]; -} - -template -inline const Element& RepeatedField::Get(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return elements_[index]; -} - -template -inline Element* RepeatedField::Mutable(int index) { - GOOGLE_DCHECK_LT(index, size()); - return elements_ + index; -} - -template -inline void RepeatedField::Set(int index, const Element& value) { - GOOGLE_DCHECK_LT(index, size()); - elements_[index] = value; -} - -template -inline void RepeatedField::Add(const Element& value) { - if (current_size_ == total_size_) Reserve(total_size_ + 1); - elements_[current_size_++] = value; -} - -template -inline Element* RepeatedField::Add() { - if (current_size_ == total_size_) Reserve(total_size_ + 1); - return &elements_[current_size_++]; -} - -template -inline void RepeatedField::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - --current_size_; -} - -template -inline void RepeatedField::Clear() { - current_size_ = 0; -} - -template -inline void RepeatedField::MergeFrom(const RepeatedField& other) { - Reserve(current_size_ + other.current_size_); - CopyArray(elements_ + current_size_, other.elements_, other.current_size_); - current_size_ += other.current_size_; -} - -template -inline Element* RepeatedField::mutable_data() { - return elements_; -} - -template -inline const Element* RepeatedField::data() const { - return elements_; -} - - -template -void RepeatedField::Swap(RepeatedField* other) { - Element* swap_elements = elements_; - int swap_current_size = current_size_; - int swap_total_size = total_size_; - // We may not be using initial_space_ but it's not worth checking. Just - // copy it anyway. - Element swap_initial_space[kInitialSize]; - MoveArray(swap_initial_space, initial_space_, kInitialSize); - - elements_ = other->elements_; - current_size_ = other->current_size_; - total_size_ = other->total_size_; - MoveArray(initial_space_, other->initial_space_, kInitialSize); - - other->elements_ = swap_elements; - other->current_size_ = swap_current_size; - other->total_size_ = swap_total_size; - MoveArray(other->initial_space_, swap_initial_space, kInitialSize); - - if (elements_ == other->initial_space_) { - elements_ = initial_space_; - } - if (other->elements_ == initial_space_) { - other->elements_ = other->initial_space_; - } -} - -template -void RepeatedField::SwapElements(int index1, int index2) { - std::swap(elements_[index1], elements_[index2]); -} - -template -inline typename RepeatedField::iterator -RepeatedField::begin() { - return elements_; -} -template -inline typename RepeatedField::const_iterator -RepeatedField::begin() const { - return elements_; -} -template -inline typename RepeatedField::iterator -RepeatedField::end() { - return elements_ + current_size_; -} -template -inline typename RepeatedField::const_iterator -RepeatedField::end() const { - return elements_ + current_size_; -} - -template -inline int RepeatedField::SpaceUsedExcludingSelf() const { - return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0; -} - -// Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant -// amount of code bloat. -template -void RepeatedField::Reserve(int new_size) { - if (total_size_ >= new_size) return; - - Element* old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new Element[total_size_]; - MoveArray(elements_, old_elements, current_size_); - if (old_elements != initial_space_) { - delete [] old_elements; - } -} - -template -inline void RepeatedField::Truncate(int new_size) { - GOOGLE_DCHECK_LE(new_size, current_size_); - current_size_ = new_size; -} - -template -inline void RepeatedField::MoveArray( - Element to[], Element from[], int size) { - memcpy(to, from, size * sizeof(Element)); -} - -template -inline void RepeatedField::CopyArray( - Element to[], const Element from[], int size) { - memcpy(to, from, size * sizeof(Element)); -} - - -// ------------------------------------------------------------------- - -namespace internal { - -inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() - : elements_(initial_space_), - current_size_(0), - allocated_size_(0), - total_size_(kInitialSize) { -} - -template -void RepeatedPtrFieldBase::Destroy() { - for (int i = 0; i < allocated_size_; i++) { - TypeHandler::Delete(cast(elements_[i])); - } - if (elements_ != initial_space_) { - delete [] elements_; - } -} - -inline int RepeatedPtrFieldBase::size() const { - return current_size_; -} - - -template -inline const typename TypeHandler::Type& -RepeatedPtrFieldBase::Get(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return *cast(elements_[index]); -} - -template -inline typename TypeHandler::Type* -RepeatedPtrFieldBase::Mutable(int index) { - GOOGLE_DCHECK_LT(index, size()); - return cast(elements_[index]); -} - -template -inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() { - if (current_size_ < allocated_size_) { - return cast(elements_[current_size_++]); - } - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - ++allocated_size_; - typename TypeHandler::Type* result = TypeHandler::New(); - elements_[current_size_++] = result; - return result; -} - -template -inline void RepeatedPtrFieldBase::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - TypeHandler::Clear(cast(elements_[--current_size_])); -} - -template -void RepeatedPtrFieldBase::Clear() { - for (int i = 0; i < current_size_; i++) { - TypeHandler::Clear(cast(elements_[i])); - } - current_size_ = 0; -} - -template -inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { - Reserve(current_size_ + other.current_size_); - for (int i = 0; i < other.current_size_; i++) { - TypeHandler::Merge(other.Get(i), Add()); - } -} - -inline int RepeatedPtrFieldBase::Capacity() const { - return total_size_; -} - -inline void* const* RepeatedPtrFieldBase::raw_data() const { - return elements_; -} - -inline void** RepeatedPtrFieldBase::raw_mutable_data() const { - return elements_; -} - -template -inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { - // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this - // method entirely. - return reinterpret_cast(elements_); -} - -template -inline const typename TypeHandler::Type* const* -RepeatedPtrFieldBase::data() const { - // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this - // method entirely. - return reinterpret_cast(elements_); -} - -inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { - std::swap(elements_[index1], elements_[index2]); -} - -template -inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const { - int allocated_bytes = - (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0; - for (int i = 0; i < allocated_size_; ++i) { - allocated_bytes += TypeHandler::SpaceUsed(*cast(elements_[i])); - } - return allocated_bytes; -} - -template -inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { - if (current_size_ < allocated_size_) { - return cast(elements_[current_size_++]); - } else { - return NULL; - } -} - -template -void RepeatedPtrFieldBase::AddAllocated( - typename TypeHandler::Type* value) { - // Make room for the new pointer. - if (current_size_ == total_size_) { - // The array is completely full with no cleared objects, so grow it. - Reserve(total_size_ + 1); - ++allocated_size_; - } else if (allocated_size_ == total_size_) { - // There is no more space in the pointer array because it contains some - // cleared objects awaiting reuse. We don't want to grow the array in this - // case because otherwise a loop calling AddAllocated() followed by Clear() - // would leak memory. - TypeHandler::Delete(cast(elements_[current_size_])); - } else if (current_size_ < allocated_size_) { - // We have some cleared objects. We don't care about their order, so we - // can just move the first one to the end to make space. - elements_[allocated_size_] = elements_[current_size_]; - ++allocated_size_; - } else { - // There are no cleared objects. - ++allocated_size_; - } - - elements_[current_size_++] = value; -} - -template -inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - typename TypeHandler::Type* result = - cast(elements_[--current_size_]); - --allocated_size_; - if (current_size_ < allocated_size_) { - // There are cleared elements on the end; replace the removed element - // with the last allocated element. - elements_[current_size_] = elements_[allocated_size_]; - } - return result; -} - - -inline int RepeatedPtrFieldBase::ClearedCount() const { - return allocated_size_ - current_size_; -} - -template -inline void RepeatedPtrFieldBase::AddCleared( - typename TypeHandler::Type* value) { - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - elements_[allocated_size_++] = value; -} - -template -inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { - GOOGLE_DCHECK_GT(allocated_size_, current_size_); - return cast(elements_[--allocated_size_]); -} - -} // namespace internal - -// ------------------------------------------------------------------- - -template -class RepeatedPtrField::TypeHandler - : public internal::GenericTypeHandler {}; - -template <> -class RepeatedPtrField::TypeHandler - : public internal::StringTypeHandler {}; - - -template -inline RepeatedPtrField::RepeatedPtrField() {} - -template -RepeatedPtrField::~RepeatedPtrField() { - Destroy(); -} - -template -inline int RepeatedPtrField::size() const { - return RepeatedPtrFieldBase::size(); -} - -template -inline const Element& RepeatedPtrField::Get(int index) const { - return RepeatedPtrFieldBase::Get(index); -} - -template -inline Element* RepeatedPtrField::Mutable(int index) { - return RepeatedPtrFieldBase::Mutable(index); -} - -template -inline Element* RepeatedPtrField::Add() { - return RepeatedPtrFieldBase::Add(); -} - -template -inline void RepeatedPtrField::RemoveLast() { - RepeatedPtrFieldBase::RemoveLast(); -} - -template -inline void RepeatedPtrField::Clear() { - RepeatedPtrFieldBase::Clear(); -} - -template -inline void RepeatedPtrField::MergeFrom( - const RepeatedPtrField& other) { - RepeatedPtrFieldBase::MergeFrom(other); -} - -template -inline Element** RepeatedPtrField::mutable_data() { - return RepeatedPtrFieldBase::mutable_data(); -} - -template -inline const Element* const* RepeatedPtrField::data() const { - return RepeatedPtrFieldBase::data(); -} - -template -void RepeatedPtrField::Swap(RepeatedPtrField* other) { - RepeatedPtrFieldBase::Swap(other); -} - -template -void RepeatedPtrField::SwapElements(int index1, int index2) { - RepeatedPtrFieldBase::SwapElements(index1, index2); -} - -template -inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { - return RepeatedPtrFieldBase::SpaceUsedExcludingSelf(); -} - -template -inline void RepeatedPtrField::AddAllocated(Element* value) { - RepeatedPtrFieldBase::AddAllocated(value); -} - -template -inline Element* RepeatedPtrField::ReleaseLast() { - return RepeatedPtrFieldBase::ReleaseLast(); -} - - -template -inline int RepeatedPtrField::ClearedCount() const { - return RepeatedPtrFieldBase::ClearedCount(); -} - -template -inline void RepeatedPtrField::AddCleared(Element* value) { - return RepeatedPtrFieldBase::AddCleared(value); -} - -template -inline Element* RepeatedPtrField::ReleaseCleared() { - return RepeatedPtrFieldBase::ReleaseCleared(); -} - -template -inline void RepeatedPtrField::Reserve(int new_size) { - return RepeatedPtrFieldBase::Reserve(new_size); -} - -template -inline int RepeatedPtrField::Capacity() const { - return RepeatedPtrFieldBase::Capacity(); -} - -// ------------------------------------------------------------------- - -namespace internal { - -// STL-like iterator implementation for RepeatedPtrField. You should not -// refer to this class directly; use RepeatedPtrField::iterator instead. -// -// The iterator for RepeatedPtrField, RepeatedPtrIterator, is -// very similar to iterator_ptr in util/gtl/iterator_adaptors-inl.h, -// but adds random-access operators and is modified to wrap a void** base -// iterator (since RepeatedPtrField stores its array as a void* array and -// casting void** to T** would violate C++ aliasing rules). -// -// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin -// (jyasskin@google.com). -template -class RepeatedPtrIterator - : public std::iterator< - std::random_access_iterator_tag, Element> { - public: - typedef RepeatedPtrIterator iterator; - typedef std::iterator< - std::random_access_iterator_tag, Element> superclass; - - // Let the compiler know that these are type names, so we don't have to - // write "typename" in front of them everywhere. - typedef typename superclass::reference reference; - typedef typename superclass::pointer pointer; - typedef typename superclass::difference_type difference_type; - - RepeatedPtrIterator() : it_(NULL) {} - explicit RepeatedPtrIterator(void* const* it) : it_(it) {} - - // Allow "upcasting" from RepeatedPtrIterator to - // RepeatedPtrIterator. - template - RepeatedPtrIterator(const RepeatedPtrIterator& other) - : it_(other.it_) { - // Force a compiler error if the other type is not convertable to ours. - if (false) { - implicit_cast(0); - } - } - - // dereferenceable - reference operator*() const { return *reinterpret_cast(*it_); } - pointer operator->() const { return &(operator*()); } - - // {inc,dec}rementable - iterator& operator++() { ++it_; return *this; } - iterator operator++(int) { return iterator(it_++); } - iterator& operator--() { --it_; return *this; } - iterator operator--(int) { return iterator(it_--); } - - // equality_comparable - bool operator==(const iterator& x) const { return it_ == x.it_; } - bool operator!=(const iterator& x) const { return it_ != x.it_; } - - // less_than_comparable - bool operator<(const iterator& x) const { return it_ < x.it_; } - bool operator<=(const iterator& x) const { return it_ <= x.it_; } - bool operator>(const iterator& x) const { return it_ > x.it_; } - bool operator>=(const iterator& x) const { return it_ >= x.it_; } - - // addable, subtractable - iterator& operator+=(difference_type d) { - it_ += d; - return *this; - } - friend iterator operator+(iterator it, difference_type d) { - it += d; - return it; - } - friend iterator operator+(difference_type d, iterator it) { - it += d; - return it; - } - iterator& operator-=(difference_type d) { - it_ -= d; - return *this; - } - friend iterator operator-(iterator it, difference_type d) { - it -= d; - return it; - } - - // indexable - reference operator[](difference_type d) const { return *(*this + d); } - - // random access iterator - difference_type operator-(const iterator& x) const { return it_ - x.it_; } - - private: - template - friend class RepeatedPtrIterator; - - // The internal iterator. - void* const* it_; -}; - -// Provide an iterator that operates on pointers to the underlying objects -// rather than the objects themselves as RepeatedPtrIterator does. -// Consider using this when working with stl algorithms that change -// the array. -template -class RepeatedPtrOverPtrsIterator - : public std::iterator { - public: - typedef RepeatedPtrOverPtrsIterator iterator; - typedef std::iterator< - std::random_access_iterator_tag, Element*> superclass; - - // Let the compiler know that these are type names, so we don't have to - // write "typename" in front of them everywhere. - typedef typename superclass::reference reference; - typedef typename superclass::pointer pointer; - typedef typename superclass::difference_type difference_type; - - RepeatedPtrOverPtrsIterator() : it_(NULL) {} - explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {} - - // dereferenceable - reference operator*() const { return *reinterpret_cast(it_); } - pointer operator->() const { return &(operator*()); } - - // {inc,dec}rementable - iterator& operator++() { ++it_; return *this; } - iterator operator++(int) { return iterator(it_++); } - iterator& operator--() { --it_; return *this; } - iterator operator--(int) { return iterator(it_--); } - - // equality_comparable - bool operator==(const iterator& x) const { return it_ == x.it_; } - bool operator!=(const iterator& x) const { return it_ != x.it_; } - - // less_than_comparable - bool operator<(const iterator& x) const { return it_ < x.it_; } - bool operator<=(const iterator& x) const { return it_ <= x.it_; } - bool operator>(const iterator& x) const { return it_ > x.it_; } - bool operator>=(const iterator& x) const { return it_ >= x.it_; } - - // addable, subtractable - iterator& operator+=(difference_type d) { - it_ += d; - return *this; - } - friend iterator operator+(iterator it, difference_type d) { - it += d; - return it; - } - friend iterator operator+(difference_type d, iterator it) { - it += d; - return it; - } - iterator& operator-=(difference_type d) { - it_ -= d; - return *this; - } - friend iterator operator-(iterator it, difference_type d) { - it -= d; - return it; - } - - // indexable - reference operator[](difference_type d) const { return *(*this + d); } - - // random access iterator - difference_type operator-(const iterator& x) const { return it_ - x.it_; } - - private: - template - friend class RepeatedPtrIterator; - - // The internal iterator. - void** it_; -}; - - -} // namespace internal - -template -inline typename RepeatedPtrField::iterator -RepeatedPtrField::begin() { - return iterator(raw_data()); -} -template -inline typename RepeatedPtrField::const_iterator -RepeatedPtrField::begin() const { - return iterator(raw_data()); -} -template -inline typename RepeatedPtrField::iterator -RepeatedPtrField::end() { - return iterator(raw_data() + size()); -} -template -inline typename RepeatedPtrField::const_iterator -RepeatedPtrField::end() const { - return iterator(raw_data() + size()); -} - -template -inline typename RepeatedPtrField::pointer_iterator -RepeatedPtrField::pointer_begin() { - return pointer_iterator(raw_mutable_data()); -} -template -inline typename RepeatedPtrField::pointer_iterator -RepeatedPtrField::pointer_end() { - return pointer_iterator(raw_mutable_data() + size()); -} - - -// Iterators and helper functions that follow the spirit of the STL -// std::back_insert_iterator and std::back_inserter but are tailor-made -// for RepeatedField and RepatedPtrField. Typical usage would be: -// -// std::copy(some_sequence.begin(), some_sequence.end(), -// google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence())); -// -// Ported by johannes from util/gtl/proto-array-iterators-inl.h - -namespace internal { -// A back inserter for RepeatedField objects. -template class RepeatedFieldBackInsertIterator - : public std::iterator { - public: - explicit RepeatedFieldBackInsertIterator( - RepeatedField* const mutable_field) - : field_(mutable_field) { - } - RepeatedFieldBackInsertIterator& operator=(const T& value) { - field_->Add(value); - return *this; - } - RepeatedFieldBackInsertIterator& operator*() { - return *this; - } - RepeatedFieldBackInsertIterator& operator++() { - return *this; - } - RepeatedFieldBackInsertIterator& operator++(int ignores_parameter) { - return *this; - } - - private: - RepeatedField* const field_; -}; - -// A back inserter for RepeatedPtrField objects. -template class RepeatedPtrFieldBackInsertIterator - : public std::iterator { - public: - RepeatedPtrFieldBackInsertIterator( - RepeatedPtrField* const mutable_field) - : field_(mutable_field) { - } - RepeatedPtrFieldBackInsertIterator& operator=(const T& value) { - *field_->Add() = value; - return *this; - } - RepeatedPtrFieldBackInsertIterator& operator=( - const T* const ptr_to_value) { - *field_->Add() = *ptr_to_value; - return *this; - } - RepeatedPtrFieldBackInsertIterator& operator*() { - return *this; - } - RepeatedPtrFieldBackInsertIterator& operator++() { - return *this; - } - RepeatedPtrFieldBackInsertIterator& operator++(int ignores_parameter) { - return *this; - } - - private: - RepeatedPtrField* const field_; -}; - -// A back inserter for RepeatedPtrFields that inserts by transfering ownership -// of a pointer. -template class AllocatedRepeatedPtrFieldBackInsertIterator - : public std::iterator { - public: - explicit AllocatedRepeatedPtrFieldBackInsertIterator( - RepeatedPtrField* const mutable_field) - : field_(mutable_field) { - } - AllocatedRepeatedPtrFieldBackInsertIterator& operator=( - T* const ptr_to_value) { - field_->AddAllocated(ptr_to_value); - return *this; - } - AllocatedRepeatedPtrFieldBackInsertIterator& operator*() { - return *this; - } - AllocatedRepeatedPtrFieldBackInsertIterator& operator++() { - return *this; - } - AllocatedRepeatedPtrFieldBackInsertIterator& operator++( - int ignores_parameter) { - return *this; - } - - private: - RepeatedPtrField* const field_; -}; -} // namespace internal - -// Provides a back insert iterator for RepeatedField instances, -// similar to std::back_inserter(). Note the identically named -// function for RepeatedPtrField instances. -template internal::RepeatedFieldBackInsertIterator -RepeatedFieldBackInserter(RepeatedField* const mutable_field) { - return internal::RepeatedFieldBackInsertIterator(mutable_field); -} - -// Provides a back insert iterator for RepeatedPtrField instances, -// similar to std::back_inserter(). Note the identically named -// function for RepeatedField instances. -template internal::RepeatedPtrFieldBackInsertIterator -RepeatedFieldBackInserter(RepeatedPtrField* const mutable_field) { - return internal::RepeatedPtrFieldBackInsertIterator(mutable_field); -} - -// Provides a back insert iterator for RepeatedPtrField instances -// similar to std::back_inserter() which transfers the ownership while -// copying elements. -template internal::AllocatedRepeatedPtrFieldBackInsertIterator -AllocatedRepeatedPtrFieldBackInserter( - RepeatedPtrField* const mutable_field) { - return internal::AllocatedRepeatedPtrFieldBackInsertIterator( - mutable_field); -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ diff --git a/Resources/NetHook/google/protobuf/repeated_field_unittest.cc b/Resources/NetHook/google/protobuf/repeated_field_unittest.cc deleted file mode 100644 index 7c35f604..00000000 --- a/Resources/NetHook/google/protobuf/repeated_field_unittest.cc +++ /dev/null @@ -1,986 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// TODO(kenton): Improve this unittest to bring it up to the standards of -// other proto2 unittests. - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace google { -using protobuf_unittest::TestAllTypes; - -namespace protobuf { -namespace { - -// Test operations on a RepeatedField which is small enough that it does -// not allocate a separate array for storage. -TEST(RepeatedField, Small) { - RepeatedField field; - - EXPECT_EQ(field.size(), 0); - - field.Add(5); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Add(42); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 42); - - field.Set(1, 23); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 23); - EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0); - - field.RemoveLast(); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Clear(); - - EXPECT_EQ(field.size(), 0); - EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0); -} - -// Test operations on a RepeatedField which is large enough to allocate a -// separate array. -TEST(RepeatedField, Large) { - RepeatedField field; - - for (int i = 0; i < 16; i++) { - field.Add(i * i); - } - - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i), i * i); - } - - int expected_usage = 16 * sizeof(int); - EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage); -} - -// Test swapping between various types of RepeatedFields. -TEST(RepeatedField, SwapSmallSmall) { - RepeatedField field1; - RepeatedField field2; - - field1.Add(5); - field1.Add(42); - - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 0); - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); -} - -TEST(RepeatedField, SwapLargeSmall) { - RepeatedField field1; - RepeatedField field2; - - for (int i = 0; i < 16; i++) { - field1.Add(i * i); - } - field2.Add(5); - field2.Add(42); - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), 5); - EXPECT_EQ(field1.Get(1), 42); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i), i * i); - } -} - -TEST(RepeatedField, SwapLargeLarge) { - RepeatedField field1; - RepeatedField field2; - - field1.Add(5); - field1.Add(42); - for (int i = 0; i < 16; i++) { - field1.Add(i); - field2.Add(i * i); - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i), i * i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i), i - 2); - } -} - -// Determines how much space was reserved by the given field by adding elements -// to it until it re-allocates its space. -static int ReservedSpace(RepeatedField* field) { - const int* ptr = field->data(); - do { - field->Add(0); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedField, ReserveMoreThanDouble) { - // Reserve more than double the previous space in the field and expect the - // field to reserve exactly the amount specified. - RepeatedField field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanDouble) { - // Reserve less than double the previous space in the field and expect the - // field to grow by double instead. - RepeatedField field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanExisting) { - // Reserve less than the previous space in the field and expect the - // field to not re-allocate at all. - RepeatedField field; - field.Reserve(20); - const int* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, MergeFrom) { - RepeatedField source, destination; - - source.Add(4); - source.Add(5); - - destination.Add(1); - destination.Add(2); - destination.Add(3); - - destination.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - - EXPECT_EQ(1, destination.Get(0)); - EXPECT_EQ(2, destination.Get(1)); - EXPECT_EQ(3, destination.Get(2)); - EXPECT_EQ(4, destination.Get(3)); - EXPECT_EQ(5, destination.Get(4)); -} - -TEST(RepeatedField, MutableDataIsMutable) { - RepeatedField field; - field.Add(1); - EXPECT_EQ(1, field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - *field.mutable_data() = 2; - EXPECT_EQ(2, field.Get(0)); -} - -TEST(RepeatedField, Truncate) { - RepeatedField field; - - field.Add(12); - field.Add(34); - field.Add(56); - field.Add(78); - EXPECT_EQ(4, field.size()); - - field.Truncate(3); - EXPECT_EQ(3, field.size()); - - field.Add(90); - EXPECT_EQ(4, field.size()); - EXPECT_EQ(90, field.Get(3)); - - // Truncations that don't change the size are allowed, but growing is not - // allowed. - field.Truncate(field.size()); -#ifdef GTEST_HAS_DEATH_TEST - EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size"); -#endif -} - - -// =================================================================== -// RepeatedPtrField tests. These pretty much just mirror the RepeatedField -// tests above. - -TEST(RepeatedPtrField, Small) { - RepeatedPtrField field; - - EXPECT_EQ(field.size(), 0); - - field.Add()->assign("foo"); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Add()->assign("bar"); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "bar"); - - field.Mutable(1)->assign("baz"); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "baz"); - - field.RemoveLast(); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Clear(); - - EXPECT_EQ(field.size(), 0); -} - -TEST(RepeatedPtrField, Large) { - RepeatedPtrField field; - - for (int i = 0; i < 16; i++) { - *field.Add() += 'a' + i; - } - - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i).size(), 1); - EXPECT_EQ(field.Get(i)[0], 'a' + i); - } - - int min_expected_usage = 16 * sizeof(string); - EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); -} - -TEST(RepeatedPtrField, SwapSmallSmall) { - RepeatedPtrField field1; - RepeatedPtrField field2; - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 0); - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); -} - -TEST(RepeatedPtrField, SwapLargeSmall) { - RepeatedPtrField field1; - RepeatedPtrField field2; - - field2.Add()->assign("foo"); - field2.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'a' + i; - } - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), "foo"); - EXPECT_EQ(field1.Get(1), "bar"); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'a' + i); - } -} - -TEST(RepeatedPtrField, SwapLargeLarge) { - RepeatedPtrField field1; - RepeatedPtrField field2; - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'A' + i; - *field2.Add() += 'a' + i; - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i).size(), 1); - EXPECT_EQ(field1.Get(i)[0], 'a' + i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); - } -} - -static int ReservedSpace(RepeatedPtrField* field) { - const string* const* ptr = field->data(); - do { - field->Add(); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedPtrField, ReserveMoreThanDouble) { - RepeatedPtrField field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanDouble) { - RepeatedPtrField field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanExisting) { - RepeatedPtrField field; - field.Reserve(20); - const string* const* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { - // Check that a bug is fixed: An earlier implementation of Reserve() - // failed to copy pointers to allocated-but-cleared objects, possibly - // leading to segfaults. - RepeatedPtrField field; - string* first = field.Add(); - field.RemoveLast(); - - field.Reserve(20); - EXPECT_EQ(first, field.Add()); -} - -// Clearing elements is tricky with RepeatedPtrFields since the memory for -// the elements is retained and reused. -TEST(RepeatedPtrField, ClearedElements) { - RepeatedPtrField field; - - string* original = field.Add(); - *original = "foo"; - - EXPECT_EQ(field.ClearedCount(), 0); - - field.RemoveLast(); - EXPECT_TRUE(original->empty()); - EXPECT_EQ(field.ClearedCount(), 1); - - EXPECT_EQ(field.Add(), original); // Should return same string for reuse. - - EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. - EXPECT_EQ(field.ClearedCount(), 0); - - EXPECT_NE(field.Add(), original); // Should NOT return the same string. - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddAllocated(original); // Give ownership back. - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_EQ(field.Mutable(1), original); - - field.Clear(); - EXPECT_EQ(field.ClearedCount(), 2); - EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddCleared(original); // Give ownership back, but as a cleared object. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_EQ(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); -} - -// Test all code paths in AddAllocated(). -TEST(RepeatedPtrField, AddAlocated) { - RepeatedPtrField field; - while (field.size() < field.Capacity()) { - field.Add()->assign("filler"); - } - - int index = field.size(); - - // First branch: Field is at capacity with no cleared objects. - string* foo = new string("foo"); - field.AddAllocated(foo); - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(foo, &field.Get(index)); - - // Last branch: Field is not at capacity and there are no cleared objects. - string* bar = new string("bar"); - field.AddAllocated(bar); - ++index; - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(bar, &field.Get(index)); - - // Third branch: Field is not at capacity and there are no cleared objects. - field.RemoveLast(); - string* baz = new string("baz"); - field.AddAllocated(baz); - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(1, field.ClearedCount()); - EXPECT_EQ(baz, &field.Get(index)); - - // Second branch: Field is at capacity but has some cleared objects. - while (field.size() < field.Capacity()) { - field.Add()->assign("filler2"); - } - field.RemoveLast(); - index = field.size(); - string* qux = new string("qux"); - field.AddAllocated(qux); - EXPECT_EQ(index + 1, field.size()); - // We should have discarded the cleared object. - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(qux, &field.Get(index)); -} - -TEST(RepeatedPtrField, MergeFrom) { - RepeatedPtrField source, destination; - - source.Add()->assign("4"); - source.Add()->assign("5"); - - destination.Add()->assign("1"); - destination.Add()->assign("2"); - destination.Add()->assign("3"); - - destination.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - - EXPECT_EQ("1", destination.Get(0)); - EXPECT_EQ("2", destination.Get(1)); - EXPECT_EQ("3", destination.Get(2)); - EXPECT_EQ("4", destination.Get(3)); - EXPECT_EQ("5", destination.Get(4)); -} - -TEST(RepeatedPtrField, MutableDataIsMutable) { - RepeatedPtrField field; - *field.Add() = "1"; - EXPECT_EQ("1", field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - string** data = field.mutable_data(); - **data = "2"; - EXPECT_EQ("2", field.Get(0)); -} - -// =================================================================== - -// Iterator tests stolen from net/proto/proto-array_unittest. -class RepeatedFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - for (int i = 0; i < 3; ++i) { - proto_array_.Add(i); - } - } - - RepeatedField proto_array_; -}; - -TEST_F(RepeatedFieldIteratorTest, Convertible) { - RepeatedField::iterator iter = proto_array_.begin(); - RepeatedField::const_iterator c_iter = iter; - EXPECT_EQ(0, *c_iter); -} - -TEST_F(RepeatedFieldIteratorTest, MutableIteration) { - RepeatedField::iterator iter = proto_array_.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, ConstIteration) { - const RepeatedField& const_proto_array = proto_array_; - RepeatedField::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, Mutation) { - RepeatedField::iterator iter = proto_array_.begin(); - *iter = 7; - EXPECT_EQ(7, proto_array_.Get(0)); -} - -// ------------------------------------------------------------------- - -class RepeatedPtrFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - proto_array_.Add()->assign("foo"); - proto_array_.Add()->assign("bar"); - proto_array_.Add()->assign("baz"); - } - - RepeatedPtrField proto_array_; -}; - -TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { - RepeatedPtrField::iterator iter = proto_array_.begin(); - RepeatedPtrField::const_iterator c_iter = iter; -} - -TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { - RepeatedPtrField::iterator iter = proto_array_.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ("baz", *(--proto_array_.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { - const RepeatedPtrField& const_proto_array = proto_array_; - RepeatedPtrField::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(const_proto_array.end() == iter); - EXPECT_EQ("baz", *(--const_proto_array.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { - RepeatedPtrField::iterator iter = proto_array_.begin(); - RepeatedPtrField::iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", iter[2]); - EXPECT_EQ("baz", *(iter + 2)); - EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { - RepeatedPtrField::const_iterator iter = proto_array_.begin(); - RepeatedPtrField::const_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -// Uninitialized iterator does not point to any of the RepeatedPtrField. -TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { - RepeatedPtrField::iterator iter; - EXPECT_TRUE(iter != proto_array_.begin()); - EXPECT_TRUE(iter != proto_array_.begin() + 1); - EXPECT_TRUE(iter != proto_array_.begin() + 2); - EXPECT_TRUE(iter != proto_array_.begin() + 3); - EXPECT_TRUE(iter != proto_array_.end()); -} - -TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { - proto_array_.Clear(); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("x"); - proto_array_.Add()->assign("y"); - - string v = "f"; - RepeatedPtrField::const_iterator it = - lower_bound(proto_array_.begin(), proto_array_.end(), v); - - EXPECT_EQ(*it, "n"); - EXPECT_TRUE(it == proto_array_.begin() + 3); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { - RepeatedPtrField::iterator iter = proto_array_.begin(); - *iter = "qux"; - EXPECT_EQ("qux", proto_array_.Get(0)); -} - -// ------------------------------------------------------------------- - -class RepeatedPtrFieldPtrsIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - proto_array_.Add()->assign("foo"); - proto_array_.Add()->assign("bar"); - proto_array_.Add()->assign("baz"); - } - - RepeatedPtrField proto_array_; -}; - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) { - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) { - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); - EXPECT_EQ("foo", **iter); - ++iter; - EXPECT_EQ("bar", **(iter++)); - EXPECT_EQ("baz", **iter); - ++iter; - EXPECT_TRUE(proto_array_.pointer_end() == iter); - EXPECT_EQ("baz", **(--proto_array_.pointer_end())); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) { - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); - RepeatedPtrField::pointer_iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", *iter[2]); - EXPECT_EQ("baz", **(iter + 2)); - EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) { - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); - RepeatedPtrField::pointer_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs. -// Dereferencing an uninitialized iterator crashes the process. -TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) { - RepeatedPtrField::pointer_iterator iter; - EXPECT_TRUE(iter != proto_array_.pointer_begin()); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3); - EXPECT_TRUE(iter != proto_array_.pointer_end()); -} - - -// This comparison functor is required by the tests for RepeatedPtrOverPtrs. -// They operate on strings and need to compare strings as strings in -// any stl algorithm, even though the iterator returns a pointer to a string -// - i.e. *iter has type string*. -struct StringLessThan { - bool operator()(const string* z, const string& y) { - return *z < y; - } - bool operator()(const string* z, const string* y) { - return *z < *y; - } -}; - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) { - proto_array_.Clear(); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("x"); - proto_array_.Add()->assign("y"); - - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); - string v = "f"; - RepeatedPtrField::pointer_iterator it = - lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(), - &v, StringLessThan()); - - GOOGLE_CHECK(*it != NULL); - - EXPECT_EQ(**it, "n"); - EXPECT_TRUE(it == proto_array_.pointer_begin() + 3); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) { - RepeatedPtrField::pointer_iterator iter = - proto_array_.pointer_begin(); - **iter = "qux"; - EXPECT_EQ("qux", proto_array_.Get(0)); - - EXPECT_EQ("bar", proto_array_.Get(1)); - EXPECT_EQ("baz", proto_array_.Get(2)); - ++iter; - delete *iter; - *iter = new string("a"); - ++iter; - delete *iter; - *iter = new string("b"); - EXPECT_EQ("a", proto_array_.Get(1)); - EXPECT_EQ("b", proto_array_.Get(2)); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) { - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("y"); - proto_array_.Add()->assign("x"); - EXPECT_EQ("foo", proto_array_.Get(0)); - EXPECT_EQ("n", proto_array_.Get(5)); - EXPECT_EQ("x", proto_array_.Get(9)); - sort(proto_array_.pointer_begin(), - proto_array_.pointer_end(), - StringLessThan()); - EXPECT_EQ("a", proto_array_.Get(0)); - EXPECT_EQ("baz", proto_array_.Get(2)); - EXPECT_EQ("y", proto_array_.Get(9)); -} - - -// ----------------------------------------------------------------------------- -// Unit-tests for the insert iterators -// google::protobuf::RepeatedFieldBackInserter, -// google::protobuf::AllocatedRepeatedPtrFieldBackInserter -// Ported from util/gtl/proto-array-iterators_unittest. - -class RepeatedFieldInsertionIteratorsTest : public testing::Test { - protected: - std::list halves; - std::list fibonacci; - std::vector words; - typedef TestAllTypes::NestedMessage Nested; - Nested nesteds[2]; - std::vector nested_ptrs; - TestAllTypes protobuffer; - - virtual void SetUp() { - fibonacci.push_back(1); - fibonacci.push_back(1); - fibonacci.push_back(2); - fibonacci.push_back(3); - fibonacci.push_back(5); - fibonacci.push_back(8); - std::copy(fibonacci.begin(), fibonacci.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32())); - - halves.push_back(1.0); - halves.push_back(0.5); - halves.push_back(0.25); - halves.push_back(0.125); - halves.push_back(0.0625); - std::copy(halves.begin(), halves.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_double())); - - words.push_back("Able"); - words.push_back("was"); - words.push_back("I"); - words.push_back("ere"); - words.push_back("I"); - words.push_back("saw"); - words.push_back("Elba"); - std::copy(words.begin(), words.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_string())); - - nesteds[0].set_bb(17); - nesteds[1].set_bb(4711); - std::copy(&nesteds[0], &nesteds[2], - RepeatedFieldBackInserter( - protobuffer.mutable_repeated_nested_message())); - - nested_ptrs.push_back(new Nested); - nested_ptrs.back()->set_bb(170); - nested_ptrs.push_back(new Nested); - nested_ptrs.back()->set_bb(47110); - std::copy(nested_ptrs.begin(), nested_ptrs.end(), - RepeatedFieldBackInserter( - protobuffer.mutable_repeated_nested_message())); - - } - - virtual void TearDown() { - STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end()); - } -}; - -TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) { - EXPECT_TRUE(std::equal(fibonacci.begin(), - fibonacci.end(), - protobuffer.repeated_int32().begin())); - EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(), - protobuffer.repeated_int32().end(), - fibonacci.begin())); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) { - EXPECT_TRUE(std::equal(halves.begin(), - halves.end(), - protobuffer.repeated_double().begin())); - EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(), - protobuffer.repeated_double().end(), - halves.begin())); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Words) { - ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); - EXPECT_EQ(words.at(0), protobuffer.repeated_string(0)); - EXPECT_EQ(words.at(1), protobuffer.repeated_string(1)); - EXPECT_EQ(words.at(2), protobuffer.repeated_string(2)); - EXPECT_EQ(words.at(3), protobuffer.repeated_string(3)); - EXPECT_EQ(words.at(4), protobuffer.repeated_string(4)); - EXPECT_EQ(words.at(5), protobuffer.repeated_string(5)); - EXPECT_EQ(words.at(6), protobuffer.repeated_string(6)); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) { - ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4); - EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17); - EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711); - EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170); - EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - AllocatedRepeatedPtrFieldWithStringIntData) { - vector data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - Nested* new_data = new Nested; - new_data->set_bb(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_nested_message(); - new_data->set_bb(i); - } - TestAllTypes testproto; - copy(data.begin(), data.end(), - AllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_nested_message())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - AllocatedRepeatedPtrFieldWithString) { - vector data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - string* new_data = new string; - *new_data = "name-" + SimpleItoa(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_string(); - *new_data = "name-" + SimpleItoa(i); - } - TestAllTypes testproto; - copy(data.begin(), data.end(), - AllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_string())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -} // namespace - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/service.cc b/Resources/NetHook/google/protobuf/service.cc deleted file mode 100644 index caf968ca..00000000 --- a/Resources/NetHook/google/protobuf/service.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -namespace google { -namespace protobuf { - -Service::~Service() {} -RpcChannel::~RpcChannel() {} -RpcController::~RpcController() {} - -} // namespace protobuf - -} // namespace google diff --git a/Resources/NetHook/google/protobuf/service.h b/Resources/NetHook/google/protobuf/service.h deleted file mode 100644 index a6a7d16d..00000000 --- a/Resources/NetHook/google/protobuf/service.h +++ /dev/null @@ -1,291 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// DEPRECATED: This module declares the abstract interfaces underlying proto2 -// RPC services. These are intented to be independent of any particular RPC -// implementation, so that proto2 services can be used on top of a variety -// of implementations. Starting with version 2.3.0, RPC implementations should -// not try to build on these, but should instead provide code generator plugins -// which generate code specific to the particular RPC implementation. This way -// the generated code can be more appropriate for the implementation in use -// and can avoid unnecessary layers of indirection. -// -// -// When you use the protocol compiler to compile a service definition, it -// generates two classes: An abstract interface for the service (with -// methods matching the service definition) and a "stub" implementation. -// A stub is just a type-safe wrapper around an RpcChannel which emulates a -// local implementation of the service. -// -// For example, the service definition: -// service MyService { -// rpc Foo(MyRequest) returns(MyResponse); -// } -// will generate abstract interface "MyService" and class "MyService::Stub". -// You could implement a MyService as follows: -// class MyServiceImpl : public MyService { -// public: -// MyServiceImpl() {} -// ~MyServiceImpl() {} -// -// // implements MyService --------------------------------------- -// -// void Foo(google::protobuf::RpcController* controller, -// const MyRequest* request, -// MyResponse* response, -// Closure* done) { -// // ... read request and fill in response ... -// done->Run(); -// } -// }; -// You would then register an instance of MyServiceImpl with your RPC server -// implementation. (How to do that depends on the implementation.) -// -// To call a remote MyServiceImpl, first you need an RpcChannel connected to it. -// How to construct a channel depends, again, on your RPC implementation. -// Here we use a hypothentical "MyRpcChannel" as an example: -// MyRpcChannel channel("rpc:hostname:1234/myservice"); -// MyRpcController controller; -// MyServiceImpl::Stub stub(&channel); -// FooRequest request; -// FooRespnose response; -// -// // ... fill in request ... -// -// stub.Foo(&controller, request, &response, NewCallback(HandleResponse)); -// -// On Thread-Safety: -// -// Different RPC implementations may make different guarantees about what -// threads they may run callbacks on, and what threads the application is -// allowed to use to call the RPC system. Portable software should be ready -// for callbacks to be called on any thread, but should not try to call the -// RPC system from any thread except for the ones on which it received the -// callbacks. Realistically, though, simple software will probably want to -// use a single-threaded RPC system while high-end software will want to -// use multiple threads. RPC implementations should provide multiple -// choices. - -#ifndef GOOGLE_PROTOBUF_SERVICE_H__ -#define GOOGLE_PROTOBUF_SERVICE_H__ - -#include -#include - -namespace google { -namespace protobuf { - -// Defined in this file. -class Service; -class RpcController; -class RpcChannel; - -// Defined in other files. -class Descriptor; // descriptor.h -class ServiceDescriptor; // descriptor.h -class MethodDescriptor; // descriptor.h -class Message; // message.h - -// Abstract base interface for protocol-buffer-based RPC services. Services -// themselves are abstract interfaces (implemented either by servers or as -// stubs), but they subclass this base interface. The methods of this -// interface can be used to call the methods of the Service without knowing -// its exact type at compile time (analogous to Reflection). -class LIBPROTOBUF_EXPORT Service { - public: - inline Service() {} - virtual ~Service(); - - // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second - // parameter to the constructor to tell it to delete its RpcChannel when - // destroyed. - enum ChannelOwnership { - STUB_OWNS_CHANNEL, - STUB_DOESNT_OWN_CHANNEL - }; - - // Get the ServiceDescriptor describing this service and its methods. - virtual const ServiceDescriptor* GetDescriptor() = 0; - - // Call a method of the service specified by MethodDescriptor. This is - // normally implemented as a simple switch() that calls the standard - // definitions of the service's methods. - // - // Preconditions: - // * method->service() == GetDescriptor() - // * request and response are of the exact same classes as the objects - // returned by GetRequestPrototype(method) and - // GetResponsePrototype(method). - // * After the call has started, the request must not be modified and the - // response must not be accessed at all until "done" is called. - // * "controller" is of the correct type for the RPC implementation being - // used by this Service. For stubs, the "correct type" depends on the - // RpcChannel which the stub is using. Server-side Service - // implementations are expected to accept whatever type of RpcController - // the server-side RPC implementation uses. - // - // Postconditions: - // * "done" will be called when the method is complete. This may be - // before CallMethod() returns or it may be at some point in the future. - // * If the RPC succeeded, "response" contains the response returned by - // the server. - // * If the RPC failed, "response"'s contents are undefined. The - // RpcController can be queried to determine if an error occurred and - // possibly to get more information about the error. - virtual void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) = 0; - - // CallMethod() requires that the request and response passed in are of a - // particular subclass of Message. GetRequestPrototype() and - // GetResponsePrototype() get the default instances of these required types. - // You can then call Message::New() on these instances to construct mutable - // objects which you can then pass to CallMethod(). - // - // Example: - // const MethodDescriptor* method = - // service->GetDescriptor()->FindMethodByName("Foo"); - // Message* request = stub->GetRequestPrototype (method)->New(); - // Message* response = stub->GetResponsePrototype(method)->New(); - // request->ParseFromString(input); - // service->CallMethod(method, *request, response, callback); - virtual const Message& GetRequestPrototype( - const MethodDescriptor* method) const = 0; - virtual const Message& GetResponsePrototype( - const MethodDescriptor* method) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service); -}; - -// An RpcController mediates a single method call. The primary purpose of -// the controller is to provide a way to manipulate settings specific to the -// RPC implementation and to find out about RPC-level errors. -// -// The methods provided by the RpcController interface are intended to be a -// "least common denominator" set of features which we expect all -// implementations to support. Specific implementations may provide more -// advanced features (e.g. deadline propagation). -class LIBPROTOBUF_EXPORT RpcController { - public: - inline RpcController() {} - virtual ~RpcController(); - - // Client-side methods --------------------------------------------- - // These calls may be made from the client side only. Their results - // are undefined on the server side (may crash). - - // Resets the RpcController to its initial state so that it may be reused in - // a new call. Must not be called while an RPC is in progress. - virtual void Reset() = 0; - - // After a call has finished, returns true if the call failed. The possible - // reasons for failure depend on the RPC implementation. Failed() must not - // be called before a call has finished. If Failed() returns true, the - // contents of the response message are undefined. - virtual bool Failed() const = 0; - - // If Failed() is true, returns a human-readable description of the error. - virtual string ErrorText() const = 0; - - // Advises the RPC system that the caller desires that the RPC call be - // canceled. The RPC system may cancel it immediately, may wait awhile and - // then cancel it, or may not even cancel the call at all. If the call is - // canceled, the "done" callback will still be called and the RpcController - // will indicate that the call failed at that time. - virtual void StartCancel() = 0; - - // Server-side methods --------------------------------------------- - // These calls may be made from the server side only. Their results - // are undefined on the client side (may crash). - - // Causes Failed() to return true on the client side. "reason" will be - // incorporated into the message returned by ErrorText(). If you find - // you need to return machine-readable information about failures, you - // should incorporate it into your response protocol buffer and should - // NOT call SetFailed(). - virtual void SetFailed(const string& reason) = 0; - - // If true, indicates that the client canceled the RPC, so the server may - // as well give up on replying to it. The server should still call the - // final "done" callback. - virtual bool IsCanceled() const = 0; - - // Asks that the given callback be called when the RPC is canceled. The - // callback will always be called exactly once. If the RPC completes without - // being canceled, the callback will be called after completion. If the RPC - // has already been canceled when NotifyOnCancel() is called, the callback - // will be called immediately. - // - // NotifyOnCancel() must be called no more than once per request. - virtual void NotifyOnCancel(Closure* callback) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController); -}; - -// Abstract interface for an RPC channel. An RpcChannel represents a -// communication line to a Service which can be used to call that Service's -// methods. The Service may be running on another machine. Normally, you -// should not call an RpcChannel directly, but instead construct a stub Service -// wrapping it. Example: -// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); -// MyService* service = new MyService::Stub(channel); -// service->MyMethod(request, &response, callback); -class LIBPROTOBUF_EXPORT RpcChannel { - public: - inline RpcChannel() {} - virtual ~RpcChannel(); - - // Call the given method of the remote service. The signature of this - // procedure looks the same as Service::CallMethod(), but the requirements - // are less strict in one important way: the request and response objects - // need not be of any specific class as long as their descriptors are - // method->input_type() and method->output_type(). - virtual void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_SERVICE_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/common.cc b/Resources/NetHook/google/protobuf/stubs/common.cc deleted file mode 100644 index 1e2d68d2..00000000 --- a/Resources/NetHook/google/protobuf/stubs/common.cc +++ /dev/null @@ -1,365 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include -#include -#include -#include -#include - -#include "config.h" - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN // We only need minimal includes -#include -#define snprintf _snprintf // see comment in strutil.cc -#elif defined(HAVE_PTHREAD) -#include -#else -#error "No suitable threading library available." -#endif - -namespace google { -namespace protobuf { - -namespace internal { - -void VerifyVersion(int headerVersion, - int minLibraryVersion, - const char* filename) { - if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { - // Library is too old for headers. - GOOGLE_LOG(FATAL) - << "This program requires version " << VersionString(minLibraryVersion) - << " of the Protocol Buffer runtime library, but the installed version " - "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update " - "your library. If you compiled the program yourself, make sure that " - "your headers are from the same version of Protocol Buffers as your " - "link-time library. (Version verification failed in \"" - << filename << "\".)"; - } - if (headerVersion < kMinHeaderVersionForLibrary) { - // Headers are too old for library. - GOOGLE_LOG(FATAL) - << "This program was compiled against version " - << VersionString(headerVersion) << " of the Protocol Buffer runtime " - "library, which is not compatible with the installed version (" - << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program " - "author for an update. If you compiled the program yourself, make " - "sure that your headers are from the same version of Protocol Buffers " - "as your link-time library. (Version verification failed in \"" - << filename << "\".)"; - } -} - -string VersionString(int version) { - int major = version / 1000000; - int minor = (version / 1000) % 1000; - int micro = version % 1000; - - // 128 bytes should always be enough, but we use snprintf() anyway to be - // safe. - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro); - - // Guard against broken MSVC snprintf(). - buffer[sizeof(buffer)-1] = '\0'; - - return buffer; -} - -} // namespace internal - -// =================================================================== -// emulates google3/base/logging.cc - -namespace internal { - -void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { - static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; - - // We use fprintf() instead of cerr because we want this to work at static - // initialization time. - fprintf(stderr, "libprotobuf %s %s:%d] %s\n", - level_names[level], filename, line, message.c_str()); - fflush(stderr); // Needed on MSVC. -} - -void NullLogHandler(LogLevel level, const char* filename, int line, - const string& message) { - // Nothing. -} - -static LogHandler* log_handler_ = &DefaultLogHandler; -static int log_silencer_count_ = 0; - -static Mutex* log_silencer_count_mutex_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_); - -void DeleteLogSilencerCount() { - delete log_silencer_count_mutex_; - log_silencer_count_mutex_ = NULL; -} -void InitLogSilencerCount() { - log_silencer_count_mutex_ = new Mutex; - OnShutdown(&DeleteLogSilencerCount); -} -void InitLogSilencerCountOnce() { - GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount); -} - -LogMessage& LogMessage::operator<<(const string& value) { - message_ += value; - return *this; -} - -LogMessage& LogMessage::operator<<(const char* value) { - message_ += value; - return *this; -} - -// Since this is just for logging, we don't care if the current locale changes -// the results -- in fact, we probably prefer that. So we use snprintf() -// instead of Simple*toa(). -#undef DECLARE_STREAM_OPERATOR -#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \ - LogMessage& LogMessage::operator<<(TYPE value) { \ - /* 128 bytes should be big enough for any of the primitive */ \ - /* values which we print with this, but well use snprintf() */ \ - /* anyway to be extra safe. */ \ - char buffer[128]; \ - snprintf(buffer, sizeof(buffer), FORMAT, value); \ - /* Guard against broken MSVC snprintf(). */ \ - buffer[sizeof(buffer)-1] = '\0'; \ - message_ += buffer; \ - return *this; \ - } - -DECLARE_STREAM_OPERATOR(char , "%c" ) -DECLARE_STREAM_OPERATOR(int , "%d" ) -DECLARE_STREAM_OPERATOR(uint , "%u" ) -DECLARE_STREAM_OPERATOR(long , "%ld") -DECLARE_STREAM_OPERATOR(unsigned long, "%lu") -DECLARE_STREAM_OPERATOR(double , "%g" ) -#undef DECLARE_STREAM_OPERATOR - -LogMessage::LogMessage(LogLevel level, const char* filename, int line) - : level_(level), filename_(filename), line_(line) {} -LogMessage::~LogMessage() {} - -void LogMessage::Finish() { - bool suppress = false; - - if (level_ != LOGLEVEL_FATAL) { - InitLogSilencerCountOnce(); - MutexLock lock(log_silencer_count_mutex_); - suppress = internal::log_silencer_count_ > 0; - } - - if (!suppress) { - internal::log_handler_(level_, filename_, line_, message_); - } - - if (level_ == LOGLEVEL_FATAL) { - abort(); - } -} - -void LogFinisher::operator=(LogMessage& other) { - other.Finish(); -} - -} // namespace internal - -LogHandler* SetLogHandler(LogHandler* new_func) { - LogHandler* old = internal::log_handler_; - if (old == &internal::NullLogHandler) { - old = NULL; - } - if (new_func == NULL) { - internal::log_handler_ = &internal::NullLogHandler; - } else { - internal::log_handler_ = new_func; - } - return old; -} - -LogSilencer::LogSilencer() { - internal::InitLogSilencerCountOnce(); - MutexLock lock(internal::log_silencer_count_mutex_); - ++internal::log_silencer_count_; -}; - -LogSilencer::~LogSilencer() { - internal::InitLogSilencerCountOnce(); - MutexLock lock(internal::log_silencer_count_mutex_); - --internal::log_silencer_count_; -}; - -// =================================================================== -// emulates google3/base/callback.cc - -Closure::~Closure() {} - -namespace internal { FunctionClosure0::~FunctionClosure0() {} } - -void DoNothing() {} - -// =================================================================== -// emulates google3/base/mutex.cc - -#ifdef _WIN32 - -struct Mutex::Internal { - CRITICAL_SECTION mutex; -#ifndef NDEBUG - // Used only to implement AssertHeld(). - DWORD thread_id; -#endif -}; - -Mutex::Mutex() - : mInternal(new Internal) { - InitializeCriticalSection(&mInternal->mutex); -} - -Mutex::~Mutex() { - DeleteCriticalSection(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - EnterCriticalSection(&mInternal->mutex); -#ifndef NDEBUG - mInternal->thread_id = GetCurrentThreadId(); -#endif -} - -void Mutex::Unlock() { -#ifndef NDEBUG - mInternal->thread_id = 0; -#endif - LeaveCriticalSection(&mInternal->mutex); -} - -void Mutex::AssertHeld() { -#ifndef NDEBUG - GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); -#endif -} - -#elif defined(HAVE_PTHREAD) - -struct Mutex::Internal { - pthread_mutex_t mutex; -}; - -Mutex::Mutex() - : mInternal(new Internal) { - pthread_mutex_init(&mInternal->mutex, NULL); -} - -Mutex::~Mutex() { - pthread_mutex_destroy(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - int result = pthread_mutex_lock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); - } -} - -void Mutex::Unlock() { - int result = pthread_mutex_unlock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); - } -} - -void Mutex::AssertHeld() { - // pthreads dosn't provide a way to check which thread holds the mutex. - // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? -} - -#endif - -// =================================================================== -// Shutdown support. - -namespace internal { - -typedef void OnShutdownFunc(); -vector* shutdown_functions = NULL; -Mutex* shutdown_functions_mutex = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); - -void InitShutdownFunctions() { - shutdown_functions = new vector; - shutdown_functions_mutex = new Mutex; -} - -inline void InitShutdownFunctionsOnce() { - GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions); -} - -void OnShutdown(void (*func)()) { - InitShutdownFunctionsOnce(); - MutexLock lock(shutdown_functions_mutex); - shutdown_functions->push_back(func); -} - -} // namespace internal - -void ShutdownProtobufLibrary() { - internal::InitShutdownFunctionsOnce(); - - // We don't need to lock shutdown_functions_mutex because it's up to the - // caller to make sure that no one is using the library before this is - // called. - - // Make it safe to call this multiple times. - if (internal::shutdown_functions == NULL) return; - - for (int i = 0; i < internal::shutdown_functions->size(); i++) { - internal::shutdown_functions->at(i)(); - } - delete internal::shutdown_functions; - internal::shutdown_functions = NULL; - delete internal::shutdown_functions_mutex; - internal::shutdown_functions_mutex = NULL; -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/common.h b/Resources/NetHook/google/protobuf/stubs/common.h deleted file mode 100644 index 551ee4aa..00000000 --- a/Resources/NetHook/google/protobuf/stubs/common.h +++ /dev/null @@ -1,1155 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) and others -// -// Contains basic types and utilities used by the rest of the library. - -#ifndef GOOGLE_PROTOBUF_COMMON_H__ -#define GOOGLE_PROTOBUF_COMMON_H__ - -#include -#include -#include -#include -#include -#if defined(__osf__) -// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of -// what stdint.h would define. -#include -#elif !defined(_MSC_VER) -#include -#endif - -namespace std {} - -namespace google { -namespace protobuf { - -using namespace std; // Don't do this at home, kids. - -#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS -#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) - #ifdef LIBPROTOBUF_EXPORTS - #define LIBPROTOBUF_EXPORT __declspec(dllexport) - #else - #define LIBPROTOBUF_EXPORT __declspec(dllimport) - #endif - #ifdef LIBPROTOC_EXPORTS - #define LIBPROTOC_EXPORT __declspec(dllexport) - #else - #define LIBPROTOC_EXPORT __declspec(dllimport) - #endif -#else - #define LIBPROTOBUF_EXPORT - #define LIBPROTOC_EXPORT -#endif - -namespace internal { - -// Some of these constants are macros rather than const ints so that they can -// be used in #if directives. - -// The current version, represented as a single integer to make comparison -// easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2003000 - -// The minimum library version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2003000 - -// The minimum header version which works with the current version of -// the library. This constant should only be used by protoc's C++ code -// generator. -static const int kMinHeaderVersionForLibrary = 2003000; - -// The minimum protoc version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2003000 - -// The minimum header version which works with the current version of -// protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2003000; - -// Verifies that the headers and libraries are compatible. Use the macro -// below to call this. -void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, - const char* filename); - -// Converts a numeric version number to a string. -string LIBPROTOBUF_EXPORT VersionString(int version); - -} // namespace internal - -// Place this macro in your main() function (or somewhere before you attempt -// to use the protobuf library) to verify that the version you link against -// matches the headers you compiled against. If a version mismatch is -// detected, the process will abort. -#define GOOGLE_PROTOBUF_VERIFY_VERSION \ - ::google::protobuf::internal::VerifyVersion( \ - GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ - __FILE__) - -// =================================================================== -// from google3/base/port.h - -typedef unsigned int uint; - -#ifdef _MSC_VER -typedef __int8 int8; -typedef __int16 int16; -typedef __int32 int32; -typedef __int64 int64; - -typedef unsigned __int8 uint8; -typedef unsigned __int16 uint16; -typedef unsigned __int32 uint32; -typedef unsigned __int64 uint64; -#else -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; -#endif - -// long long macros to be used because gcc and vc++ use different suffixes, -// and different size specifiers in format strings -#undef GOOGLE_LONGLONG -#undef GOOGLE_ULONGLONG -#undef GOOGLE_LL_FORMAT - -#ifdef _MSC_VER -#define GOOGLE_LONGLONG(x) x##I64 -#define GOOGLE_ULONGLONG(x) x##UI64 -#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) -#else -#define GOOGLE_LONGLONG(x) x##LL -#define GOOGLE_ULONGLONG(x) x##ULL -#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. -#endif - -static const int32 kint32max = 0x7FFFFFFF; -static const int32 kint32min = -kint32max - 1; -static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); -static const int64 kint64min = -kint64max - 1; -static const uint32 kuint32max = 0xFFFFFFFFu; -static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); - -// ------------------------------------------------------------------- -// Annotations: Some parts of the code have been annotated in ways that might -// be useful to some compilers or tools, but are not supported universally. -// You can #define these annotations yourself if the default implementation -// is not right for you. - -#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -// For functions we want to force inline. -// Introduced in gcc 3.1. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) -#else -// Other compilers will have to figure it out for themselves. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#endif -#endif - -#ifndef GOOGLE_ATTRIBUTE_DEPRECATED -#ifdef __GNUC__ -// If the method/variable/type is used anywhere, produce a warning. -#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) -#else -#define GOOGLE_ATTRIBUTE_DEPRECATED -#endif -#endif - -#ifndef GOOGLE_PREDICT_TRUE -#ifdef __GNUC__ -// Provided at least since GCC 3.0. -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_TRUE -#endif -#endif - -// Delimits a block of code which may write to memory which is simultaneously -// written by other threads, but which has been determined to be thread-safe -// (e.g. because it is an idempotent write). -#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN -#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() -#endif -#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END -#define GOOGLE_SAFE_CONCURRENT_WRITES_END() -#endif - -// =================================================================== -// from google3/base/basictypes.h - -// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. -// The expression is a compile-time constant, and therefore can be -// used in defining new arrays, for example. -// -// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error -// -// "warning: division by zero in ..." -// -// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. -// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. -// -// The following comments are on the implementation details, and can -// be ignored by the users. -// -// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in -// the array) and sizeof(*(arr)) (the # of bytes in one array -// element). If the former is divisible by the latter, perhaps arr is -// indeed an array, in which case the division result is the # of -// elements in the array. Otherwise, arr cannot possibly be an array, -// and we generate a compiler error to prevent the code from -// compiling. -// -// Since the size of bool is implementation-defined, we need to cast -// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final -// result has type size_t. -// -// This macro is not perfect as it wrongfully accepts certain -// pointers, namely where the pointer size is divisible by the pointee -// size. Since all our code has to go through a 32-bit compiler, -// where a pointer is 4 bytes, this means all pointers to a type whose -// size is 3 or greater than 4 will be (righteously) rejected. -// -// Kudos to Jorg Brown for this simple and elegant implementation. - -#undef GOOGLE_ARRAYSIZE -#define GOOGLE_ARRAYSIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) - -namespace internal { - -// Use implicit_cast as a safe version of static_cast or const_cast -// for upcasting in the type hierarchy (i.e. casting a pointer to Foo -// to a pointer to SuperclassOfFoo or casting a pointer to Foo to -// a const pointer to Foo). -// When you use implicit_cast, the compiler checks that the cast is safe. -// Such explicit implicit_casts are necessary in surprisingly many -// situations where C++ demands an exact type match instead of an -// argument type convertable to a target type. -// -// The From type can be inferred, so the preferred syntax for using -// implicit_cast is the same as for static_cast etc.: -// -// implicit_cast(expr) -// -// implicit_cast would have been part of the C++ standard library, -// but the proposal was submitted too late. It will probably make -// its way into the language in the future. -template -inline To implicit_cast(From const &f) { - return f; -} - -// When you upcast (that is, cast a pointer from type Foo to type -// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts -// always succeed. When you downcast (that is, cast a pointer from -// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because -// how do you know the pointer is really of type SubclassOfFoo? It -// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, -// when you downcast, you should use this macro. In debug mode, we -// use dynamic_cast<> to double-check the downcast is legal (we die -// if it's not). In normal mode, we do the efficient static_cast<> -// instead. Thus, it's important to test in debug mode to make sure -// the cast is legal! -// This is the only place in the code we should use dynamic_cast<>. -// In particular, you SHOULDN'T be using dynamic_cast<> in order to -// do RTTI (eg code like this: -// if (dynamic_cast(foo)) HandleASubclass1Object(foo); -// if (dynamic_cast(foo)) HandleASubclass2Object(foo); -// You should design the code some other way not to need this. - -template // use like this: down_cast(foo); -inline To down_cast(From* f) { // so we only accept pointers - // Ensures that To is a sub-type of From *. This test is here only - // for compile-time type checking, and has no overhead in an - // optimized build at run-time, as it will be optimized away - // completely. - if (false) { - implicit_cast(0); - } - -#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) - assert(f == NULL || dynamic_cast(f) != NULL); // RTTI: debug mode only! -#endif - return static_cast(f); -} - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::implicit_cast; -using internal::down_cast; - -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -namespace internal { - -template -struct CompileAssert { -}; - -} // namespace internal - -#undef GOOGLE_COMPILE_ASSERT -#define GOOGLE_COMPILE_ASSERT(expr, msg) \ - typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \ - msg[bool(expr) ? 1 : -1] - -// Implementation details of COMPILE_ASSERT: -// -// - COMPILE_ASSERT works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert -// -// instead, these compilers will refuse to compile -// -// COMPILE_ASSERT(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// =================================================================== -// from google3/base/scoped_ptr.h - -namespace internal { - -// This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. - -template class scoped_ptr; -template class scoped_array; - -// A scoped_ptr is like a T*, except that the destructor of scoped_ptr -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr owns the T object that it points to. -// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. -// -// The size of a scoped_ptr is small: -// sizeof(scoped_ptr) == sizeof(C*) -template -class scoped_ptr { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to intializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = NULL) : ptr_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_ptr() { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != ptr_) { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - ptr_ = p; - } - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - C* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - C* get() const { return ptr_; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return ptr_ == p; } - bool operator!=(C* p) const { return ptr_ != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - C* tmp = ptr_; - ptr_ = p2.ptr_; - p2.ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = ptr_; - ptr_ = NULL; - return retVal; - } - - private: - C* ptr_; - - // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't - // make sense, and if C2 == C, it still doesn't make sense because you should - // never have the same object owned by two different scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; - - // Disallow evil constructors - scoped_ptr(const scoped_ptr&); - void operator=(const scoped_ptr&); -}; - -// scoped_array is like scoped_ptr, except that the caller must allocate -// with new [] and the destructor deletes objects with delete []. -// -// As with scoped_ptr, a scoped_array either points to an object -// or is NULL. A scoped_array owns the object that it points to. -// -// Size: sizeof(scoped_array) == sizeof(C*) -template -class scoped_array { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to intializing with NULL. - // There is no way to create an uninitialized scoped_array. - // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_array() { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != array_) { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - array_ = p; - } - } - - // Get one element of the current object. - // Will assert() if there is no current object, or index i is negative. - C& operator[](std::ptrdiff_t i) const { - assert(i >= 0); - assert(array_ != NULL); - return array_[i]; - } - - // Get a pointer to the zeroth element of the current object. - // If there is no current object, return NULL. - C* get() const { - return array_; - } - - // Comparison operators. - // These return whether two scoped_array refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return array_ == p; } - bool operator!=(C* p) const { return array_ != p; } - - // Swap two scoped arrays. - void swap(scoped_array& p2) { - C* tmp = array_; - array_ = p2.array_; - p2.array_ = tmp; - } - - // Release an array. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = array_; - array_ = NULL; - return retVal; - } - - private: - C* array_; - - // Forbid comparison of different scoped_array types. - template bool operator==(scoped_array const& p2) const; - template bool operator!=(scoped_array const& p2) const; - - // Disallow evil constructors - scoped_array(const scoped_array&); - void operator=(const scoped_array&); -}; - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::scoped_ptr; -using internal::scoped_array; - -// =================================================================== -// emulates google3/base/logging.h - -enum LogLevel { - LOGLEVEL_INFO, // Informational. This is never actually used by - // libprotobuf. - LOGLEVEL_WARNING, // Warns about issues that, although not technically a - // problem now, could cause problems in the future. For - // example, a // warning will be printed when parsing a - // message that is near the message size limit. - LOGLEVEL_ERROR, // An error occurred which should never happen during - // normal use. - LOGLEVEL_FATAL, // An error occurred from which the library cannot - // recover. This usually indicates a programming error - // in the code which calls the library, especially when - // compiled in debug mode. - -#ifdef NDEBUG - LOGLEVEL_DFATAL = LOGLEVEL_ERROR -#else - LOGLEVEL_DFATAL = LOGLEVEL_FATAL -#endif -}; - -namespace internal { - -class LogFinisher; - -class LIBPROTOBUF_EXPORT LogMessage { - public: - LogMessage(LogLevel level, const char* filename, int line); - ~LogMessage(); - - LogMessage& operator<<(const string& value); - LogMessage& operator<<(const char* value); - LogMessage& operator<<(char value); - LogMessage& operator<<(int value); - LogMessage& operator<<(uint value); - LogMessage& operator<<(long value); - LogMessage& operator<<(unsigned long value); - LogMessage& operator<<(double value); - - private: - friend class LogFinisher; - void Finish(); - - LogLevel level_; - const char* filename_; - int line_; - string message_; -}; - -// Used to make the entire "LOG(BLAH) << etc." expression have a void return -// type and print a newline after each message. -class LIBPROTOBUF_EXPORT LogFinisher { - public: - void operator=(LogMessage& other); -}; - -} // namespace internal - -// Undef everything in case we're being mixed with some other Google library -// which already defined them itself. Presumably all Google libraries will -// support the same syntax for these so it should not be a big deal if they -// end up using our definitions instead. -#undef GOOGLE_LOG -#undef GOOGLE_LOG_IF - -#undef GOOGLE_CHECK -#undef GOOGLE_CHECK_EQ -#undef GOOGLE_CHECK_NE -#undef GOOGLE_CHECK_LT -#undef GOOGLE_CHECK_LE -#undef GOOGLE_CHECK_GT -#undef GOOGLE_CHECK_GE - -#undef GOOGLE_DLOG -#undef GOOGLE_DCHECK -#undef GOOGLE_DCHECK_EQ -#undef GOOGLE_DCHECK_NE -#undef GOOGLE_DCHECK_LT -#undef GOOGLE_DCHECK_LE -#undef GOOGLE_DCHECK_GT -#undef GOOGLE_DCHECK_GE - -#define GOOGLE_LOG(LEVEL) \ - ::google::protobuf::internal::LogFinisher() = \ - ::google::protobuf::internal::LogMessage( \ - ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) -#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ - !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) - -#define GOOGLE_CHECK(EXPRESSION) \ - GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " -#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) -#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) -#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) -#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) -#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) -#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) - -#ifdef NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false) - -#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) -#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) -#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) -#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) -#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) -#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) -#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) - -#else // NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG - -#define GOOGLE_DCHECK GOOGLE_CHECK -#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ -#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE -#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT -#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE -#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT -#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE - -#endif // !NDEBUG - -typedef void LogHandler(LogLevel level, const char* filename, int line, - const string& message); - -// The protobuf library sometimes writes warning and error messages to -// stderr. These messages are primarily useful for developers, but may -// also help end users figure out a problem. If you would prefer that -// these messages be sent somewhere other than stderr, call SetLogHandler() -// to set your own handler. This returns the old handler. Set the handler -// to NULL to ignore log messages (but see also LogSilencer, below). -// -// Obviously, SetLogHandler is not thread-safe. You should only call it -// at initialization time, and probably not from library code. If you -// simply want to suppress log messages temporarily (e.g. because you -// have some code that tends to trigger them frequently and you know -// the warnings are not important to you), use the LogSilencer class -// below. -LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); - -// Create a LogSilencer if you want to temporarily suppress all log -// messages. As long as any LogSilencer objects exist, non-fatal -// log messages will be discarded (the current LogHandler will *not* -// be called). Constructing a LogSilencer is thread-safe. You may -// accidentally suppress log messages occurring in another thread, but -// since messages are generally for debugging purposes only, this isn't -// a big deal. If you want to intercept log messages, use SetLogHandler(). -class LIBPROTOBUF_EXPORT LogSilencer { - public: - LogSilencer(); - ~LogSilencer(); -}; - -// =================================================================== -// emulates google3/base/callback.h - -// Abstract interface for a callback. When calling an RPC, you must provide -// a Closure to call when the procedure completes. See the Service interface -// in service.h. -// -// To automatically construct a Closure which calls a particular function or -// method with a particular set of parameters, use the NewCallback() function. -// Example: -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(&FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// -// Example that calls a method: -// class Handler { -// public: -// ... -// -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(this, &Handler::FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// }; -// -// Currently NewCallback() supports binding zero, one, or two arguments. -// -// Callbacks created with NewCallback() automatically delete themselves when -// executed. They should be used when a callback is to be called exactly -// once (usually the case with RPC callbacks). If a callback may be called -// a different number of times (including zero), create it with -// NewPermanentCallback() instead. You are then responsible for deleting the -// callback (using the "delete" keyword as normal). -// -// Note that NewCallback() is a bit touchy regarding argument types. Generally, -// the values you provide for the parameter bindings must exactly match the -// types accepted by the callback function. For example: -// void Foo(string s); -// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS -// Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; -// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. -// However, correctly-typed pointers will work just fine. -class LIBPROTOBUF_EXPORT Closure { - public: - Closure() {} - virtual ~Closure(); - - virtual void Run() = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); -}; - -namespace internal { - -class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { - public: - typedef void (*FunctionType)(); - - FunctionClosure0(FunctionType function, bool self_deleting) - : function_(function), self_deleting_(self_deleting) {} - ~FunctionClosure0(); - - void Run() { - function_(); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; -}; - -template -class MethodClosure0 : public Closure { - public: - typedef void (Class::*MethodType)(); - - MethodClosure0(Class* object, MethodType method, bool self_deleting) - : object_(object), method_(method), self_deleting_(self_deleting) {} - ~MethodClosure0() {} - - void Run() { - (object_->*method_)(); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; -}; - -template -class FunctionClosure1 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1); - - FunctionClosure1(FunctionType function, bool self_deleting, - Arg1 arg1) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1) {} - ~FunctionClosure1() {} - - void Run() { - function_(arg1_); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; -}; - -template -class MethodClosure1 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1); - - MethodClosure1(Class* object, MethodType method, bool self_deleting, - Arg1 arg1) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1) {} - ~MethodClosure1() {} - - void Run() { - (object_->*method_)(arg1_); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; -}; - -template -class FunctionClosure2 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); - - FunctionClosure2(FunctionType function, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~FunctionClosure2() {} - - void Run() { - function_(arg1_, arg2_); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -template -class MethodClosure2 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); - - MethodClosure2(Class* object, MethodType method, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~MethodClosure2() {} - - void Run() { - (object_->*method_)(arg1_, arg2_); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -} // namespace internal - -// See Closure. -inline Closure* NewCallback(void (*function)()) { - return new internal::FunctionClosure0(function, true); -} - -// See Closure. -inline Closure* NewPermanentCallback(void (*function)()) { - return new internal::FunctionClosure0(function, false); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0(object, method, true); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0(object, method, false); -} - -// See Closure. -template -inline Closure* NewCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1(function, true, arg1); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1(function, false, arg1); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1(object, method, true, arg1); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1(object, method, false, arg1); -} - -// See Closure. -template -inline Closure* NewCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2( - function, true, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2( - function, false, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2( - object, method, true, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewPermanentCallback( - Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2( - object, method, false, arg1, arg2); -} - -// A function which does nothing. Useful for creating no-op callbacks, e.g.: -// Closure* nothing = NewCallback(&DoNothing); -void LIBPROTOBUF_EXPORT DoNothing(); - -// =================================================================== -// emulates google3/base/mutex.h - -namespace internal { - -// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T -// may hold a mutex at a given time. If T attempts to Lock() the same Mutex -// while holding it, T will deadlock. -class LIBPROTOBUF_EXPORT Mutex { - public: - // Create a Mutex that is not held by anybody. - Mutex(); - - // Destructor - ~Mutex(); - - // Block if necessary until this Mutex is free, then acquire it exclusively. - void Lock(); - - // Release this Mutex. Caller must hold it exclusively. - void Unlock(); - - // Crash if this Mutex is not held exclusively by this thread. - // May fail to crash when it should; will never crash when it should not. - void AssertHeld(); - - private: - struct Internal; - Internal* mInternal; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); -}; - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class LIBPROTOBUF_EXPORT MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } - ~MutexLock() { this->mu_->Unlock(); } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); -}; - -// TODO(kenton): Implement these? Hard to implement portably. -typedef MutexLock ReaderMutexLock; -typedef MutexLock WriterMutexLock; - -// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. -class LIBPROTOBUF_EXPORT MutexLockMaybe { - public: - explicit MutexLockMaybe(Mutex *mu) : - mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } - ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); -}; - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::Mutex; -using internal::MutexLock; -using internal::ReaderMutexLock; -using internal::WriterMutexLock; -using internal::MutexLockMaybe; - -// =================================================================== -// from google3/base/type_traits.h - -namespace internal { - -// Specified by TR1 [4.7.4] Pointer modifications. -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { - typedef T type; }; - -// =================================================================== - -// Checks if the buffer contains structurally-valid UTF-8. Implemented in -// structurally_valid.cc. -LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); - -} // namespace internal - -// =================================================================== -// Shutdown support. - -// Shut down the entire protocol buffers library, deleting all static-duration -// objects allocated by the library or by generated .pb.cc files. -// -// There are two reasons you might want to call this: -// * You use a draconian definition of "memory leak" in which you expect -// every single malloc() to have a corresponding free(), even for objects -// which live until program exit. -// * You are writing a dynamically-loaded library which needs to clean up -// after itself when the library is unloaded. -// -// It is safe to call this multiple times. However, it is not safe to use -// any other part of the protocol buffers library after -// ShutdownProtobufLibrary() has been called. -LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary(); - -namespace internal { - -// Register a function to be called when ShutdownProtocolBuffers() is called. -LIBPROTOBUF_EXPORT void OnShutdown(void (*func)()); - -} // namespace internal - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMMON_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/common_unittest.cc b/Resources/NetHook/google/protobuf/stubs/common_unittest.cc deleted file mode 100644 index 32c1d08e..00000000 --- a/Resources/NetHook/google/protobuf/stubs/common_unittest.cc +++ /dev/null @@ -1,345 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include -#include -#include -#include - -#include -#include - -#include "config.h" - -namespace google { -namespace protobuf { -namespace { - -// TODO(kenton): More tests. - -#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC - -TEST(VersionTest, VersionMatchesConfig) { - // Verify that the version string specified in config.h matches the one - // in common.h. The config.h version is a string which may have a suffix - // like "beta" or "rc1", so we remove that. - string version = PACKAGE_VERSION; - int pos = 0; - while (pos < version.size() && - (ascii_isdigit(version[pos]) || version[pos] == '.')) { - ++pos; - } - version.erase(pos); - - EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION)); -} - -#endif // PACKAGE_VERSION - -TEST(CommonTest, IntMinMaxConstants) { - // kint32min was declared incorrectly in the first release of protobufs. - // Ugh. - EXPECT_LT(kint32min, kint32max); - EXPECT_EQ(static_cast(kint32min), static_cast(kint32max) + 1); - EXPECT_LT(kint64min, kint64max); - EXPECT_EQ(static_cast(kint64min), static_cast(kint64max) + 1); - EXPECT_EQ(0, kuint32max + 1); - EXPECT_EQ(0, kuint64max + 1); -} - -vector captured_messages_; - -void CaptureLog(LogLevel level, const char* filename, int line, - const string& message) { - captured_messages_.push_back( - strings::Substitute("$0 $1:$2: $3", - implicit_cast(level), filename, line, message)); -} - -TEST(LoggingTest, DefaultLogging) { - CaptureTestStderr(); - int line = __LINE__; - GOOGLE_LOG(INFO ) << "A message."; - GOOGLE_LOG(WARNING) << "A warning."; - GOOGLE_LOG(ERROR ) << "An error."; - - string text = GetCapturedTestStderr(); - EXPECT_EQ( - "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n" - "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n" - "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n", - text); -} - -TEST(LoggingTest, NullLogging) { - LogHandler* old_handler = SetLogHandler(NULL); - - CaptureTestStderr(); - GOOGLE_LOG(INFO ) << "A message."; - GOOGLE_LOG(WARNING) << "A warning."; - GOOGLE_LOG(ERROR ) << "An error."; - - EXPECT_TRUE(SetLogHandler(old_handler) == NULL); - - string text = GetCapturedTestStderr(); - EXPECT_EQ("", text); -} - -TEST(LoggingTest, CaptureLogging) { - captured_messages_.clear(); - - LogHandler* old_handler = SetLogHandler(&CaptureLog); - - int start_line = __LINE__; - GOOGLE_LOG(ERROR) << "An error."; - GOOGLE_LOG(WARNING) << "A warning."; - - EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); - - ASSERT_EQ(2, captured_messages_.size()); - EXPECT_EQ( - "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.", - captured_messages_[0]); - EXPECT_EQ( - "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.", - captured_messages_[1]); -} - -TEST(LoggingTest, SilenceLogging) { - captured_messages_.clear(); - - LogHandler* old_handler = SetLogHandler(&CaptureLog); - - int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1"; - LogSilencer* silencer1 = new LogSilencer; - GOOGLE_LOG(INFO) << "Not visible."; - LogSilencer* silencer2 = new LogSilencer; - GOOGLE_LOG(INFO) << "Not visible."; - delete silencer1; - GOOGLE_LOG(INFO) << "Not visible."; - delete silencer2; - int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2"; - - EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); - - ASSERT_EQ(2, captured_messages_.size()); - EXPECT_EQ( - "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1", - captured_messages_[0]); - EXPECT_EQ( - "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2", - captured_messages_[1]); -} - -class ClosureTest : public testing::Test { - public: - void SetA123Method() { a_ = 123; } - static void SetA123Function() { current_instance_->a_ = 123; } - - void SetAMethod(int a) { a_ = a; } - void SetCMethod(string c) { c_ = c; } - - static void SetAFunction(int a) { current_instance_->a_ = a; } - static void SetCFunction(string c) { current_instance_->c_ = c; } - - void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } - static void SetABFunction(int a, const char* b) { - current_instance_->a_ = a; - current_instance_->b_ = b; - } - - virtual void SetUp() { - current_instance_ = this; - a_ = 0; - b_ = NULL; - c_.clear(); - } - - int a_; - const char* b_; - string c_; - - static ClosureTest* current_instance_; -}; - -ClosureTest* ClosureTest::current_instance_ = NULL; - -TEST_F(ClosureTest, TestClosureFunction0) { - Closure* closure = NewCallback(&SetA123Function); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); -} - -TEST_F(ClosureTest, TestClosureMethod0) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetA123Method); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); -} - -TEST_F(ClosureTest, TestClosureFunction1) { - Closure* closure = NewCallback(&SetAFunction, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); -} - -TEST_F(ClosureTest, TestClosureMethod1) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetAMethod, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); -} - -TEST_F(ClosureTest, TestClosureFunction1String) { - Closure* closure = NewCallback(&SetCFunction, string("test")); - EXPECT_NE("test", c_); - closure->Run(); - EXPECT_EQ("test", c_); -} - -TEST_F(ClosureTest, TestClosureMethod1String) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetCMethod, string("test")); - EXPECT_NE("test", c_); - closure->Run(); - EXPECT_EQ("test", c_); -} - -TEST_F(ClosureTest, TestClosureFunction2) { - const char* cstr = "hello"; - Closure* closure = NewCallback(&SetABFunction, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); -} - -TEST_F(ClosureTest, TestClosureMethod2) { - const char* cstr = "hello"; - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetABMethod, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); -} - -// Repeat all of the above with NewPermanentCallback() - -TEST_F(ClosureTest, TestPermanentClosureFunction0) { - Closure* closure = NewPermanentCallback(&SetA123Function); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(123, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod0) { - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetA123Method); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(123, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureFunction1) { - Closure* closure = NewPermanentCallback(&SetAFunction, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(456, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod1) { - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetAMethod, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(456, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureFunction2) { - const char* cstr = "hello"; - Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - a_ = 0; - b_ = NULL; - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod2) { - const char* cstr = "hello"; - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetABMethod, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - a_ = 0; - b_ = NULL; - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - delete closure; -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/hash.cc b/Resources/NetHook/google/protobuf/stubs/hash.cc deleted file mode 100644 index 9eaf4a1e..00000000 --- a/Resources/NetHook/google/protobuf/stubs/hash.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include - -namespace google { -namespace protobuf { - -// Nothing needed here right now. - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/hash.h b/Resources/NetHook/google/protobuf/stubs/hash.h deleted file mode 100644 index 822d6050..00000000 --- a/Resources/NetHook/google/protobuf/stubs/hash.h +++ /dev/null @@ -1,220 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// Deals with the fact that hash_map is not defined everywhere. - -#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ -#define GOOGLE_PROTOBUF_STUBS_HASH_H__ - -#include -#include -#include "config.h" - -#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET) -#include HASH_MAP_H -#include HASH_SET_H -#else -#define MISSING_HASH -#include -#include -#endif - -namespace google { -namespace protobuf { - -#ifdef MISSING_HASH - -// This system doesn't have hash_map or hash_set. Emulate them using map and -// set. - -// Make hash be the same as less. Note that everywhere where custom -// hash functions are defined in the protobuf code, they are also defined such -// that they can be used as "less" functions, which is required by MSVC anyway. -template -struct hash { - // Dummy, just to make derivative hash functions compile. - int operator()(const Key& key) { - GOOGLE_LOG(FATAL) << "Should never be called."; - return 0; - } - - inline bool operator()(const Key& a, const Key& b) const { - return a < b; - } -}; - -// Make sure char* is compared by value. -template <> -struct hash { - // Dummy, just to make derivative hash functions compile. - int operator()(const char* key) { - GOOGLE_LOG(FATAL) << "Should never be called."; - return 0; - } - - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -template , - typename EqualKey = int > -class hash_map : public std::map { -}; - -template , - typename EqualKey = int > -class hash_set : public std::set { -}; - -#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) - -template -struct hash : public HASH_NAMESPACE::hash_compare { -}; - -// MSVC's hash_compare hashes based on the string contents but -// compares based on the string pointer. WTF? -class CstringLess { - public: - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -template <> -struct hash - : public HASH_NAMESPACE::hash_compare { -}; - -template , - typename EqualKey = int > -class hash_map : public HASH_NAMESPACE::hash_map< - Key, Data, HashFcn> { -}; - -template , - typename EqualKey = int > -class hash_set : public HASH_NAMESPACE::hash_set< - Key, HashFcn> { -}; - -#else - -template -struct hash : public HASH_NAMESPACE::hash { -}; - -template -struct hash { - inline size_t operator()(const Key* key) const { - return reinterpret_cast(key); - } -}; - -// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So, -// we go ahead and provide our own implementation. -template <> -struct hash { - inline size_t operator()(const char* str) const { - size_t result = 0; - for (; *str != '\0'; str++) { - result = 5 * result + *str; - } - return result; - } -}; - -template , - typename EqualKey = std::equal_to > -class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS< - Key, Data, HashFcn, EqualKey> { -}; - -template , - typename EqualKey = std::equal_to > -class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS< - Key, HashFcn, EqualKey> { -}; - -#endif - -template <> -struct hash { - inline size_t operator()(const string& key) const { - return hash()(key.c_str()); - } - - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline size_t operator()(const string& a, const string& b) const { - return a < b; - } -}; - -template -struct hash > { - inline size_t operator()(const pair& key) const { - size_t first_hash = hash()(key.first); - size_t second_hash = hash()(key.second); - - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - return first_hash * ((1 << 16) - 1) + second_hash; - } - - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline size_t operator()(const pair& a, - const pair& b) const { - return a < b; - } -}; - -// Used by GCC/SGI STL only. (Why isn't this provided by the standard -// library? :( ) -struct streq { - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) == 0; - } -}; - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/map-util.h b/Resources/NetHook/google/protobuf/stubs/map-util.h deleted file mode 100644 index f5c9d6b6..00000000 --- a/Resources/NetHook/google/protobuf/stubs/map-util.h +++ /dev/null @@ -1,119 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// from google3/util/gtl/map-util.h -// Author: Anton Carver - -#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ -#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ - -#include - -namespace google { -namespace protobuf { - -// Perform a lookup in a map or hash_map. -// If the key is present in the map then the value associated with that -// key is returned, otherwise the value passed as a default is returned. -template -const typename Collection::value_type::second_type& -FindWithDefault(const Collection& collection, - const typename Collection::value_type::first_type& key, - const typename Collection::value_type::second_type& value) { - typename Collection::const_iterator it = collection.find(key); - if (it == collection.end()) { - return value; - } - return it->second; -} - -// Perform a lookup in a map or hash_map. -// If the key is present a const pointer to the associated value is returned, -// otherwise a NULL pointer is returned. -template -const typename Collection::value_type::second_type* -FindOrNull(const Collection& collection, - const typename Collection::value_type::first_type& key) { - typename Collection::const_iterator it = collection.find(key); - if (it == collection.end()) { - return 0; - } - return &it->second; -} - -// Perform a lookup in a map or hash_map whose values are pointers. -// If the key is present a const pointer to the associated value is returned, -// otherwise a NULL pointer is returned. -// This function does not distinguish between a missing key and a key mapped -// to a NULL value. -template -const typename Collection::value_type::second_type -FindPtrOrNull(const Collection& collection, - const typename Collection::value_type::first_type& key) { - typename Collection::const_iterator it = collection.find(key); - if (it == collection.end()) { - return 0; - } - return it->second; -} - -// Change the value associated with a particular key in a map or hash_map. -// If the key is not present in the map the key and value are inserted, -// otherwise the value is updated to be a copy of the value provided. -// True indicates that an insert took place, false indicates an update. -template -bool InsertOrUpdate(Collection * const collection, - const Key& key, const Value& value) { - pair ret = - collection->insert(typename Collection::value_type(key, value)); - if (!ret.second) { - // update - ret.first->second = value; - return false; - } - return true; -} - -// Insert a new key and value into a map or hash_map. -// If the key is not present in the map the key and value are -// inserted, otherwise nothing happens. True indicates that an insert -// took place, false indicates the key was already present. -template -bool InsertIfNotPresent(Collection * const collection, - const Key& key, const Value& value) { - pair ret = - collection->insert(typename Collection::value_type(key, value)); - return ret.second; -} - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/once.cc b/Resources/NetHook/google/protobuf/stubs/once.cc deleted file mode 100644 index 5b7af9ce..00000000 --- a/Resources/NetHook/google/protobuf/stubs/once.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// emulates google3/base/once.h -// -// This header is intended to be included only by internal .cc files and -// generated .pb.cc files. Users should not use this directly. - -#ifdef _WIN32 -#include -#endif - -#include - -namespace google { -namespace protobuf { - -#ifdef _WIN32 - -struct ProtobufOnceInternal { - ProtobufOnceInternal() { - InitializeCriticalSection(&critical_section); - } - ~ProtobufOnceInternal() { - DeleteCriticalSection(&critical_section); - } - CRITICAL_SECTION critical_section; -}; - -ProtobufOnceType::~ProtobufOnceType() -{ - delete internal_; - internal_ = NULL; -} - -ProtobufOnceType::ProtobufOnceType() { - // internal_ may be non-NULL if Init() was already called. - if (internal_ == NULL) internal_ = new ProtobufOnceInternal; -} - -void ProtobufOnceType::Init(void (*init_func)()) { - // internal_ may be NULL if we're still in dynamic initialization and the - // constructor has not been called yet. As mentioned in once.h, we assume - // that the program is still single-threaded at this time, and therefore it - // should be safe to initialize internal_ like so. - if (internal_ == NULL) internal_ = new ProtobufOnceInternal; - - EnterCriticalSection(&internal_->critical_section); - if (!initialized_) { - init_func(); - initialized_ = true; - } - LeaveCriticalSection(&internal_->critical_section); -} - -#endif - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/once.h b/Resources/NetHook/google/protobuf/stubs/once.h deleted file mode 100644 index 0dee4076..00000000 --- a/Resources/NetHook/google/protobuf/stubs/once.h +++ /dev/null @@ -1,123 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// emulates google3/base/once.h -// -// This header is intended to be included only by internal .cc files and -// generated .pb.cc files. Users should not use this directly. -// -// This is basically a portable version of pthread_once(). -// -// This header declares three things: -// * A type called ProtobufOnceType. -// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type -// ProtobufOnceType. This is the only legal way to declare such a variable. -// The macro may only be used at the global scope (you cannot create local -// or class member variables of this type). -// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()). -// This function, when invoked multiple times given the same ProtobufOnceType -// object, will invoke init_func on the first call only, and will make sure -// none of the calls return before that first call to init_func has finished. -// -// This implements a way to perform lazy initialization. It's more efficient -// than using mutexes as no lock is needed if initialization has already -// happened. -// -// Example usage: -// void Init(); -// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init); -// -// // Calls Init() exactly once. -// void InitOnce() { -// GoogleOnceInit(&once_init, &Init); -// } -// -// Note that if GoogleOnceInit() is called before main() has begun, it must -// only be called by the thread that will eventually call main() -- that is, -// the thread that performs dynamic initialization. In general this is a safe -// assumption since people don't usually construct threads before main() starts, -// but it is technically not guaranteed. Unfortunately, Win32 provides no way -// whatsoever to statically-initialize its synchronization primitives, so our -// only choice is to assume that dynamic initialization is single-threaded. - -#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ -#define GOOGLE_PROTOBUF_STUBS_ONCE_H__ - -#include - -#ifndef _WIN32 -#include -#endif - -namespace google { -namespace protobuf { - -#ifdef _WIN32 - -struct ProtobufOnceInternal; - -struct LIBPROTOBUF_EXPORT ProtobufOnceType { - ProtobufOnceType(); - ~ProtobufOnceType(); - void Init(void (*init_func)()); - - volatile bool initialized_; - ProtobufOnceInternal* internal_; -}; - -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - ::google::protobuf::ProtobufOnceType NAME - -inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - // Note: Double-checked locking is safe on x86. - if (!once->initialized_) { - once->Init(init_func); - } -} - -#else - -typedef pthread_once_t ProtobufOnceType; - -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - pthread_once_t NAME = PTHREAD_ONCE_INIT - -inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - pthread_once(once, init_func); -} - -#endif - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/once_unittest.cc b/Resources/NetHook/google/protobuf/stubs/once_unittest.cc deleted file mode 100644 index b8f86a0f..00000000 --- a/Resources/NetHook/google/protobuf/stubs/once_unittest.cc +++ /dev/null @@ -1,253 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace { - -class OnceInitTest : public testing::Test { - protected: - void SetUp() { - state_ = INIT_NOT_STARTED; - current_test_ = this; - } - - // Since ProtobufOnceType is only allowed to be allocated in static storage, - // each test must use a different pair of ProtobufOnceType objects which it - // must declare itself. - void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) { - once_ = once; - recursive_once_ = recursive_once; - } - - void InitOnce() { - GoogleOnceInit(once_, &InitStatic); - } - void InitRecursiveOnce() { - GoogleOnceInit(recursive_once_, &InitRecursiveStatic); - } - - void BlockInit() { init_blocker_.Lock(); } - void UnblockInit() { init_blocker_.Unlock(); } - - class TestThread { - public: - TestThread(Closure* callback) - : done_(false), joined_(false), callback_(callback) { -#ifdef _WIN32 - thread_ = CreateThread(NULL, 0, &Start, this, 0, NULL); -#else - pthread_create(&thread_, NULL, &Start, this); -#endif - } - ~TestThread() { - if (!joined_) Join(); - } - - bool IsDone() { - MutexLock lock(&done_mutex_); - return done_; - } - void Join() { - joined_ = true; -#ifdef _WIN32 - WaitForSingleObject(thread_, INFINITE); - CloseHandle(thread_); -#else - pthread_join(thread_, NULL); -#endif - } - - private: -#ifdef _WIN32 - HANDLE thread_; -#else - pthread_t thread_; -#endif - - Mutex done_mutex_; - bool done_; - bool joined_; - Closure* callback_; - -#ifdef _WIN32 - static DWORD WINAPI Start(LPVOID arg) { -#else - static void* Start(void* arg) { -#endif - reinterpret_cast(arg)->Run(); - return 0; - } - - void Run() { - callback_->Run(); - MutexLock lock(&done_mutex_); - done_ = true; - } - }; - - TestThread* RunInitOnceInNewThread() { - return new TestThread(NewCallback(this, &OnceInitTest::InitOnce)); - } - TestThread* RunInitRecursiveOnceInNewThread() { - return new TestThread(NewCallback(this, &OnceInitTest::InitRecursiveOnce)); - } - - enum State { - INIT_NOT_STARTED, - INIT_STARTED, - INIT_DONE - }; - State CurrentState() { - MutexLock lock(&mutex_); - return state_; - } - - void WaitABit() { -#ifdef _WIN32 - Sleep(1000); -#else - sleep(1); -#endif - } - - private: - Mutex mutex_; - Mutex init_blocker_; - State state_; - ProtobufOnceType* once_; - ProtobufOnceType* recursive_once_; - - void Init() { - MutexLock lock(&mutex_); - EXPECT_EQ(INIT_NOT_STARTED, state_); - state_ = INIT_STARTED; - mutex_.Unlock(); - init_blocker_.Lock(); - init_blocker_.Unlock(); - mutex_.Lock(); - state_ = INIT_DONE; - } - - static OnceInitTest* current_test_; - static void InitStatic() { current_test_->Init(); } - static void InitRecursiveStatic() { current_test_->InitOnce(); } -}; - -OnceInitTest* OnceInitTest::current_test_ = NULL; - -GOOGLE_PROTOBUF_DECLARE_ONCE(simple_once); - -TEST_F(OnceInitTest, Simple) { - SetOnces(&simple_once, NULL); - - EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); - InitOnce(); - EXPECT_EQ(INIT_DONE, CurrentState()); - - // Calling again has no effect. - InitOnce(); - EXPECT_EQ(INIT_DONE, CurrentState()); -} - -GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once1); -GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once2); - -TEST_F(OnceInitTest, Recursive) { - SetOnces(&recursive_once1, &recursive_once2); - - EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); - InitRecursiveOnce(); - EXPECT_EQ(INIT_DONE, CurrentState()); -} - -GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_once); - -TEST_F(OnceInitTest, MultipleThreads) { - SetOnces(&multiple_threads_once, NULL); - - scoped_ptr threads[4]; - EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); - for (int i = 0; i < 4; i++) { - threads[i].reset(RunInitOnceInNewThread()); - } - for (int i = 0; i < 4; i++) { - threads[i]->Join(); - } - EXPECT_EQ(INIT_DONE, CurrentState()); -} - -GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once1); -GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once2); - -TEST_F(OnceInitTest, MultipleThreadsBlocked) { - SetOnces(&multiple_threads_blocked_once1, &multiple_threads_blocked_once2); - - scoped_ptr threads[8]; - EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); - - BlockInit(); - for (int i = 0; i < 4; i++) { - threads[i].reset(RunInitOnceInNewThread()); - } - for (int i = 4; i < 8; i++) { - threads[i].reset(RunInitRecursiveOnceInNewThread()); - } - - WaitABit(); - - // We should now have one thread blocked inside Init(), four blocked waiting - // for Init() to complete, and three blocked waiting for InitRecursive() to - // complete. - EXPECT_EQ(INIT_STARTED, CurrentState()); - UnblockInit(); - - for (int i = 0; i < 8; i++) { - threads[i]->Join(); - } - EXPECT_EQ(INIT_DONE, CurrentState()); -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/stl_util-inl.h b/Resources/NetHook/google/protobuf/stubs/stl_util-inl.h deleted file mode 100644 index a2e671bb..00000000 --- a/Resources/NetHook/google/protobuf/stubs/stl_util-inl.h +++ /dev/null @@ -1,121 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// from google3/util/gtl/stl_util-inl.h - -#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ -#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ - -#include - -namespace google { -namespace protobuf { - -// STLDeleteContainerPointers() -// For a range within a container of pointers, calls delete -// (non-array version) on these pointers. -// NOTE: for these three functions, we could just implement a DeleteObject -// functor and then call for_each() on the range and functor, but this -// requires us to pull in all of algorithm.h, which seems expensive. -// For hash_[multi]set, it is important that this deletes behind the iterator -// because the hash_set may call the hash function on the iterator when it is -// advanced, which could result in the hash function trying to deference a -// stale pointer. -template -void STLDeleteContainerPointers(ForwardIterator begin, - ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete *temp; - } -} - -// Inside Google, this function implements a horrible, disgusting hack in which -// we reach into the string's private implementation and resize it without -// initializing the new bytes. In some cases doing this can significantly -// improve performance. However, since it's totally non-portable it has no -// place in open source code. Feel free to fill this function in with your -// own disgusting hack if you want the perf boost. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { - s->resize(new_size); -} - -// Return a mutable char* pointing to a string's internal buffer, -// which may not be null-terminated. Writing through this pointer will -// modify the string. -// -// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the -// next call to a string method that invalidates iterators. -// -// As of 2006-04, there is no standard-blessed way of getting a -// mutable reference to a string's internal buffer. However, issue 530 -// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) -// proposes this as the method. According to Matt Austern, this should -// already work on all current implementations. -inline char* string_as_array(string* str) { - // DO NOT USE const_cast(str->data())! See the unittest for why. - return str->empty() ? NULL : &*str->begin(); -} - -// STLDeleteElements() deletes all the elements in an STL container and clears -// the container. This function is suitable for use with a vector, set, -// hash_set, or any other STL container which defines sensible begin(), end(), -// and clear() methods. -// -// If container is NULL, this function is a no-op. -// -// As an alternative to calling STLDeleteElements() directly, consider -// ElementDeleter (defined below), which ensures that your container's elements -// are deleted when the ElementDeleter goes out of scope. -template -void STLDeleteElements(T *container) { - if (!container) return; - STLDeleteContainerPointers(container->begin(), container->end()); - container->clear(); -} - -// Given an STL container consisting of (key, value) pairs, STLDeleteValues -// deletes all the "value" components and clears the container. Does nothing -// in the case it's given a NULL pointer. - -template -void STLDeleteValues(T *v) { - if (!v) return; - for (typename T::iterator i = v->begin(); i != v->end(); ++i) { - delete i->second; - } - v->clear(); -} - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ diff --git a/Resources/NetHook/google/protobuf/stubs/structurally_valid.cc b/Resources/NetHook/google/protobuf/stubs/structurally_valid.cc deleted file mode 100644 index 0f6afe6d..00000000 --- a/Resources/NetHook/google/protobuf/stubs/structurally_valid.cc +++ /dev/null @@ -1,536 +0,0 @@ -// Copyright 2005-2008 Google Inc. All Rights Reserved. -// Author: jrm@google.com (Jim Meehan) - -#include - -namespace google { -namespace protobuf { -namespace internal { - -// These four-byte entries compactly encode how many bytes 0..255 to delete -// in making a string replacement, how many bytes to add 0..255, and the offset -// 0..64k-1 of the replacement string in remap_string. -struct RemapEntry { - uint8 delete_bytes; - uint8 add_bytes; - uint16 bytes_offset; -}; - -// Exit type codes for state tables. All but the first get stuffed into -// signed one-byte entries. The first is only generated by executable code. -// To distinguish from next-state entries, these must be contiguous and -// all <= kExitNone -typedef enum { - kExitDstSpaceFull = 239, - kExitIllegalStructure, // 240 - kExitOK, // 241 - kExitReject, // ... - kExitReplace1, - kExitReplace2, - kExitReplace3, - kExitReplace21, - kExitReplace31, - kExitReplace32, - kExitReplaceOffset1, - kExitReplaceOffset2, - kExitReplace1S0, - kExitSpecial, - kExitDoAgain, - kExitRejectAlt, - kExitNone // 255 -} ExitReason; - - -// This struct represents one entire state table. The three initialized byte -// areas are state_table, remap_base, and remap_string. state0 and state0_size -// give the byte offset and length within state_table of the initial state -- -// table lookups are expected to start and end in this state, but for -// truncated UTF-8 strings, may end in a different state. These allow a quick -// test for that condition. entry_shift is 8 for tables subscripted by a full -// byte value and 6 for space-optimized tables subscripted by only six -// significant bits in UTF-8 continuation bytes. -typedef struct { - const uint32 state0; - const uint32 state0_size; - const uint32 total_size; - const int max_expand; - const int entry_shift; - const int bytes_per_entry; - const uint32 losub; - const uint32 hiadd; - const uint8* state_table; - const RemapEntry* remap_base; - const uint8* remap_string; - const uint8* fast_state; -} UTF8StateMachineObj; - -typedef UTF8StateMachineObj UTF8ScanObj; - -#define X__ (kExitIllegalStructure) -#define RJ_ (kExitReject) -#define S1_ (kExitReplace1) -#define S2_ (kExitReplace2) -#define S3_ (kExitReplace3) -#define S21 (kExitReplace21) -#define S31 (kExitReplace31) -#define S32 (kExitReplace32) -#define T1_ (kExitReplaceOffset1) -#define T2_ (kExitReplaceOffset2) -#define S11 (kExitReplace1S0) -#define SP_ (kExitSpecial) -#define D__ (kExitDoAgain) -#define RJA (kExitRejectAlt) - -// Entire table has 9 state blocks of 256 entries each -static const unsigned int utf8acceptnonsurrogates_STATE0 = 0; // state[0] -static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256; // =[1] -static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304; -static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0; -static const unsigned int utf8acceptnonsurrogates_SHIFT = 8; -static const unsigned int utf8acceptnonsurrogates_BYTES = 1; -static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020; -static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000; - -static const uint8 utf8acceptnonsurrogates[] = { -// state[0] 0x000000 Byte 1 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3, - 4, 5, 5, 5, 6, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[1] 0x000080 Byte 2 of 2 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[2] 0x000000 Byte 2 of 3 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[3] 0x001000 Byte 2 of 3 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[4] 0x000000 Byte 2 of 4 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[5] 0x040000 Byte 2 of 4 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[6] 0x100000 Byte 2 of 4 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[7] 0x00d000 Byte 2 of 3 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -// state[8] 0x00d800 Byte 3 of 3 -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, - -RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, -RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, -RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, -RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, - -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, -}; - -// Remap base[0] = (del, add, string_offset) -static const RemapEntry utf8acceptnonsurrogates_remap_base[] = { -{0, 0, 0} }; - -// Remap string[0] -static const unsigned char utf8acceptnonsurrogates_remap_string[] = { -0 }; - -static const unsigned char utf8acceptnonsurrogates_fast[256] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const UTF8ScanObj utf8acceptnonsurrogates_obj = { - utf8acceptnonsurrogates_STATE0, - utf8acceptnonsurrogates_STATE0_SIZE, - utf8acceptnonsurrogates_TOTAL_SIZE, - utf8acceptnonsurrogates_MAX_EXPAND_X4, - utf8acceptnonsurrogates_SHIFT, - utf8acceptnonsurrogates_BYTES, - utf8acceptnonsurrogates_LOSUB, - utf8acceptnonsurrogates_HIADD, - utf8acceptnonsurrogates, - utf8acceptnonsurrogates_remap_base, - utf8acceptnonsurrogates_remap_string, - utf8acceptnonsurrogates_fast -}; - - -#undef X__ -#undef RJ_ -#undef S1_ -#undef S2_ -#undef S3_ -#undef S21 -#undef S31 -#undef S32 -#undef T1_ -#undef T2_ -#undef S11 -#undef SP_ -#undef D__ -#undef RJA - -// Return true if current Tbl pointer is within state0 range -// Note that unsigned compare checks both ends of range simultaneously -static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) { - const uint8* Tbl0 = &st->state_table[st->state0]; - return (static_cast(Tbl - Tbl0) < st->state0_size); -} - -// Scan a UTF-8 string based on state table. -// Always scan complete UTF-8 characters -// Set number of bytes scanned. Return reason for exiting -int UTF8GenericScan(const UTF8ScanObj* st, - const char * str, - int str_length, - int* bytes_consumed) { - *bytes_consumed = 0; - if (str_length == 0) return kExitOK; - - int eshift = st->entry_shift; - const uint8* isrc = reinterpret_cast(str); - const uint8* src = isrc; - const uint8* srclimit = isrc + str_length; - const uint8* srclimit8 = srclimit - 7; - const uint8* Tbl_0 = &st->state_table[st->state0]; - - DoAgain: - // Do state-table scan - int e = 0; - uint8 c; - const uint8* Tbl2 = &st->fast_state[0]; - const uint32 losub = st->losub; - const uint32 hiadd = st->hiadd; - // Check initial few bytes one at a time until 8-byte aligned - //---------------------------- - while ((((uintptr_t)src & 0x07) != 0) && - (src < srclimit) && - Tbl2[src[0]] == 0) { - src++; - } - if (((uintptr_t)src & 0x07) == 0) { - // Do fast for groups of 8 identity bytes. - // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop, - // including slowing slightly on cr/lf/ht - //---------------------------- - while (src < srclimit8) { - uint32 s0123 = (reinterpret_cast(src))[0]; - uint32 s4567 = (reinterpret_cast(src))[1]; - src += 8; - // This is a fast range check for all bytes in [lowsub..0x80-hiadd) - uint32 temp = (s0123 - losub) | (s0123 + hiadd) | - (s4567 - losub) | (s4567 + hiadd); - if ((temp & 0x80808080) != 0) { - // We typically end up here on cr/lf/ht; src was incremented - int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) | - (Tbl2[src[-6]] | Tbl2[src[-5]]); - if (e0123 != 0) { - src -= 8; - break; - } // Exit on Non-interchange - e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) | - (Tbl2[src[-2]] | Tbl2[src[-1]]); - if (e0123 != 0) { - src -= 4; - break; - } // Exit on Non-interchange - // Else OK, go around again - } - } - } - //---------------------------- - - // Byte-at-a-time scan - //---------------------------- - const uint8* Tbl = Tbl_0; - while (src < srclimit) { - c = *src; - e = Tbl[c]; - src++; - if (e >= kExitIllegalStructure) {break;} - Tbl = &Tbl_0[e << eshift]; - } - //---------------------------- - - - // Exit posibilities: - // Some exit code, !state0, back up over last char - // Some exit code, state0, back up one byte exactly - // source consumed, !state0, back up over partial char - // source consumed, state0, exit OK - // For illegal byte in state0, avoid backup up over PREVIOUS char - // For truncated last char, back up to beginning of it - - if (e >= kExitIllegalStructure) { - // Back up over exactly one byte of rejected/illegal UTF-8 character - src--; - // Back up more if needed - if (!InStateZero(st, Tbl)) { - do { - src--; - } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); - } - } else if (!InStateZero(st, Tbl)) { - // Back up over truncated UTF-8 character - e = kExitIllegalStructure; - do { - src--; - } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); - } else { - // Normal termination, source fully consumed - e = kExitOK; - } - - if (e == kExitDoAgain) { - // Loop back up to the fast scan - goto DoAgain; - } - - *bytes_consumed = src - isrc; - return e; -} - -int UTF8GenericScanFastAscii(const UTF8ScanObj* st, - const char * str, - int str_length, - int* bytes_consumed) { - *bytes_consumed = 0; - if (str_length == 0) return kExitOK; - - const uint8* isrc = reinterpret_cast(str); - const uint8* src = isrc; - const uint8* srclimit = isrc + str_length; - const uint8* srclimit8 = srclimit - 7; - int n; - int rest_consumed; - int exit_reason; - do { - // Check initial few bytes one at a time until 8-byte aligned - while ((((uintptr_t)src & 0x07) != 0) && - (src < srclimit) && (src[0] < 0x80)) { - src++; - } - if (((uintptr_t)src & 0x07) == 0) { - while ((src < srclimit8) && - (((reinterpret_cast(src)[0] | - reinterpret_cast(src)[1]) & 0x80808080) == 0)) { - src += 8; - } - } - while ((src < srclimit) && (src[0] < 0x80)) { - src++; - } - // Run state table on the rest - n = src - isrc; - exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed); - src += rest_consumed; - } while ( exit_reason == kExitDoAgain ); - - *bytes_consumed = src - isrc; - return exit_reason; -} - -// Hack: On some compilers the static tables are initialized at startup. -// We can't use them until they are initialized. However, some Protocol -// Buffer parsing happens at static init time and may try to validate -// UTF-8 strings. Since UTF-8 validation is only used for debugging -// anyway, we simply always return success if initialization hasn't -// occurred yet. -namespace { - -bool module_initialized_ = false; - -struct InitDetector { - InitDetector() { - module_initialized_ = true; - } -}; -InitDetector init_detector; - -} // namespace - -bool IsStructurallyValidUTF8(const char* buf, int len) { - if (!module_initialized_) return true; - - int bytes_consumed = 0; - UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj, - buf, len, &bytes_consumed); - return (bytes_consumed == len); -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/structurally_valid_unittest.cc b/Resources/NetHook/google/protobuf/stubs/structurally_valid_unittest.cc deleted file mode 100644 index 90888885..00000000 --- a/Resources/NetHook/google/protobuf/stubs/structurally_valid_unittest.cc +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. -// Author: xpeng@google.com (Peter Peng) - -#include -#include - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -TEST(StructurallyValidTest, ValidUTF8String) { - // On GCC, this string can be written as: - // "abcd 1234 - \u2014\u2013\u2212" - // MSVC seems to interpret \u differently. - string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); - EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), - valid_str.size())); - // Additional check for pointer alignment - for (int i = 1; i < 8; ++i) { - EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i, - valid_str.size() - i)); - } -} - -TEST(StructurallyValidTest, InvalidUTF8String) { - const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); - EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), - invalid_str.size())); - // Additional check for pointer alignment - for (int i = 1; i < 8; ++i) { - EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i, - invalid_str.size() - i)); - } -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/strutil.cc b/Resources/NetHook/google/protobuf/stubs/strutil.cc deleted file mode 100644 index bb658ba8..00000000 --- a/Resources/NetHook/google/protobuf/stubs/strutil.cc +++ /dev/null @@ -1,1166 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// from google3/strings/strutil.cc - -#include -#include -#include // FLT_DIG and DBL_DIG -#include -#include -#include -#include - -#ifdef _WIN32 -// MSVC has only _snprintf, not snprintf. -// -// MinGW has both snprintf and _snprintf, but they appear to be different -// functions. The former is buggy. When invoked like so: -// char buffer[32]; -// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f); -// it prints "1.23000e+10". This is plainly wrong: %g should never print -// trailing zeros after the decimal point. For some reason this bug only -// occurs with some input values, not all. In any case, _snprintf does the -// right thing, so we use it. -#define snprintf _snprintf -#endif - -namespace google { -namespace protobuf { - -inline bool IsNaN(double value) { - // NaN is never equal to anything, even itself. - return value != value; -} - -// These are defined as macros on some platforms. #undef them so that we can -// redefine them. -#undef isxdigit -#undef isprint - -// The definitions of these in ctype.h change based on locale. Since our -// string manipulation is all in relation to the protocol buffer and C++ -// languages, we always want to use the C locale. So, we re-define these -// exactly as we want them. -inline bool isxdigit(char c) { - return ('0' <= c && c <= '9') || - ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F'); -} - -inline bool isprint(char c) { - return c >= 0x20 && c <= 0x7E; -} - -// ---------------------------------------------------------------------- -// StripString -// Replaces any occurrence of the character 'remove' (or the characters -// in 'remove') with the character 'replacewith'. -// ---------------------------------------------------------------------- -void StripString(string* s, const char* remove, char replacewith) { - const char * str_start = s->c_str(); - const char * str = str_start; - for (str = strpbrk(str, remove); - str != NULL; - str = strpbrk(str + 1, remove)) { - (*s)[str - str_start] = replacewith; - } -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Replace the "old" pattern with the "new" pattern in a string, -// and append the result to "res". If replace_all is false, -// it only replaces the first instance of "old." -// ---------------------------------------------------------------------- - -void StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all, - string* res) { - if (oldsub.empty()) { - res->append(s); // if empty, append the given string. - return; - } - - string::size_type start_pos = 0; - string::size_type pos; - do { - pos = s.find(oldsub, start_pos); - if (pos == string::npos) { - break; - } - res->append(s, start_pos, pos - start_pos); - res->append(newsub); - start_pos = pos + oldsub.size(); // start searching again after the "old" - } while (replace_all); - res->append(s, start_pos, s.length() - start_pos); -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Give me a string and two patterns "old" and "new", and I replace -// the first instance of "old" in the string with "new", if it -// exists. If "global" is true; call this repeatedly until it -// fails. RETURN a new string, regardless of whether the replacement -// happened or not. -// ---------------------------------------------------------------------- - -string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all) { - string ret; - StringReplace(s, oldsub, newsub, replace_all, &ret); - return ret; -} - -// ---------------------------------------------------------------------- -// SplitStringUsing() -// Split a string using a character delimiter. Append the components -// to 'result'. -// -// Note: For multi-character delimiters, this routine will split on *ANY* of -// the characters in the string, not the entire string as a single delimiter. -// ---------------------------------------------------------------------- -template -static inline -void SplitStringToIteratorUsing(const string& full, - const char* delim, - ITR& result) { - // Optimize the common case where delim is a single character. - if (delim[0] != '\0' && delim[1] == '\0') { - char c = delim[0]; - const char* p = full.data(); - const char* end = p + full.size(); - while (p != end) { - if (*p == c) { - ++p; - } else { - const char* start = p; - while (++p != end && *p != c); - *result++ = string(start, p - start); - } - } - return; - } - - string::size_type begin_index, end_index; - begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { - end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); - return; - } - *result++ = full.substr(begin_index, (end_index - begin_index)); - begin_index = full.find_first_not_of(delim, end_index); - } -} - -void SplitStringUsing(const string& full, - const char* delim, - vector* result) { - back_insert_iterator< vector > it(*result); - SplitStringToIteratorUsing(full, delim, it); -} - -// ---------------------------------------------------------------------- -// JoinStrings() -// This merges a vector of string components with delim inserted -// as separaters between components. -// -// ---------------------------------------------------------------------- -template -static void JoinStringsIterator(const ITERATOR& start, - const ITERATOR& end, - const char* delim, - string* result) { - GOOGLE_CHECK(result != NULL); - result->clear(); - int delim_length = strlen(delim); - - // Precompute resulting length so we can reserve() memory in one shot. - int length = 0; - for (ITERATOR iter = start; iter != end; ++iter) { - if (iter != start) { - length += delim_length; - } - length += iter->size(); - } - result->reserve(length); - - // Now combine everything. - for (ITERATOR iter = start; iter != end; ++iter) { - if (iter != start) { - result->append(delim, delim_length); - } - result->append(iter->data(), iter->size()); - } -} - -void JoinStrings(const vector& components, - const char* delim, - string * result) { - JoinStringsIterator(components.begin(), components.end(), delim, result); -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeSequences() -// This does all the unescaping that C does: \ooo, \r, \n, etc -// Returns length of resulting string. -// The implementation of \x parses any positive number of hex digits, -// but it is an error if the value requires more than 8 bits, and the -// result is truncated to 8 bits. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// ---------------------------------------------------------------------- - -#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7')) - -inline int hex_digit_to_int(char c) { - /* Assume ASCII. */ - assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61); - assert(isxdigit(c)); - int x = static_cast(c); - if (x > '9') { - x += 9; - } - return x & 0xf; -} - -// Protocol buffers doesn't ever care about errors, but I don't want to remove -// the code. -#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false) - -int UnescapeCEscapeSequences(const char* source, char* dest) { - return UnescapeCEscapeSequences(source, dest, NULL); -} - -int UnescapeCEscapeSequences(const char* source, char* dest, - vector *errors) { - GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented."; - - char* d = dest; - const char* p = source; - - // Small optimization for case where source = dest and there's no escaping - while ( p == d && *p != '\0' && *p != '\\' ) - p++, d++; - - while (*p != '\0') { - if (*p != '\\') { - *d++ = *p++; - } else { - switch ( *++p ) { // skip past the '\\' - case '\0': - LOG_STRING(ERROR, errors) << "String cannot end with \\"; - *d = '\0'; - return d - dest; // we're done with p - case 'a': *d++ = '\a'; break; - case 'b': *d++ = '\b'; break; - case 'f': *d++ = '\f'; break; - case 'n': *d++ = '\n'; break; - case 'r': *d++ = '\r'; break; - case 't': *d++ = '\t'; break; - case 'v': *d++ = '\v'; break; - case '\\': *d++ = '\\'; break; - case '?': *d++ = '\?'; break; // \? Who knew? - case '\'': *d++ = '\''; break; - case '"': *d++ = '\"'; break; - case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits - case '4': case '5': case '6': case '7': { - char ch = *p - '0'; - if ( IS_OCTAL_DIGIT(p[1]) ) - ch = ch * 8 + *++p - '0'; - if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice - ch = ch * 8 + *++p - '0'; // now points at last digit - *d++ = ch; - break; - } - case 'x': case 'X': { - if (!isxdigit(p[1])) { - if (p[1] == '\0') { - LOG_STRING(ERROR, errors) << "String cannot end with \\x"; - } else { - LOG_STRING(ERROR, errors) << - "\\x cannot be followed by non-hex digit: \\" << *p << p[1]; - } - break; - } - unsigned int ch = 0; - const char *hex_start = p; - while (isxdigit(p[1])) // arbitrarily many hex digits - ch = (ch << 4) + hex_digit_to_int(*++p); - if (ch > 0xFF) - LOG_STRING(ERROR, errors) << "Value of " << - "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; - *d++ = ch; - break; - } -#if 0 // TODO(kenton): Support \u and \U? Requires runetochar(). - case 'u': { - // \uhhhh => convert 4 hex digits to UTF-8 - char32 rune = 0; - const char *hex_start = p; - for (int i = 0; i < 4; ++i) { - if (isxdigit(p[1])) { // Look one char ahead. - rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. - } else { - LOG_STRING(ERROR, errors) - << "\\u must be followed by 4 hex digits: \\" - << string(hex_start, p+1-hex_start); - break; - } - } - d += runetochar(d, &rune); - break; - } - case 'U': { - // \Uhhhhhhhh => convert 8 hex digits to UTF-8 - char32 rune = 0; - const char *hex_start = p; - for (int i = 0; i < 8; ++i) { - if (isxdigit(p[1])) { // Look one char ahead. - // Don't change rune until we're sure this - // is within the Unicode limit, but do advance p. - char32 newrune = (rune << 4) + hex_digit_to_int(*++p); - if (newrune > 0x10FFFF) { - LOG_STRING(ERROR, errors) - << "Value of \\" - << string(hex_start, p + 1 - hex_start) - << " exceeds Unicode limit (0x10FFFF)"; - break; - } else { - rune = newrune; - } - } else { - LOG_STRING(ERROR, errors) - << "\\U must be followed by 8 hex digits: \\" - << string(hex_start, p+1-hex_start); - break; - } - } - d += runetochar(d, &rune); - break; - } -#endif - default: - LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p; - } - p++; // read past letter we escaped - } - } - *d = '\0'; - return d - dest; -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeString() -// This does the same thing as UnescapeCEscapeSequences, but creates -// a new string. The caller does not need to worry about allocating -// a dest buffer. This should be used for non performance critical -// tasks such as printing debug messages. It is safe for src and dest -// to be the same. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// -// In the first and second calls, the length of dest is returned. In the -// the third call, the new string is returned. -// ---------------------------------------------------------------------- -int UnescapeCEscapeString(const string& src, string* dest) { - return UnescapeCEscapeString(src, dest, NULL); -} - -int UnescapeCEscapeString(const string& src, string* dest, - vector *errors) { - scoped_array unescaped(new char[src.size() + 1]); - int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); - GOOGLE_CHECK(dest); - dest->assign(unescaped.get(), len); - return len; -} - -string UnescapeCEscapeString(const string& src) { - scoped_array unescaped(new char[src.size() + 1]); - int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL); - return string(unescaped.get(), len); -} - -// ---------------------------------------------------------------------- -// CEscapeString() -// CHexEscapeString() -// Copies 'src' to 'dest', escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses -// hexadecimal rather than octal sequences. -// Returns the number of bytes written to 'dest' (not including the \0) -// or -1 if there was insufficient space. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -int CEscapeInternal(const char* src, int src_len, char* dest, - int dest_len, bool use_hex, bool utf8_safe) { - const char* src_end = src + src_len; - int used = 0; - bool last_hex_escape = false; // true if last output char was \xNN - - for (; src < src_end; src++) { - if (dest_len - used < 2) // Need space for two letter escape - return -1; - - bool is_hex_escape = false; - switch (*src) { - case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; - case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; - case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; - case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; - case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; - case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; - default: - // Note that if we emit \xNN and the src character after that is a hex - // digit then that digit must be escaped too to prevent it being - // interpreted as part of the character code by C. - if ((!utf8_safe || static_cast(*src) < 0x80) && - (!isprint(*src) || - (last_hex_escape && isxdigit(*src)))) { - if (dest_len - used < 4) // need space for 4 letter escape - return -1; - sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), - static_cast(*src)); - is_hex_escape = use_hex; - used += 4; - } else { - dest[used++] = *src; break; - } - } - last_hex_escape = is_hex_escape; - } - - if (dest_len - used < 1) // make sure that there is room for \0 - return -1; - - dest[used] = '\0'; // doesn't count towards return value though - return used; -} - -int CEscapeString(const char* src, int src_len, char* dest, int dest_len) { - return CEscapeInternal(src, src_len, dest, dest_len, false, false); -} - -// ---------------------------------------------------------------------- -// CEscape() -// CHexEscape() -// Copies 'src' to result, escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. The 'Hex' version -// hexadecimal rather than octal sequences. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -string CEscape(const string& src) { - const int dest_length = src.size() * 4 + 1; // Maximum possible expansion - scoped_array dest(new char[dest_length]); - const int len = CEscapeInternal(src.data(), src.size(), - dest.get(), dest_length, false, false); - GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); -} - -namespace strings { - -string Utf8SafeCEscape(const string& src) { - const int dest_length = src.size() * 4 + 1; // Maximum possible expansion - scoped_array dest(new char[dest_length]); - const int len = CEscapeInternal(src.data(), src.size(), - dest.get(), dest_length, false, true); - GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); -} - -string CHexEscape(const string& src) { - const int dest_length = src.size() * 4 + 1; // Maximum possible expansion - scoped_array dest(new char[dest_length]); - const int len = CEscapeInternal(src.data(), src.size(), - dest.get(), dest_length, true, false); - GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); -} - -} // namespace strings - -// ---------------------------------------------------------------------- -// strto32_adaptor() -// strtou32_adaptor() -// Implementation of strto[u]l replacements that have identical -// overflow and underflow characteristics for both ILP-32 and LP-64 -// platforms, including errno preservation in error-free calls. -// ---------------------------------------------------------------------- - -int32 strto32_adaptor(const char *nptr, char **endptr, int base) { - const int saved_errno = errno; - errno = 0; - const long result = strtol(nptr, endptr, base); - if (errno == ERANGE && result == LONG_MIN) { - return kint32min; - } else if (errno == ERANGE && result == LONG_MAX) { - return kint32max; - } else if (errno == 0 && result < kint32min) { - errno = ERANGE; - return kint32min; - } else if (errno == 0 && result > kint32max) { - errno = ERANGE; - return kint32max; - } - if (errno == 0) - errno = saved_errno; - return static_cast(result); -} - -uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { - const int saved_errno = errno; - errno = 0; - const unsigned long result = strtoul(nptr, endptr, base); - if (errno == ERANGE && result == ULONG_MAX) { - return kuint32max; - } else if (errno == 0 && result > kuint32max) { - errno = ERANGE; - return kuint32max; - } - if (errno == 0) - errno = saved_errno; - return static_cast(result); -} - -// ---------------------------------------------------------------------- -// FastIntToBuffer() -// FastInt64ToBuffer() -// FastHexToBuffer() -// FastHex64ToBuffer() -// FastHex32ToBuffer() -// ---------------------------------------------------------------------- - -// Offset into buffer where FastInt64ToBuffer places the end of string -// null character. Also used by FastInt64ToBufferLeft. -static const int kFastInt64ToBufferOffset = 21; - -char *FastInt64ToBuffer(int64 i, char* buffer) { - // We could collapse the positive and negative sections, but that - // would be slightly slower for positive numbers... - // 22 bytes is enough to store -2**64, -18446744073709551616. - char* p = buffer + kFastInt64ToBufferOffset; - *p-- = '\0'; - if (i >= 0) { - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; - } else { - // On different platforms, % and / have different behaviors for - // negative numbers, so we need to jump through hoops to make sure - // we don't divide negative numbers. - if (i > -10) { - i = -i; - *p-- = '0' + i; - *p = '-'; - return p; - } else { - // Make sure we aren't at MIN_INT, in which case we can't say i = -i - i = i + 10; - i = -i; - *p-- = '0' + i % 10; - // Undo what we did a moment ago - i = i / 10 + 1; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - *p = '-'; - return p; - } - } -} - -// Offset into buffer where FastInt32ToBuffer places the end of string -// null character. Also used by FastInt32ToBufferLeft -static const int kFastInt32ToBufferOffset = 11; - -// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the -// compiler to generate 32 bit arithmetic instructions. It's much faster, at -// least with 32 bit binaries. -char *FastInt32ToBuffer(int32 i, char* buffer) { - // We could collapse the positive and negative sections, but that - // would be slightly slower for positive numbers... - // 12 bytes is enough to store -2**32, -4294967296. - char* p = buffer + kFastInt32ToBufferOffset; - *p-- = '\0'; - if (i >= 0) { - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; - } else { - // On different platforms, % and / have different behaviors for - // negative numbers, so we need to jump through hoops to make sure - // we don't divide negative numbers. - if (i > -10) { - i = -i; - *p-- = '0' + i; - *p = '-'; - return p; - } else { - // Make sure we aren't at MIN_INT, in which case we can't say i = -i - i = i + 10; - i = -i; - *p-- = '0' + i % 10; - // Undo what we did a moment ago - i = i / 10 + 1; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - *p = '-'; - return p; - } - } -} - -char *FastHexToBuffer(int i, char* buffer) { - GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i; - - static const char *hexdigits = "0123456789abcdef"; - char *p = buffer + 21; - *p-- = '\0'; - do { - *p-- = hexdigits[i & 15]; // mod by 16 - i >>= 4; // divide by 16 - } while (i > 0); - return p + 1; -} - -char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) { - static const char *hexdigits = "0123456789abcdef"; - buffer[num_byte] = '\0'; - for (int i = num_byte - 1; i >= 0; i--) { - buffer[i] = hexdigits[uint32(value) & 0xf]; - value >>= 4; - } - return buffer; -} - -char *FastHex64ToBuffer(uint64 value, char* buffer) { - return InternalFastHexToBuffer(value, buffer, 16); -} - -char *FastHex32ToBuffer(uint32 value, char* buffer) { - return InternalFastHexToBuffer(value, buffer, 8); -} - -static inline char* PlaceNum(char* p, int num, char prev_sep) { - *p-- = '0' + num % 10; - *p-- = '0' + num / 10; - *p-- = prev_sep; - return p; -} - -// ---------------------------------------------------------------------- -// FastInt32ToBufferLeft() -// FastUInt32ToBufferLeft() -// FastInt64ToBufferLeft() -// FastUInt64ToBufferLeft() -// -// Like the Fast*ToBuffer() functions above, these are intended for speed. -// Unlike the Fast*ToBuffer() functions, however, these functions write -// their output to the beginning of the buffer (hence the name, as the -// output is left-aligned). The caller is responsible for ensuring that -// the buffer has enough space to hold the output. -// -// Returns a pointer to the end of the string (i.e. the null character -// terminating the string). -// ---------------------------------------------------------------------- - -static const char two_ASCII_digits[100][2] = { - {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'}, - {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'}, - {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'}, - {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'}, - {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'}, - {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'}, - {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'}, - {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'}, - {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'}, - {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'}, - {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'}, - {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'}, - {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'}, - {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'}, - {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'}, - {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'}, - {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'}, - {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'}, - {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'}, - {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'} -}; - -char* FastUInt32ToBufferLeft(uint32 u, char* buffer) { - int digits; - const char *ASCII_digits = NULL; - // The idea of this implementation is to trim the number of divides to as few - // as possible by using multiplication and subtraction rather than mod (%), - // and by outputting two digits at a time rather than one. - // The huge-number case is first, in the hopes that the compiler will output - // that case in one branch-free block of code, and only output conditional - // branches into it from below. - if (u >= 1000000000) { // >= 1,000,000,000 - digits = u / 100000000; // 100,000,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt100_000_000: - u -= digits * 100000000; // 100,000,000 -lt100_000_000: - digits = u / 1000000; // 1,000,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt1_000_000: - u -= digits * 1000000; // 1,000,000 -lt1_000_000: - digits = u / 10000; // 10,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt10_000: - u -= digits * 10000; // 10,000 -lt10_000: - digits = u / 100; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt100: - u -= digits * 100; -lt100: - digits = u; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -done: - *buffer = 0; - return buffer; - } - - if (u < 100) { - digits = u; - if (u >= 10) goto lt100; - *buffer++ = '0' + digits; - goto done; - } - if (u < 10000) { // 10,000 - if (u >= 1000) goto lt10_000; - digits = u / 100; - *buffer++ = '0' + digits; - goto sublt100; - } - if (u < 1000000) { // 1,000,000 - if (u >= 100000) goto lt1_000_000; - digits = u / 10000; // 10,000 - *buffer++ = '0' + digits; - goto sublt10_000; - } - if (u < 100000000) { // 100,000,000 - if (u >= 10000000) goto lt100_000_000; - digits = u / 1000000; // 1,000,000 - *buffer++ = '0' + digits; - goto sublt1_000_000; - } - // we already know that u < 1,000,000,000 - digits = u / 100000000; // 100,000,000 - *buffer++ = '0' + digits; - goto sublt100_000_000; -} - -char* FastInt32ToBufferLeft(int32 i, char* buffer) { - uint32 u = i; - if (i < 0) { - *buffer++ = '-'; - u = -i; - } - return FastUInt32ToBufferLeft(u, buffer); -} - -char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) { - int digits; - const char *ASCII_digits = NULL; - - uint32 u = static_cast(u64); - if (u == u64) return FastUInt32ToBufferLeft(u, buffer); - - uint64 top_11_digits = u64 / 1000000000; - buffer = FastUInt64ToBufferLeft(top_11_digits, buffer); - u = u64 - (top_11_digits * 1000000000); - - digits = u / 10000000; // 10,000,000 - GOOGLE_DCHECK_LT(digits, 100); - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 10000000; // 10,000,000 - digits = u / 100000; // 100,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 100000; // 100,000 - digits = u / 1000; // 1,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 1000; // 1,000 - digits = u / 10; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 10; - digits = u; - *buffer++ = '0' + digits; - *buffer = 0; - return buffer; -} - -char* FastInt64ToBufferLeft(int64 i, char* buffer) { - uint64 u = i; - if (i < 0) { - *buffer++ = '-'; - u = -i; - } - return FastUInt64ToBufferLeft(u, buffer); -} - -// ---------------------------------------------------------------------- -// SimpleItoa() -// Description: converts an integer to a string. -// -// Return value: string -// ---------------------------------------------------------------------- - -string SimpleItoa(int i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned int i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -string SimpleItoa(long i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned long i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -string SimpleItoa(long long i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned long long i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -// ---------------------------------------------------------------------- -// SimpleDtoa() -// SimpleFtoa() -// DoubleToBuffer() -// FloatToBuffer() -// We want to print the value without losing precision, but we also do -// not want to print more digits than necessary. This turns out to be -// trickier than it sounds. Numbers like 0.2 cannot be represented -// exactly in binary. If we print 0.2 with a very large precision, -// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167". -// On the other hand, if we set the precision too low, we lose -// significant digits when printing numbers that actually need them. -// It turns out there is no precision value that does the right thing -// for all numbers. -// -// Our strategy is to first try printing with a precision that is never -// over-precise, then parse the result with strtod() to see if it -// matches. If not, we print again with a precision that will always -// give a precise result, but may use more digits than necessary. -// -// An arguably better strategy would be to use the algorithm described -// in "How to Print Floating-Point Numbers Accurately" by Steele & -// White, e.g. as implemented by David M. Gay's dtoa(). It turns out, -// however, that the following implementation is about as fast as -// DMG's code. Furthermore, DMG's code locks mutexes, which means it -// will not scale well on multi-core machines. DMG's code is slightly -// more accurate (in that it will never use more digits than -// necessary), but this is probably irrelevant for most users. -// -// Rob Pike and Ken Thompson also have an implementation of dtoa() in -// third_party/fmt/fltfmt.cc. Their implementation is similar to this -// one in that it makes guesses and then uses strtod() to check them. -// Their implementation is faster because they use their own code to -// generate the digits in the first place rather than use snprintf(), -// thus avoiding format string parsing overhead. However, this makes -// it considerably more complicated than the following implementation, -// and it is embedded in a larger library. If speed turns out to be -// an issue, we could re-implement this in terms of their -// implementation. -// ---------------------------------------------------------------------- - -string SimpleDtoa(double value) { - char buffer[kDoubleToBufferSize]; - return DoubleToBuffer(value, buffer); -} - -string SimpleFtoa(float value) { - char buffer[kFloatToBufferSize]; - return FloatToBuffer(value, buffer); -} - -static inline bool IsValidFloatChar(char c) { - return ('0' <= c && c <= '9') || - c == 'e' || c == 'E' || - c == '+' || c == '-'; -} - -void DelocalizeRadix(char* buffer) { - // Fast check: if the buffer has a normal decimal point, assume no - // translation is needed. - if (strchr(buffer, '.') != NULL) return; - - // Find the first unknown character. - while (IsValidFloatChar(*buffer)) ++buffer; - - if (*buffer == '\0') { - // No radix character found. - return; - } - - // We are now pointing at the locale-specific radix character. Replace it - // with '.'. - *buffer = '.'; - ++buffer; - - if (!IsValidFloatChar(*buffer) && *buffer != '\0') { - // It appears the radix was a multi-byte character. We need to remove the - // extra bytes. - char* target = buffer; - do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); - memmove(target, buffer, strlen(buffer) + 1); - } -} - -char* DoubleToBuffer(double value, char* buffer) { - // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all - // platforms these days. Just in case some system exists where DBL_DIG - // is significantly larger -- and risks overflowing our buffer -- we have - // this assert. - GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); - - if (value == numeric_limits::infinity()) { - strcpy(buffer, "inf"); - return buffer; - } else if (value == -numeric_limits::infinity()) { - strcpy(buffer, "-inf"); - return buffer; - } else if (IsNaN(value)) { - strcpy(buffer, "nan"); - return buffer; - } - - int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); - - // The snprintf should never overflow because the buffer is significantly - // larger than the precision we asked for. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); - - // We need to make parsed_value volatile in order to force the compiler to - // write it out to the stack. Otherwise, it may keep the value in a - // register, and if it does that, it may keep it as a long double instead - // of a double. This long double may have extra bits that make it compare - // unequal to "value" even though it would be exactly equal if it were - // truncated to a double. - volatile double parsed_value = strtod(buffer, NULL); - if (parsed_value != value) { - int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); - - // Should never overflow; see above. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); - } - - DelocalizeRadix(buffer); - return buffer; -} - -bool safe_strtof(const char* str, float* value) { - char* endptr; - errno = 0; // errno only gets set on errors -#if defined(_WIN32) || defined (__hpux) // has no strtof() - *value = strtod(str, &endptr); -#else - *value = strtof(str, &endptr); -#endif - return *str != 0 && *endptr == 0 && errno == 0; -} - -char* FloatToBuffer(float value, char* buffer) { - // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all - // platforms these days. Just in case some system exists where FLT_DIG - // is significantly larger -- and risks overflowing our buffer -- we have - // this assert. - GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); - - if (value == numeric_limits::infinity()) { - strcpy(buffer, "inf"); - return buffer; - } else if (value == -numeric_limits::infinity()) { - strcpy(buffer, "-inf"); - return buffer; - } else if (IsNaN(value)) { - strcpy(buffer, "nan"); - return buffer; - } - - int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); - - // The snprintf should never overflow because the buffer is significantly - // larger than the precision we asked for. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); - - float parsed_value; - if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { - int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); - - // Should never overflow; see above. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); - } - - DelocalizeRadix(buffer); - return buffer; -} - -// ---------------------------------------------------------------------- -// NoLocaleStrtod() -// This code will make you cry. -// ---------------------------------------------------------------------- - -// Returns a string identical to *input except that the character pointed to -// by radix_pos (which should be '.') is replaced with the locale-specific -// radix character. -string LocalizeRadix(const char* input, const char* radix_pos) { - // Determine the locale-specific radix character by calling sprintf() to - // print the number 1.5, then stripping off the digits. As far as I can - // tell, this is the only portable, thread-safe way to get the C library - // to divuldge the locale's radix character. No, localeconv() is NOT - // thread-safe. - char temp[16]; - int size = sprintf(temp, "%.1f", 1.5); - GOOGLE_CHECK_EQ(temp[0], '1'); - GOOGLE_CHECK_EQ(temp[size-1], '5'); - GOOGLE_CHECK_LE(size, 6); - - // Now replace the '.' in the input with it. - string result; - result.reserve(strlen(input) + size - 3); - result.append(input, radix_pos); - result.append(temp + 1, size - 2); - result.append(radix_pos + 1); - return result; -} - -double NoLocaleStrtod(const char* text, char** original_endptr) { - // We cannot simply set the locale to "C" temporarily with setlocale() - // as this is not thread-safe. Instead, we try to parse in the current - // locale first. If parsing stops at a '.' character, then this is a - // pretty good hint that we're actually in some other locale in which - // '.' is not the radix character. - - char* temp_endptr; - double result = strtod(text, &temp_endptr); - if (original_endptr != NULL) *original_endptr = temp_endptr; - if (*temp_endptr != '.') return result; - - // Parsing halted on a '.'. Perhaps we're in a different locale? Let's - // try to replace the '.' with a locale-specific radix character and - // try again. - string localized = LocalizeRadix(text, temp_endptr); - const char* localized_cstr = localized.c_str(); - char* localized_endptr; - result = strtod(localized_cstr, &localized_endptr); - if ((localized_endptr - localized_cstr) > - (temp_endptr - text)) { - // This attempt got further, so replacing the decimal must have helped. - // Update original_endptr to point at the right location. - if (original_endptr != NULL) { - // size_diff is non-zero if the localized radix has multiple bytes. - int size_diff = localized.size() - strlen(text); - // const_cast is necessary to match the strtod() interface. - *original_endptr = const_cast( - text + (localized_endptr - localized_cstr - size_diff)); - } - } - - return result; -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/strutil.h b/Resources/NetHook/google/protobuf/stubs/strutil.h deleted file mode 100644 index 777694b7..00000000 --- a/Resources/NetHook/google/protobuf/stubs/strutil.h +++ /dev/null @@ -1,459 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// from google3/strings/strutil.h - -#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ -#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - -#include -#include -#include - -namespace google { -namespace protobuf { - -#ifdef _MSC_VER -#define strtoll _strtoi64 -#define strtoull _strtoui64 -#elif defined(__DECCXX) && defined(__osf__) -// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit. -#define strtoll strtol -#define strtoull strtoul -#endif - -// ---------------------------------------------------------------------- -// ascii_isalnum() -// Check if an ASCII character is alphanumeric. We can't use ctype's -// isalnum() because it is affected by locale. This function is applied -// to identifiers in the protocol buffer language, not to natural-language -// strings, so locale should not be taken into account. -// ascii_isdigit() -// Like above, but only accepts digits. -// ---------------------------------------------------------------------- - -inline bool ascii_isalnum(char c) { - return ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9'); -} - -inline bool ascii_isdigit(char c) { - return ('0' <= c && c <= '9'); -} - -// ---------------------------------------------------------------------- -// HasPrefixString() -// Check if a string begins with a given prefix. -// StripPrefixString() -// Given a string and a putative prefix, returns the string minus the -// prefix string if the prefix matches, otherwise the original -// string. -// ---------------------------------------------------------------------- -inline bool HasPrefixString(const string& str, - const string& prefix) { - return str.size() >= prefix.size() && - str.compare(0, prefix.size(), prefix) == 0; -} - -inline string StripPrefixString(const string& str, const string& prefix) { - if (HasPrefixString(str, prefix)) { - return str.substr(prefix.size()); - } else { - return str; - } -} - -// ---------------------------------------------------------------------- -// HasSuffixString() -// Return true if str ends in suffix. -// StripSuffixString() -// Given a string and a putative suffix, returns the string minus the -// suffix string if the suffix matches, otherwise the original -// string. -// ---------------------------------------------------------------------- -inline bool HasSuffixString(const string& str, - const string& suffix) { - return str.size() >= suffix.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; -} - -inline string StripSuffixString(const string& str, const string& suffix) { - if (HasSuffixString(str, suffix)) { - return str.substr(0, str.size() - suffix.size()); - } else { - return str; - } -} - -// ---------------------------------------------------------------------- -// StripString -// Replaces any occurrence of the character 'remove' (or the characters -// in 'remove') with the character 'replacewith'. -// Good for keeping html characters or protocol characters (\t) out -// of places where they might cause a problem. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, - char replacewith); - -// ---------------------------------------------------------------------- -// LowerString() -// UpperString() -// Convert the characters in "s" to lowercase or uppercase. ASCII-only: -// these functions intentionally ignore locale because they are applied to -// identifiers used in the Protocol Buffer language, not to natural-language -// strings. -// ---------------------------------------------------------------------- - -inline void LowerString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { - // tolower() changes based on locale. We don't want this! - if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; - } -} - -inline void UpperString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { - // toupper() changes based on locale. We don't want this! - if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; - } -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Give me a string and two patterns "old" and "new", and I replace -// the first instance of "old" in the string with "new", if it -// exists. RETURN a new string, regardless of whether the replacement -// happened or not. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); - -// ---------------------------------------------------------------------- -// SplitStringUsing() -// Split a string using a character delimiter. Append the components -// to 'result'. If there are consecutive delimiters, this function skips -// over all of them. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, - vector* res); - -// ---------------------------------------------------------------------- -// JoinStrings() -// These methods concatenate a vector of strings into a C++ string, using -// the C-string "delim" as a separator between components. There are two -// flavors of the function, one flavor returns the concatenated string, -// another takes a pointer to the target string. In the latter case the -// target string is cleared and overwritten. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void JoinStrings(const vector& components, - const char* delim, string* result); - -inline string JoinStrings(const vector& components, - const char* delim) { - string result; - JoinStrings(components, delim, &result); - return result; -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeSequences() -// Copies "source" to "dest", rewriting C-style escape sequences -// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII -// equivalents. "dest" must be sufficiently large to hold all -// the characters in the rewritten string (i.e. at least as large -// as strlen(source) + 1 should be safe, since the replacements -// are always shorter than the original escaped sequences). It's -// safe for source and dest to be the same. RETURNS the length -// of dest. -// -// It allows hex sequences \xhh, or generally \xhhhhh with an -// arbitrary number of hex digits, but all of them together must -// specify a value of a single byte (e.g. \x0045 is equivalent -// to \x45, and \x1234 is erroneous). -// -// It also allows escape sequences of the form \uhhhh (exactly four -// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight -// hex digits, upper or lower case) to specify a Unicode code -// point. The dest array will contain the UTF8-encoded version of -// that code-point (e.g., if source contains \u2019, then dest will -// contain the three bytes 0xE2, 0x80, and 0x99). For the inverse -// transformation, use UniLib::UTF8EscapeString -// (util/utf8/unilib.h), not CEscapeString. -// -// Errors: In the first form of the call, errors are reported with -// LOG(ERROR). The same is true for the second form of the call if -// the pointer to the string vector is NULL; otherwise, error -// messages are stored in the vector. In either case, the effect on -// the dest array is not defined, but rest of the source will be -// processed. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - vector *errors); - -// ---------------------------------------------------------------------- -// UnescapeCEscapeString() -// This does the same thing as UnescapeCEscapeSequences, but creates -// a new string. The caller does not need to worry about allocating -// a dest buffer. This should be used for non performance critical -// tasks such as printing debug messages. It is safe for src and dest -// to be the same. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// -// In the first and second calls, the length of dest is returned. In the -// the third call, the new string is returned. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - vector *errors); -LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); - -// ---------------------------------------------------------------------- -// CEscapeString() -// Copies 'src' to 'dest', escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. -// Returns the number of bytes written to 'dest' (not including the \0) -// or -1 if there was insufficient space. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len, - char* dest, int dest_len); - -// ---------------------------------------------------------------------- -// CEscape() -// More convenient form of CEscapeString: returns result as a "string". -// This version is slower than CEscapeString() because it does more -// allocation. However, it is much more convenient to use in -// non-speed-critical code like logging messages etc. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string CEscape(const string& src); - -namespace strings { -// Like CEscape() but does not escape bytes with the upper bit set. -LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); - -// Like CEscape() but uses hex (\x) escapes instead of octals. -LIBPROTOBUF_EXPORT string CHexEscape(const string& src); -} // namespace strings - -// ---------------------------------------------------------------------- -// strto32() -// strtou32() -// strto64() -// strtou64() -// Architecture-neutral plug compatible replacements for strtol() and -// strtoul(). Long's have different lengths on ILP-32 and LP-64 -// platforms, so using these is safer, from the point of view of -// overflow behavior, than using the standard libc functions. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr, - int base); -LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr, - int base); - -inline int32 strto32(const char *nptr, char **endptr, int base) { - if (sizeof(int32) == sizeof(long)) - return strtol(nptr, endptr, base); - else - return strto32_adaptor(nptr, endptr, base); -} - -inline uint32 strtou32(const char *nptr, char **endptr, int base) { - if (sizeof(uint32) == sizeof(unsigned long)) - return strtoul(nptr, endptr, base); - else - return strtou32_adaptor(nptr, endptr, base); -} - -// For now, long long is 64-bit on all the platforms we care about, so these -// functions can simply pass the call to strto[u]ll. -inline int64 strto64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), - sizeof_int64_is_not_sizeof_long_long); - return strtoll(nptr, endptr, base); -} - -inline uint64 strtou64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), - sizeof_uint64_is_not_sizeof_long_long); - return strtoull(nptr, endptr, base); -} - -// ---------------------------------------------------------------------- -// FastIntToBuffer() -// FastHexToBuffer() -// FastHex64ToBuffer() -// FastHex32ToBuffer() -// FastTimeToBuffer() -// These are intended for speed. FastIntToBuffer() assumes the -// integer is non-negative. FastHexToBuffer() puts output in -// hex rather than decimal. FastTimeToBuffer() puts the output -// into RFC822 format. -// -// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format, -// padded to exactly 16 bytes (plus one byte for '\0') -// -// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format, -// padded to exactly 8 bytes (plus one byte for '\0') -// -// All functions take the output buffer as an arg. -// They all return a pointer to the beginning of the output, -// which may not be the beginning of the input buffer. -// ---------------------------------------------------------------------- - -// Suggested buffer size for FastToBuffer functions. Also works with -// DoubleToBuffer() and FloatToBuffer(). -static const int kFastToBufferSize = 32; - -LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer); -char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below -char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below -LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer); -LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer); - -// at least 22 bytes long -inline char* FastIntToBuffer(int i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); -} -inline char* FastUIntToBuffer(unsigned int i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); -} -inline char* FastLongToBuffer(long i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); -} -inline char* FastULongToBuffer(unsigned long i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); -} - -// ---------------------------------------------------------------------- -// FastInt32ToBufferLeft() -// FastUInt32ToBufferLeft() -// FastInt64ToBufferLeft() -// FastUInt64ToBufferLeft() -// -// Like the Fast*ToBuffer() functions above, these are intended for speed. -// Unlike the Fast*ToBuffer() functions, however, these functions write -// their output to the beginning of the buffer (hence the name, as the -// output is left-aligned). The caller is responsible for ensuring that -// the buffer has enough space to hold the output. -// -// Returns a pointer to the end of the string (i.e. the null character -// terminating the string). -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer); - -// Just define these in terms of the above. -inline char* FastUInt32ToBuffer(uint32 i, char* buffer) { - FastUInt32ToBufferLeft(i, buffer); - return buffer; -} -inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { - FastUInt64ToBufferLeft(i, buffer); - return buffer; -} - -// ---------------------------------------------------------------------- -// SimpleItoa() -// Description: converts an integer to a string. -// -// Return value: string -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string SimpleItoa(int i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i); -LIBPROTOBUF_EXPORT string SimpleItoa(long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i); -LIBPROTOBUF_EXPORT string SimpleItoa(long long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i); - -// ---------------------------------------------------------------------- -// SimpleDtoa() -// SimpleFtoa() -// DoubleToBuffer() -// FloatToBuffer() -// Description: converts a double or float to a string which, if -// passed to NoLocaleStrtod(), will produce the exact same original double -// (except in case of NaN; all NaNs are considered the same value). -// We try to keep the string short but it's not guaranteed to be as -// short as possible. -// -// DoubleToBuffer() and FloatToBuffer() write the text to the given -// buffer and return it. The buffer must be at least -// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize -// bytes for floats. kFastToBufferSize is also guaranteed to be large -// enough to hold either. -// -// Return value: string -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string SimpleDtoa(double value); -LIBPROTOBUF_EXPORT string SimpleFtoa(float value); - -LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); -LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); - -// In practice, doubles should never need more than 24 bytes and floats -// should never need more than 14 (including null terminators), but we -// overestimate to be safe. -static const int kDoubleToBufferSize = 32; -static const int kFloatToBufferSize = 24; - -// ---------------------------------------------------------------------- -// NoLocaleStrtod() -// Exactly like strtod(), except it always behaves as if in the "C" -// locale (i.e. decimal points must be '.'s). -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr); - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - - diff --git a/Resources/NetHook/google/protobuf/stubs/strutil_unittest.cc b/Resources/NetHook/google/protobuf/stubs/strutil_unittest.cc deleted file mode 100644 index b9c9253b..00000000 --- a/Resources/NetHook/google/protobuf/stubs/strutil_unittest.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace { - -// TODO(kenton): Copy strutil tests from google3? - -TEST(StringUtilityTest, ImmuneToLocales) { - // Remember the old locale. - char* old_locale_cstr = setlocale(LC_NUMERIC, NULL); - ASSERT_TRUE(old_locale_cstr != NULL); - string old_locale = old_locale_cstr; - - // Set the locale to "C". - ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL); - - EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); - EXPECT_EQ("1.5", SimpleDtoa(1.5)); - EXPECT_EQ("1.5", SimpleFtoa(1.5)); - - // Verify that the endptr is set correctly even if not all text was parsed. - const char* text = "1.5f"; - char* endptr; - EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); - EXPECT_EQ(3, endptr - text); - - if (setlocale(LC_NUMERIC, "es_ES") == NULL && - setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) { - // Some systems may not have the desired locale available. - GOOGLE_LOG(WARNING) - << "Couldn't set locale to es_ES. Skipping this test."; - } else { - EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); - EXPECT_EQ("1.5", SimpleDtoa(1.5)); - EXPECT_EQ("1.5", SimpleFtoa(1.5)); - EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); - EXPECT_EQ(3, endptr - text); - } - - // Return to original locale. - setlocale(LC_NUMERIC, old_locale.c_str()); -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/substitute.cc b/Resources/NetHook/google/protobuf/stubs/substitute.cc deleted file mode 100644 index b542aaa4..00000000 --- a/Resources/NetHook/google/protobuf/stubs/substitute.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -#include -#include -#include - -namespace google { -namespace protobuf { -namespace strings { - -using internal::SubstituteArg; - -// Returns the number of args in arg_array which were passed explicitly -// to Substitute(). -static int CountSubstituteArgs(const SubstituteArg* const* args_array) { - int count = 0; - while (args_array[count] != NULL && args_array[count]->size() != -1) { - ++count; - } - return count; -} - -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - string result; - SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8, arg9); - return result; -} - -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - const SubstituteArg* const args_array[] = { - &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL - }; - - // Determine total size needed. - int size = 0; - for (int i = 0; format[i] != '\0'; i++) { - if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - int index = format[i+1] - '0'; - if (args_array[index]->size() == -1) { - GOOGLE_LOG(DFATAL) - << "strings::Substitute format string invalid: asked for \"$" - << index << "\", but only " << CountSubstituteArgs(args_array) - << " args were given. Full format string was: \"" - << CEscape(format) << "\"."; - return; - } - size += args_array[index]->size(); - ++i; // Skip next char. - } else if (format[i+1] == '$') { - ++size; - ++i; // Skip next char. - } else { - GOOGLE_LOG(DFATAL) - << "Invalid strings::Substitute() format string: \"" - << CEscape(format) << "\"."; - return; - } - } else { - ++size; - } - } - - if (size == 0) return; - - // Build the string. - int original_size = output->size(); - STLStringResizeUninitialized(output, original_size + size); - char* target = string_as_array(output) + original_size; - for (int i = 0; format[i] != '\0'; i++) { - if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - const SubstituteArg* src = args_array[format[i+1] - '0']; - memcpy(target, src->data(), src->size()); - target += src->size(); - ++i; // Skip next char. - } else if (format[i+1] == '$') { - *target++ = '$'; - ++i; // Skip next char. - } - } else { - *target++ = format[i]; - } - } - - GOOGLE_DCHECK_EQ(target - output->data(), output->size()); -} - -} // namespace strings -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/stubs/substitute.h b/Resources/NetHook/google/protobuf/stubs/substitute.h deleted file mode 100644 index 2581793b..00000000 --- a/Resources/NetHook/google/protobuf/stubs/substitute.h +++ /dev/null @@ -1,170 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// from google3/strings/substitute.h - -#include -#include -#include - -#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ -#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ - -namespace google { -namespace protobuf { -namespace strings { - -// ---------------------------------------------------------------------- -// strings::Substitute() -// strings::SubstituteAndAppend() -// Kind of like StringPrintf, but different. -// -// Example: -// string GetMessage(string first_name, string last_name, int age) { -// return strings::Substitute("My name is $0 $1 and I am $2 years old.", -// first_name, last_name, age); -// } -// -// Differences from StringPrintf: -// * The format string does not identify the types of arguments. -// Instead, the magic of C++ deals with this for us. See below -// for a list of accepted types. -// * Substitutions in the format string are identified by a '$' -// followed by a digit. So, you can use arguments out-of-order and -// use the same argument multiple times. -// * It's much faster than StringPrintf. -// -// Supported types: -// * Strings (const char*, const string&) -// * Note that this means you do not have to add .c_str() to all of -// your strings. In fact, you shouldn't; it will be slower. -// * int32, int64, uint32, uint64: Formatted using SimpleItoa(). -// * float, double: Formatted using SimpleFtoa() and SimpleDtoa(). -// * bool: Printed as "true" or "false". -// -// SubstituteAndAppend() is like Substitute() but appends the result to -// *output. Example: -// -// string str; -// strings::SubstituteAndAppend(&str, -// "My name is $0 $1 and I am $2 years old.", -// first_name, last_name, age); -// -// Substitute() is significantly faster than StringPrintf(). For very -// large strings, it may be orders of magnitude faster. -// ---------------------------------------------------------------------- - -namespace internal { // Implementation details. - -class SubstituteArg { - public: - inline SubstituteArg(const char* value) - : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} - - // Indicates that no argument was given. - inline explicit SubstituteArg() - : text_(NULL), size_(-1) {} - - // Primitives - // We don't overload for signed and unsigned char because if people are - // explicitly declaring their chars as signed or unsigned then they are - // probably actually using them as 8-bit integers and would probably - // prefer an integer representation. But, we don't really know. So, we - // make the caller decide what to do. - inline SubstituteArg(char value) - : text_(scratch_), size_(1) { scratch_[0] = value; } - inline SubstituteArg(short value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned short value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(int value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned int value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long value) - : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long value) - : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long long value) - : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long long value) - : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(float value) - : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(double value) - : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(bool value) - : text_(value ? "true" : "false"), size_(strlen(text_)) {} - - inline const char* data() const { return text_; } - inline int size() const { return size_; } - - private: - const char* text_; - int size_; - char scratch_[kFastToBufferSize]; -}; - -} // namespace internal - -LIBPROTOBUF_EXPORT string Substitute( - const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); - -LIBPROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); - -} // namespace strings -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ diff --git a/Resources/NetHook/google/protobuf/test_util.cc b/Resources/NetHook/google/protobuf/test_util.cc deleted file mode 100644 index af8b3909..00000000 --- a/Resources/NetHook/google/protobuf/test_util.cc +++ /dev/null @@ -1,2854 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifdef _WIN32 -// Verify that #including windows.h does not break anything (e.g. because -// windows.h #defines GetMessage() as a macro). -#include -#endif - -#include -#include -#include - -#include -#include -#include - -namespace google { -namespace protobuf { - -void TestUtil::SetAllFields(unittest::TestAllTypes* message) { - message->set_optional_int32 (101); - message->set_optional_int64 (102); - message->set_optional_uint32 (103); - message->set_optional_uint64 (104); - message->set_optional_sint32 (105); - message->set_optional_sint64 (106); - message->set_optional_fixed32 (107); - message->set_optional_fixed64 (108); - message->set_optional_sfixed32(109); - message->set_optional_sfixed64(110); - message->set_optional_float (111); - message->set_optional_double (112); - message->set_optional_bool (true); - message->set_optional_string ("115"); - message->set_optional_bytes ("116"); - - message->mutable_optionalgroup ()->set_a(117); - message->mutable_optional_nested_message ()->set_bb(118); - message->mutable_optional_foreign_message()->set_c(119); - message->mutable_optional_import_message ()->set_d(120); - - message->set_optional_nested_enum (unittest::TestAllTypes::BAZ); - message->set_optional_foreign_enum(unittest::FOREIGN_BAZ ); - message->set_optional_import_enum (unittest_import::IMPORT_BAZ); - - // StringPiece and Cord fields are only accessible via reflection in the - // open source release; see comments in compiler/cpp/string_field.cc. -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("optional_string_piece"), - "124"); - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("optional_cord"), - "125"); -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - - // ----------------------------------------------------------------- - - message->add_repeated_int32 (201); - message->add_repeated_int64 (202); - message->add_repeated_uint32 (203); - message->add_repeated_uint64 (204); - message->add_repeated_sint32 (205); - message->add_repeated_sint64 (206); - message->add_repeated_fixed32 (207); - message->add_repeated_fixed64 (208); - message->add_repeated_sfixed32(209); - message->add_repeated_sfixed64(210); - message->add_repeated_float (211); - message->add_repeated_double (212); - message->add_repeated_bool (true); - message->add_repeated_string ("215"); - message->add_repeated_bytes ("216"); - - message->add_repeatedgroup ()->set_a(217); - message->add_repeated_nested_message ()->set_bb(218); - message->add_repeated_foreign_message()->set_c(219); - message->add_repeated_import_message ()->set_d(220); - - message->add_repeated_nested_enum (unittest::TestAllTypes::BAR); - message->add_repeated_foreign_enum(unittest::FOREIGN_BAR ); - message->add_repeated_import_enum (unittest_import::IMPORT_BAR); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - "224"); - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - "225"); -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - - // Add a second one of each field. - message->add_repeated_int32 (301); - message->add_repeated_int64 (302); - message->add_repeated_uint32 (303); - message->add_repeated_uint64 (304); - message->add_repeated_sint32 (305); - message->add_repeated_sint64 (306); - message->add_repeated_fixed32 (307); - message->add_repeated_fixed64 (308); - message->add_repeated_sfixed32(309); - message->add_repeated_sfixed64(310); - message->add_repeated_float (311); - message->add_repeated_double (312); - message->add_repeated_bool (false); - message->add_repeated_string ("315"); - message->add_repeated_bytes ("316"); - - message->add_repeatedgroup ()->set_a(317); - message->add_repeated_nested_message ()->set_bb(318); - message->add_repeated_foreign_message()->set_c(319); - message->add_repeated_import_message ()->set_d(320); - - message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ); - message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ ); - message->add_repeated_import_enum (unittest_import::IMPORT_BAZ); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - "324"); - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - "325"); -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - - // ----------------------------------------------------------------- - - message->set_default_int32 (401); - message->set_default_int64 (402); - message->set_default_uint32 (403); - message->set_default_uint64 (404); - message->set_default_sint32 (405); - message->set_default_sint64 (406); - message->set_default_fixed32 (407); - message->set_default_fixed64 (408); - message->set_default_sfixed32(409); - message->set_default_sfixed64(410); - message->set_default_float (411); - message->set_default_double (412); - message->set_default_bool (false); - message->set_default_string ("415"); - message->set_default_bytes ("416"); - - message->set_default_nested_enum (unittest::TestAllTypes::FOO); - message->set_default_foreign_enum(unittest::FOREIGN_FOO ); - message->set_default_import_enum (unittest_import::IMPORT_FOO); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("default_string_piece"), - "424"); - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("default_cord"), - "425"); -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) { - message->set_repeated_int32 (1, 501); - message->set_repeated_int64 (1, 502); - message->set_repeated_uint32 (1, 503); - message->set_repeated_uint64 (1, 504); - message->set_repeated_sint32 (1, 505); - message->set_repeated_sint64 (1, 506); - message->set_repeated_fixed32 (1, 507); - message->set_repeated_fixed64 (1, 508); - message->set_repeated_sfixed32(1, 509); - message->set_repeated_sfixed64(1, 510); - message->set_repeated_float (1, 511); - message->set_repeated_double (1, 512); - message->set_repeated_bool (1, true); - message->set_repeated_string (1, "515"); - message->set_repeated_bytes (1, "516"); - - message->mutable_repeatedgroup (1)->set_a(517); - message->mutable_repeated_nested_message (1)->set_bb(518); - message->mutable_repeated_foreign_message(1)->set_c(519); - message->mutable_repeated_import_message (1)->set_d(520); - - message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO); - message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO ); - message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - message->GetReflection()->SetRepeatedString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - 1, "524"); - message->GetReflection()->SetRepeatedString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - 1, "525"); -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) { - EXPECT_TRUE(message.has_optional_int32 ()); - EXPECT_TRUE(message.has_optional_int64 ()); - EXPECT_TRUE(message.has_optional_uint32 ()); - EXPECT_TRUE(message.has_optional_uint64 ()); - EXPECT_TRUE(message.has_optional_sint32 ()); - EXPECT_TRUE(message.has_optional_sint64 ()); - EXPECT_TRUE(message.has_optional_fixed32 ()); - EXPECT_TRUE(message.has_optional_fixed64 ()); - EXPECT_TRUE(message.has_optional_sfixed32()); - EXPECT_TRUE(message.has_optional_sfixed64()); - EXPECT_TRUE(message.has_optional_float ()); - EXPECT_TRUE(message.has_optional_double ()); - EXPECT_TRUE(message.has_optional_bool ()); - EXPECT_TRUE(message.has_optional_string ()); - EXPECT_TRUE(message.has_optional_bytes ()); - - EXPECT_TRUE(message.has_optionalgroup ()); - EXPECT_TRUE(message.has_optional_nested_message ()); - EXPECT_TRUE(message.has_optional_foreign_message()); - EXPECT_TRUE(message.has_optional_import_message ()); - - EXPECT_TRUE(message.optionalgroup ().has_a()); - EXPECT_TRUE(message.optional_nested_message ().has_bb()); - EXPECT_TRUE(message.optional_foreign_message().has_c()); - EXPECT_TRUE(message.optional_import_message ().has_d()); - - EXPECT_TRUE(message.has_optional_nested_enum ()); - EXPECT_TRUE(message.has_optional_foreign_enum()); - EXPECT_TRUE(message.has_optional_import_enum ()); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - EXPECT_TRUE(message.has_optional_string_piece()); - EXPECT_TRUE(message.has_optional_cord()); -#endif - - EXPECT_EQ(101 , message.optional_int32 ()); - EXPECT_EQ(102 , message.optional_int64 ()); - EXPECT_EQ(103 , message.optional_uint32 ()); - EXPECT_EQ(104 , message.optional_uint64 ()); - EXPECT_EQ(105 , message.optional_sint32 ()); - EXPECT_EQ(106 , message.optional_sint64 ()); - EXPECT_EQ(107 , message.optional_fixed32 ()); - EXPECT_EQ(108 , message.optional_fixed64 ()); - EXPECT_EQ(109 , message.optional_sfixed32()); - EXPECT_EQ(110 , message.optional_sfixed64()); - EXPECT_EQ(111 , message.optional_float ()); - EXPECT_EQ(112 , message.optional_double ()); - EXPECT_EQ(true , message.optional_bool ()); - EXPECT_EQ("115", message.optional_string ()); - EXPECT_EQ("116", message.optional_bytes ()); - - EXPECT_EQ(117, message.optionalgroup ().a()); - EXPECT_EQ(118, message.optional_nested_message ().bb()); - EXPECT_EQ(119, message.optional_foreign_message().c()); - EXPECT_EQ(120, message.optional_import_message ().d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.optional_import_enum ()); - - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - ASSERT_EQ(2, message.repeated_string_piece_size()); - ASSERT_EQ(2, message.repeated_cord_size()); -#endif - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); - - EXPECT_EQ(301 , message.repeated_int32 (1)); - EXPECT_EQ(302 , message.repeated_int64 (1)); - EXPECT_EQ(303 , message.repeated_uint32 (1)); - EXPECT_EQ(304 , message.repeated_uint64 (1)); - EXPECT_EQ(305 , message.repeated_sint32 (1)); - EXPECT_EQ(306 , message.repeated_sint64 (1)); - EXPECT_EQ(307 , message.repeated_fixed32 (1)); - EXPECT_EQ(308 , message.repeated_fixed64 (1)); - EXPECT_EQ(309 , message.repeated_sfixed32(1)); - EXPECT_EQ(310 , message.repeated_sfixed64(1)); - EXPECT_EQ(311 , message.repeated_float (1)); - EXPECT_EQ(312 , message.repeated_double (1)); - EXPECT_EQ(false, message.repeated_bool (1)); - EXPECT_EQ("315", message.repeated_string (1)); - EXPECT_EQ("316", message.repeated_bytes (1)); - - EXPECT_EQ(317, message.repeatedgroup (1).a()); - EXPECT_EQ(318, message.repeated_nested_message (1).bb()); - EXPECT_EQ(319, message.repeated_foreign_message(1).c()); - EXPECT_EQ(320, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (1)); - - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.has_default_int32 ()); - EXPECT_TRUE(message.has_default_int64 ()); - EXPECT_TRUE(message.has_default_uint32 ()); - EXPECT_TRUE(message.has_default_uint64 ()); - EXPECT_TRUE(message.has_default_sint32 ()); - EXPECT_TRUE(message.has_default_sint64 ()); - EXPECT_TRUE(message.has_default_fixed32 ()); - EXPECT_TRUE(message.has_default_fixed64 ()); - EXPECT_TRUE(message.has_default_sfixed32()); - EXPECT_TRUE(message.has_default_sfixed64()); - EXPECT_TRUE(message.has_default_float ()); - EXPECT_TRUE(message.has_default_double ()); - EXPECT_TRUE(message.has_default_bool ()); - EXPECT_TRUE(message.has_default_string ()); - EXPECT_TRUE(message.has_default_bytes ()); - - EXPECT_TRUE(message.has_default_nested_enum ()); - EXPECT_TRUE(message.has_default_foreign_enum()); - EXPECT_TRUE(message.has_default_import_enum ()); - - - EXPECT_EQ(401 , message.default_int32 ()); - EXPECT_EQ(402 , message.default_int64 ()); - EXPECT_EQ(403 , message.default_uint32 ()); - EXPECT_EQ(404 , message.default_uint64 ()); - EXPECT_EQ(405 , message.default_sint32 ()); - EXPECT_EQ(406 , message.default_sint64 ()); - EXPECT_EQ(407 , message.default_fixed32 ()); - EXPECT_EQ(408 , message.default_fixed64 ()); - EXPECT_EQ(409 , message.default_sfixed32()); - EXPECT_EQ(410 , message.default_sfixed64()); - EXPECT_EQ(411 , message.default_float ()); - EXPECT_EQ(412 , message.default_double ()); - EXPECT_EQ(false, message.default_bool ()); - EXPECT_EQ("415", message.default_string ()); - EXPECT_EQ("416", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_FOO , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectClear(const unittest::TestAllTypes& message) { - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.has_optional_int32 ()); - EXPECT_FALSE(message.has_optional_int64 ()); - EXPECT_FALSE(message.has_optional_uint32 ()); - EXPECT_FALSE(message.has_optional_uint64 ()); - EXPECT_FALSE(message.has_optional_sint32 ()); - EXPECT_FALSE(message.has_optional_sint64 ()); - EXPECT_FALSE(message.has_optional_fixed32 ()); - EXPECT_FALSE(message.has_optional_fixed64 ()); - EXPECT_FALSE(message.has_optional_sfixed32()); - EXPECT_FALSE(message.has_optional_sfixed64()); - EXPECT_FALSE(message.has_optional_float ()); - EXPECT_FALSE(message.has_optional_double ()); - EXPECT_FALSE(message.has_optional_bool ()); - EXPECT_FALSE(message.has_optional_string ()); - EXPECT_FALSE(message.has_optional_bytes ()); - - EXPECT_FALSE(message.has_optionalgroup ()); - EXPECT_FALSE(message.has_optional_nested_message ()); - EXPECT_FALSE(message.has_optional_foreign_message()); - EXPECT_FALSE(message.has_optional_import_message ()); - - EXPECT_FALSE(message.has_optional_nested_enum ()); - EXPECT_FALSE(message.has_optional_foreign_enum()); - EXPECT_FALSE(message.has_optional_import_enum ()); - - EXPECT_FALSE(message.has_optional_string_piece()); - EXPECT_FALSE(message.has_optional_cord()); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.optional_int32 ()); - EXPECT_EQ(0 , message.optional_int64 ()); - EXPECT_EQ(0 , message.optional_uint32 ()); - EXPECT_EQ(0 , message.optional_uint64 ()); - EXPECT_EQ(0 , message.optional_sint32 ()); - EXPECT_EQ(0 , message.optional_sint64 ()); - EXPECT_EQ(0 , message.optional_fixed32 ()); - EXPECT_EQ(0 , message.optional_fixed64 ()); - EXPECT_EQ(0 , message.optional_sfixed32()); - EXPECT_EQ(0 , message.optional_sfixed64()); - EXPECT_EQ(0 , message.optional_float ()); - EXPECT_EQ(0 , message.optional_double ()); - EXPECT_EQ(false, message.optional_bool ()); - EXPECT_EQ("" , message.optional_string ()); - EXPECT_EQ("" , message.optional_bytes ()); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.optionalgroup ().has_a()); - EXPECT_FALSE(message.optional_nested_message ().has_bb()); - EXPECT_FALSE(message.optional_foreign_message().has_c()); - EXPECT_FALSE(message.optional_import_message ().has_d()); - - EXPECT_EQ(0, message.optionalgroup ().a()); - EXPECT_EQ(0, message.optional_nested_message ().bb()); - EXPECT_EQ(0, message.optional_foreign_message().c()); - EXPECT_EQ(0, message.optional_import_message ().d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_FOO , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.optional_import_enum ()); - - - // Repeated fields are empty. - EXPECT_EQ(0, message.repeated_int32_size ()); - EXPECT_EQ(0, message.repeated_int64_size ()); - EXPECT_EQ(0, message.repeated_uint32_size ()); - EXPECT_EQ(0, message.repeated_uint64_size ()); - EXPECT_EQ(0, message.repeated_sint32_size ()); - EXPECT_EQ(0, message.repeated_sint64_size ()); - EXPECT_EQ(0, message.repeated_fixed32_size ()); - EXPECT_EQ(0, message.repeated_fixed64_size ()); - EXPECT_EQ(0, message.repeated_sfixed32_size()); - EXPECT_EQ(0, message.repeated_sfixed64_size()); - EXPECT_EQ(0, message.repeated_float_size ()); - EXPECT_EQ(0, message.repeated_double_size ()); - EXPECT_EQ(0, message.repeated_bool_size ()); - EXPECT_EQ(0, message.repeated_string_size ()); - EXPECT_EQ(0, message.repeated_bytes_size ()); - - EXPECT_EQ(0, message.repeatedgroup_size ()); - EXPECT_EQ(0, message.repeated_nested_message_size ()); - EXPECT_EQ(0, message.repeated_foreign_message_size()); - EXPECT_EQ(0, message.repeated_import_message_size ()); - EXPECT_EQ(0, message.repeated_nested_enum_size ()); - EXPECT_EQ(0, message.repeated_foreign_enum_size ()); - EXPECT_EQ(0, message.repeated_import_enum_size ()); - - EXPECT_EQ(0, message.repeated_string_piece_size()); - EXPECT_EQ(0, message.repeated_cord_size()); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.has_default_int32 ()); - EXPECT_FALSE(message.has_default_int64 ()); - EXPECT_FALSE(message.has_default_uint32 ()); - EXPECT_FALSE(message.has_default_uint64 ()); - EXPECT_FALSE(message.has_default_sint32 ()); - EXPECT_FALSE(message.has_default_sint64 ()); - EXPECT_FALSE(message.has_default_fixed32 ()); - EXPECT_FALSE(message.has_default_fixed64 ()); - EXPECT_FALSE(message.has_default_sfixed32()); - EXPECT_FALSE(message.has_default_sfixed64()); - EXPECT_FALSE(message.has_default_float ()); - EXPECT_FALSE(message.has_default_double ()); - EXPECT_FALSE(message.has_default_bool ()); - EXPECT_FALSE(message.has_default_string ()); - EXPECT_FALSE(message.has_default_bytes ()); - - EXPECT_FALSE(message.has_default_nested_enum ()); - EXPECT_FALSE(message.has_default_foreign_enum()); - EXPECT_FALSE(message.has_default_import_enum ()); - - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.default_int32 ()); - EXPECT_EQ( 42 , message.default_int64 ()); - EXPECT_EQ( 43 , message.default_uint32 ()); - EXPECT_EQ( 44 , message.default_uint64 ()); - EXPECT_EQ(-45 , message.default_sint32 ()); - EXPECT_EQ( 46 , message.default_sint64 ()); - EXPECT_EQ( 47 , message.default_fixed32 ()); - EXPECT_EQ( 48 , message.default_fixed64 ()); - EXPECT_EQ( 49 , message.default_sfixed32()); - EXPECT_EQ(-50 , message.default_sfixed64()); - EXPECT_EQ( 51.5 , message.default_float ()); - EXPECT_EQ( 52e3 , message.default_double ()); - EXPECT_EQ(true , message.default_bool ()); - EXPECT_EQ("hello", message.default_string ()); - EXPECT_EQ("world", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_BAR , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectRepeatedFieldsModified( - const unittest::TestAllTypes& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - ASSERT_EQ(2, message.repeated_string_piece_size()); - ASSERT_EQ(2, message.repeated_cord_size()); -#endif - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); - - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.repeated_int32 (1)); - EXPECT_EQ(502 , message.repeated_int64 (1)); - EXPECT_EQ(503 , message.repeated_uint32 (1)); - EXPECT_EQ(504 , message.repeated_uint64 (1)); - EXPECT_EQ(505 , message.repeated_sint32 (1)); - EXPECT_EQ(506 , message.repeated_sint64 (1)); - EXPECT_EQ(507 , message.repeated_fixed32 (1)); - EXPECT_EQ(508 , message.repeated_fixed64 (1)); - EXPECT_EQ(509 , message.repeated_sfixed32(1)); - EXPECT_EQ(510 , message.repeated_sfixed64(1)); - EXPECT_EQ(511 , message.repeated_float (1)); - EXPECT_EQ(512 , message.repeated_double (1)); - EXPECT_EQ(true , message.repeated_bool (1)); - EXPECT_EQ("515", message.repeated_string (1)); - EXPECT_EQ("516", message.repeated_bytes (1)); - - EXPECT_EQ(517, message.repeatedgroup (1).a()); - EXPECT_EQ(518, message.repeated_nested_message (1).bb()); - EXPECT_EQ(519, message.repeated_foreign_message(1).c()); - EXPECT_EQ(520, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_FOO , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.repeated_import_enum (1)); - -} - -// ------------------------------------------------------------------- - -void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) { - message->add_packed_int32 (601); - message->add_packed_int64 (602); - message->add_packed_uint32 (603); - message->add_packed_uint64 (604); - message->add_packed_sint32 (605); - message->add_packed_sint64 (606); - message->add_packed_fixed32 (607); - message->add_packed_fixed64 (608); - message->add_packed_sfixed32(609); - message->add_packed_sfixed64(610); - message->add_packed_float (611); - message->add_packed_double (612); - message->add_packed_bool (true); - message->add_packed_enum (unittest::FOREIGN_BAR); - // add a second one of each field - message->add_packed_int32 (701); - message->add_packed_int64 (702); - message->add_packed_uint32 (703); - message->add_packed_uint64 (704); - message->add_packed_sint32 (705); - message->add_packed_sint64 (706); - message->add_packed_fixed32 (707); - message->add_packed_fixed64 (708); - message->add_packed_sfixed32(709); - message->add_packed_sfixed64(710); - message->add_packed_float (711); - message->add_packed_double (712); - message->add_packed_bool (false); - message->add_packed_enum (unittest::FOREIGN_BAZ); -} - -void TestUtil::SetUnpackedFields(unittest::TestUnpackedTypes* message) { - // The values applied here must match those of SetPackedFields. - - message->add_unpacked_int32 (601); - message->add_unpacked_int64 (602); - message->add_unpacked_uint32 (603); - message->add_unpacked_uint64 (604); - message->add_unpacked_sint32 (605); - message->add_unpacked_sint64 (606); - message->add_unpacked_fixed32 (607); - message->add_unpacked_fixed64 (608); - message->add_unpacked_sfixed32(609); - message->add_unpacked_sfixed64(610); - message->add_unpacked_float (611); - message->add_unpacked_double (612); - message->add_unpacked_bool (true); - message->add_unpacked_enum (unittest::FOREIGN_BAR); - // add a second one of each field - message->add_unpacked_int32 (701); - message->add_unpacked_int64 (702); - message->add_unpacked_uint32 (703); - message->add_unpacked_uint64 (704); - message->add_unpacked_sint32 (705); - message->add_unpacked_sint64 (706); - message->add_unpacked_fixed32 (707); - message->add_unpacked_fixed64 (708); - message->add_unpacked_sfixed32(709); - message->add_unpacked_sfixed64(710); - message->add_unpacked_float (711); - message->add_unpacked_double (712); - message->add_unpacked_bool (false); - message->add_unpacked_enum (unittest::FOREIGN_BAZ); -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) { - message->set_packed_int32 (1, 801); - message->set_packed_int64 (1, 802); - message->set_packed_uint32 (1, 803); - message->set_packed_uint64 (1, 804); - message->set_packed_sint32 (1, 805); - message->set_packed_sint64 (1, 806); - message->set_packed_fixed32 (1, 807); - message->set_packed_fixed64 (1, 808); - message->set_packed_sfixed32(1, 809); - message->set_packed_sfixed64(1, 810); - message->set_packed_float (1, 811); - message->set_packed_double (1, 812); - message->set_packed_bool (1, true); - message->set_packed_enum (1, unittest::FOREIGN_FOO); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) { - ASSERT_EQ(2, message.packed_int32_size ()); - ASSERT_EQ(2, message.packed_int64_size ()); - ASSERT_EQ(2, message.packed_uint32_size ()); - ASSERT_EQ(2, message.packed_uint64_size ()); - ASSERT_EQ(2, message.packed_sint32_size ()); - ASSERT_EQ(2, message.packed_sint64_size ()); - ASSERT_EQ(2, message.packed_fixed32_size ()); - ASSERT_EQ(2, message.packed_fixed64_size ()); - ASSERT_EQ(2, message.packed_sfixed32_size()); - ASSERT_EQ(2, message.packed_sfixed64_size()); - ASSERT_EQ(2, message.packed_float_size ()); - ASSERT_EQ(2, message.packed_double_size ()); - ASSERT_EQ(2, message.packed_bool_size ()); - ASSERT_EQ(2, message.packed_enum_size ()); - - EXPECT_EQ(601 , message.packed_int32 (0)); - EXPECT_EQ(602 , message.packed_int64 (0)); - EXPECT_EQ(603 , message.packed_uint32 (0)); - EXPECT_EQ(604 , message.packed_uint64 (0)); - EXPECT_EQ(605 , message.packed_sint32 (0)); - EXPECT_EQ(606 , message.packed_sint64 (0)); - EXPECT_EQ(607 , message.packed_fixed32 (0)); - EXPECT_EQ(608 , message.packed_fixed64 (0)); - EXPECT_EQ(609 , message.packed_sfixed32(0)); - EXPECT_EQ(610 , message.packed_sfixed64(0)); - EXPECT_EQ(611 , message.packed_float (0)); - EXPECT_EQ(612 , message.packed_double (0)); - EXPECT_EQ(true , message.packed_bool (0)); - EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0)); - - EXPECT_EQ(701 , message.packed_int32 (1)); - EXPECT_EQ(702 , message.packed_int64 (1)); - EXPECT_EQ(703 , message.packed_uint32 (1)); - EXPECT_EQ(704 , message.packed_uint64 (1)); - EXPECT_EQ(705 , message.packed_sint32 (1)); - EXPECT_EQ(706 , message.packed_sint64 (1)); - EXPECT_EQ(707 , message.packed_fixed32 (1)); - EXPECT_EQ(708 , message.packed_fixed64 (1)); - EXPECT_EQ(709 , message.packed_sfixed32(1)); - EXPECT_EQ(710 , message.packed_sfixed64(1)); - EXPECT_EQ(711 , message.packed_float (1)); - EXPECT_EQ(712 , message.packed_double (1)); - EXPECT_EQ(false, message.packed_bool (1)); - EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1)); -} - -void TestUtil::ExpectUnpackedFieldsSet( - const unittest::TestUnpackedTypes& message) { - // The values expected here must match those of ExpectPackedFieldsSet. - - ASSERT_EQ(2, message.unpacked_int32_size ()); - ASSERT_EQ(2, message.unpacked_int64_size ()); - ASSERT_EQ(2, message.unpacked_uint32_size ()); - ASSERT_EQ(2, message.unpacked_uint64_size ()); - ASSERT_EQ(2, message.unpacked_sint32_size ()); - ASSERT_EQ(2, message.unpacked_sint64_size ()); - ASSERT_EQ(2, message.unpacked_fixed32_size ()); - ASSERT_EQ(2, message.unpacked_fixed64_size ()); - ASSERT_EQ(2, message.unpacked_sfixed32_size()); - ASSERT_EQ(2, message.unpacked_sfixed64_size()); - ASSERT_EQ(2, message.unpacked_float_size ()); - ASSERT_EQ(2, message.unpacked_double_size ()); - ASSERT_EQ(2, message.unpacked_bool_size ()); - ASSERT_EQ(2, message.unpacked_enum_size ()); - - EXPECT_EQ(601 , message.unpacked_int32 (0)); - EXPECT_EQ(602 , message.unpacked_int64 (0)); - EXPECT_EQ(603 , message.unpacked_uint32 (0)); - EXPECT_EQ(604 , message.unpacked_uint64 (0)); - EXPECT_EQ(605 , message.unpacked_sint32 (0)); - EXPECT_EQ(606 , message.unpacked_sint64 (0)); - EXPECT_EQ(607 , message.unpacked_fixed32 (0)); - EXPECT_EQ(608 , message.unpacked_fixed64 (0)); - EXPECT_EQ(609 , message.unpacked_sfixed32(0)); - EXPECT_EQ(610 , message.unpacked_sfixed64(0)); - EXPECT_EQ(611 , message.unpacked_float (0)); - EXPECT_EQ(612 , message.unpacked_double (0)); - EXPECT_EQ(true , message.unpacked_bool (0)); - EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0)); - - EXPECT_EQ(701 , message.unpacked_int32 (1)); - EXPECT_EQ(702 , message.unpacked_int64 (1)); - EXPECT_EQ(703 , message.unpacked_uint32 (1)); - EXPECT_EQ(704 , message.unpacked_uint64 (1)); - EXPECT_EQ(705 , message.unpacked_sint32 (1)); - EXPECT_EQ(706 , message.unpacked_sint64 (1)); - EXPECT_EQ(707 , message.unpacked_fixed32 (1)); - EXPECT_EQ(708 , message.unpacked_fixed64 (1)); - EXPECT_EQ(709 , message.unpacked_sfixed32(1)); - EXPECT_EQ(710 , message.unpacked_sfixed64(1)); - EXPECT_EQ(711 , message.unpacked_float (1)); - EXPECT_EQ(712 , message.unpacked_double (1)); - EXPECT_EQ(false, message.unpacked_bool (1)); - EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedClear( - const unittest::TestPackedTypes& message) { - // Packed repeated fields are empty. - EXPECT_EQ(0, message.packed_int32_size ()); - EXPECT_EQ(0, message.packed_int64_size ()); - EXPECT_EQ(0, message.packed_uint32_size ()); - EXPECT_EQ(0, message.packed_uint64_size ()); - EXPECT_EQ(0, message.packed_sint32_size ()); - EXPECT_EQ(0, message.packed_sint64_size ()); - EXPECT_EQ(0, message.packed_fixed32_size ()); - EXPECT_EQ(0, message.packed_fixed64_size ()); - EXPECT_EQ(0, message.packed_sfixed32_size()); - EXPECT_EQ(0, message.packed_sfixed64_size()); - EXPECT_EQ(0, message.packed_float_size ()); - EXPECT_EQ(0, message.packed_double_size ()); - EXPECT_EQ(0, message.packed_bool_size ()); - EXPECT_EQ(0, message.packed_enum_size ()); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedFieldsModified( - const unittest::TestPackedTypes& message) { - // Do the same for packed repeated fields. - ASSERT_EQ(2, message.packed_int32_size ()); - ASSERT_EQ(2, message.packed_int64_size ()); - ASSERT_EQ(2, message.packed_uint32_size ()); - ASSERT_EQ(2, message.packed_uint64_size ()); - ASSERT_EQ(2, message.packed_sint32_size ()); - ASSERT_EQ(2, message.packed_sint64_size ()); - ASSERT_EQ(2, message.packed_fixed32_size ()); - ASSERT_EQ(2, message.packed_fixed64_size ()); - ASSERT_EQ(2, message.packed_sfixed32_size()); - ASSERT_EQ(2, message.packed_sfixed64_size()); - ASSERT_EQ(2, message.packed_float_size ()); - ASSERT_EQ(2, message.packed_double_size ()); - ASSERT_EQ(2, message.packed_bool_size ()); - ASSERT_EQ(2, message.packed_enum_size ()); - - EXPECT_EQ(601 , message.packed_int32 (0)); - EXPECT_EQ(602 , message.packed_int64 (0)); - EXPECT_EQ(603 , message.packed_uint32 (0)); - EXPECT_EQ(604 , message.packed_uint64 (0)); - EXPECT_EQ(605 , message.packed_sint32 (0)); - EXPECT_EQ(606 , message.packed_sint64 (0)); - EXPECT_EQ(607 , message.packed_fixed32 (0)); - EXPECT_EQ(608 , message.packed_fixed64 (0)); - EXPECT_EQ(609 , message.packed_sfixed32(0)); - EXPECT_EQ(610 , message.packed_sfixed64(0)); - EXPECT_EQ(611 , message.packed_float (0)); - EXPECT_EQ(612 , message.packed_double (0)); - EXPECT_EQ(true , message.packed_bool (0)); - EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0)); - // Actually verify the second (modified) elements now. - EXPECT_EQ(801 , message.packed_int32 (1)); - EXPECT_EQ(802 , message.packed_int64 (1)); - EXPECT_EQ(803 , message.packed_uint32 (1)); - EXPECT_EQ(804 , message.packed_uint64 (1)); - EXPECT_EQ(805 , message.packed_sint32 (1)); - EXPECT_EQ(806 , message.packed_sint64 (1)); - EXPECT_EQ(807 , message.packed_fixed32 (1)); - EXPECT_EQ(808 , message.packed_fixed64 (1)); - EXPECT_EQ(809 , message.packed_sfixed32(1)); - EXPECT_EQ(810 , message.packed_sfixed64(1)); - EXPECT_EQ(811 , message.packed_float (1)); - EXPECT_EQ(812 , message.packed_double (1)); - EXPECT_EQ(true , message.packed_bool (1)); - EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_enum(1)); -} - -// =================================================================== -// Extensions -// -// All this code is exactly equivalent to the above code except that it's -// manipulating extension fields instead of normal ones. -// -// I gave up on the 80-char limit here. Sorry. - -void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) { - message->SetExtension(unittest::optional_int32_extension , 101); - message->SetExtension(unittest::optional_int64_extension , 102); - message->SetExtension(unittest::optional_uint32_extension , 103); - message->SetExtension(unittest::optional_uint64_extension , 104); - message->SetExtension(unittest::optional_sint32_extension , 105); - message->SetExtension(unittest::optional_sint64_extension , 106); - message->SetExtension(unittest::optional_fixed32_extension , 107); - message->SetExtension(unittest::optional_fixed64_extension , 108); - message->SetExtension(unittest::optional_sfixed32_extension, 109); - message->SetExtension(unittest::optional_sfixed64_extension, 110); - message->SetExtension(unittest::optional_float_extension , 111); - message->SetExtension(unittest::optional_double_extension , 112); - message->SetExtension(unittest::optional_bool_extension , true); - message->SetExtension(unittest::optional_string_extension , "115"); - message->SetExtension(unittest::optional_bytes_extension , "116"); - - message->MutableExtension(unittest::optionalgroup_extension )->set_a(117); - message->MutableExtension(unittest::optional_nested_message_extension )->set_bb(118); - message->MutableExtension(unittest::optional_foreign_message_extension)->set_c(119); - message->MutableExtension(unittest::optional_import_message_extension )->set_d(120); - - message->SetExtension(unittest::optional_nested_enum_extension , unittest::TestAllTypes::BAZ); - message->SetExtension(unittest::optional_foreign_enum_extension, unittest::FOREIGN_BAZ ); - message->SetExtension(unittest::optional_import_enum_extension , unittest_import::IMPORT_BAZ); - - message->SetExtension(unittest::optional_string_piece_extension, "124"); - message->SetExtension(unittest::optional_cord_extension, "125"); - - // ----------------------------------------------------------------- - - message->AddExtension(unittest::repeated_int32_extension , 201); - message->AddExtension(unittest::repeated_int64_extension , 202); - message->AddExtension(unittest::repeated_uint32_extension , 203); - message->AddExtension(unittest::repeated_uint64_extension , 204); - message->AddExtension(unittest::repeated_sint32_extension , 205); - message->AddExtension(unittest::repeated_sint64_extension , 206); - message->AddExtension(unittest::repeated_fixed32_extension , 207); - message->AddExtension(unittest::repeated_fixed64_extension , 208); - message->AddExtension(unittest::repeated_sfixed32_extension, 209); - message->AddExtension(unittest::repeated_sfixed64_extension, 210); - message->AddExtension(unittest::repeated_float_extension , 211); - message->AddExtension(unittest::repeated_double_extension , 212); - message->AddExtension(unittest::repeated_bool_extension , true); - message->AddExtension(unittest::repeated_string_extension , "215"); - message->AddExtension(unittest::repeated_bytes_extension , "216"); - - message->AddExtension(unittest::repeatedgroup_extension )->set_a(217); - message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218); - message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219); - message->AddExtension(unittest::repeated_import_message_extension )->set_d(220); - - message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR); - message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR ); - message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAR); - - message->AddExtension(unittest::repeated_string_piece_extension, "224"); - message->AddExtension(unittest::repeated_cord_extension, "225"); - - // Add a second one of each field. - message->AddExtension(unittest::repeated_int32_extension , 301); - message->AddExtension(unittest::repeated_int64_extension , 302); - message->AddExtension(unittest::repeated_uint32_extension , 303); - message->AddExtension(unittest::repeated_uint64_extension , 304); - message->AddExtension(unittest::repeated_sint32_extension , 305); - message->AddExtension(unittest::repeated_sint64_extension , 306); - message->AddExtension(unittest::repeated_fixed32_extension , 307); - message->AddExtension(unittest::repeated_fixed64_extension , 308); - message->AddExtension(unittest::repeated_sfixed32_extension, 309); - message->AddExtension(unittest::repeated_sfixed64_extension, 310); - message->AddExtension(unittest::repeated_float_extension , 311); - message->AddExtension(unittest::repeated_double_extension , 312); - message->AddExtension(unittest::repeated_bool_extension , false); - message->AddExtension(unittest::repeated_string_extension , "315"); - message->AddExtension(unittest::repeated_bytes_extension , "316"); - - message->AddExtension(unittest::repeatedgroup_extension )->set_a(317); - message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318); - message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319); - message->AddExtension(unittest::repeated_import_message_extension )->set_d(320); - - message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ); - message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ ); - message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAZ); - - message->AddExtension(unittest::repeated_string_piece_extension, "324"); - message->AddExtension(unittest::repeated_cord_extension, "325"); - - // ----------------------------------------------------------------- - - message->SetExtension(unittest::default_int32_extension , 401); - message->SetExtension(unittest::default_int64_extension , 402); - message->SetExtension(unittest::default_uint32_extension , 403); - message->SetExtension(unittest::default_uint64_extension , 404); - message->SetExtension(unittest::default_sint32_extension , 405); - message->SetExtension(unittest::default_sint64_extension , 406); - message->SetExtension(unittest::default_fixed32_extension , 407); - message->SetExtension(unittest::default_fixed64_extension , 408); - message->SetExtension(unittest::default_sfixed32_extension, 409); - message->SetExtension(unittest::default_sfixed64_extension, 410); - message->SetExtension(unittest::default_float_extension , 411); - message->SetExtension(unittest::default_double_extension , 412); - message->SetExtension(unittest::default_bool_extension , false); - message->SetExtension(unittest::default_string_extension , "415"); - message->SetExtension(unittest::default_bytes_extension , "416"); - - message->SetExtension(unittest::default_nested_enum_extension , unittest::TestAllTypes::FOO); - message->SetExtension(unittest::default_foreign_enum_extension, unittest::FOREIGN_FOO ); - message->SetExtension(unittest::default_import_enum_extension , unittest_import::IMPORT_FOO); - - message->SetExtension(unittest::default_string_piece_extension, "424"); - message->SetExtension(unittest::default_cord_extension, "425"); -} - -// ------------------------------------------------------------------- - -void TestUtil::SetAllFieldsAndExtensions( - unittest::TestFieldOrderings* message) { - GOOGLE_CHECK(message); - message->set_my_int(1); - message->set_my_string("foo"); - message->set_my_float(1.0); - message->SetExtension(unittest::my_extension_int, 23); - message->SetExtension(unittest::my_extension_string, "bar"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) { - message->SetExtension(unittest::repeated_int32_extension , 1, 501); - message->SetExtension(unittest::repeated_int64_extension , 1, 502); - message->SetExtension(unittest::repeated_uint32_extension , 1, 503); - message->SetExtension(unittest::repeated_uint64_extension , 1, 504); - message->SetExtension(unittest::repeated_sint32_extension , 1, 505); - message->SetExtension(unittest::repeated_sint64_extension , 1, 506); - message->SetExtension(unittest::repeated_fixed32_extension , 1, 507); - message->SetExtension(unittest::repeated_fixed64_extension , 1, 508); - message->SetExtension(unittest::repeated_sfixed32_extension, 1, 509); - message->SetExtension(unittest::repeated_sfixed64_extension, 1, 510); - message->SetExtension(unittest::repeated_float_extension , 1, 511); - message->SetExtension(unittest::repeated_double_extension , 1, 512); - message->SetExtension(unittest::repeated_bool_extension , 1, true); - message->SetExtension(unittest::repeated_string_extension , 1, "515"); - message->SetExtension(unittest::repeated_bytes_extension , 1, "516"); - - message->MutableExtension(unittest::repeatedgroup_extension , 1)->set_a(517); - message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518); - message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519); - message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520); - - message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO); - message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO ); - message->SetExtension(unittest::repeated_import_enum_extension , 1, unittest_import::IMPORT_FOO); - - message->SetExtension(unittest::repeated_string_piece_extension, 1, "524"); - message->SetExtension(unittest::repeated_cord_extension, 1, "525"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllExtensionsSet( - const unittest::TestAllExtensions& message) { - EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension )); - - EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); - EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); - EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension).has_c()); - EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); - - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::optional_string_piece_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_cord_extension)); - - EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension )); - EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension )); - EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension )); - EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension )); - EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension )); - EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension )); - EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension )); - EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension )); - EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension)); - EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension)); - EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension )); - EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension )); - EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension )); - EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension )); - EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension )); - - EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension ).a()); - EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension ).bb()); - EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension).c()); - EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension ).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::optional_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::optional_import_enum_extension )); - - EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension)); - EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension)); - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); - - EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 1)); - EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 1)); - EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 1)); - EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 1)); - EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 1)); - EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 1)); - EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); - EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); - EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); - EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); - EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 1)); - EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 1)); - EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 1)); - EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 1)); - EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 1)); - - EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); - EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); - EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); - EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 1)); - - EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 1)); - EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 1)); - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_float_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_double_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_string_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::default_string_piece_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_cord_extension)); - - EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension )); - EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension )); - EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension )); - EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension )); - EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension )); - EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension )); - EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension )); - EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension )); - EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension)); - EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension)); - EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension )); - EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension )); - EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension )); - EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension )); - EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension )); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::default_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::default_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::default_import_enum_extension )); - - EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension)); - EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectExtensionsClear( - const unittest::TestAllExtensions& message) { - string serialized; - ASSERT_TRUE(message.SerializeToString(&serialized)); - EXPECT_EQ("", serialized); - EXPECT_EQ(0, message.ByteSize()); - - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optional_string_piece_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_cord_extension)); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension )); - EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension )); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); - EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); - EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension).has_c()); - EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); - - EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension).c()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::optional_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::optional_import_enum_extension )); - - EXPECT_EQ("", message.GetExtension(unittest::optional_string_piece_extension)); - EXPECT_EQ("", message.GetExtension(unittest::optional_cord_extension)); - - // Repeated fields are empty. - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension )); - - EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_piece_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_cord_extension)); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_float_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_double_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_string_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::default_string_piece_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_cord_extension)); - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension )); - EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension )); - EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension )); - EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension )); - EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension )); - EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension )); - EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension )); - EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension )); - EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension)); - EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension)); - EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension )); - EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension )); - EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension )); - EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension )); - EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension )); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::default_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::default_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::default_import_enum_extension )); - - EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension)); - EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensions& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension , 1)); - EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension , 1)); - EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension , 1)); - EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension , 1)); - EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension , 1)); - EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension , 1)); - EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); - EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); - EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); - EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); - EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension , 1)); - EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1)); - EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension , 1)); - EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension , 1)); - - EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); - EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); - EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); - EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::repeated_import_enum_extension , 1)); - - EXPECT_EQ("524", message.GetExtension(unittest::repeated_string_piece_extension, 1)); - EXPECT_EQ("525", message.GetExtension(unittest::repeated_cord_extension, 1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::SetPackedExtensions(unittest::TestPackedExtensions* message) { - message->AddExtension(unittest::packed_int32_extension , 601); - message->AddExtension(unittest::packed_int64_extension , 602); - message->AddExtension(unittest::packed_uint32_extension , 603); - message->AddExtension(unittest::packed_uint64_extension , 604); - message->AddExtension(unittest::packed_sint32_extension , 605); - message->AddExtension(unittest::packed_sint64_extension , 606); - message->AddExtension(unittest::packed_fixed32_extension , 607); - message->AddExtension(unittest::packed_fixed64_extension , 608); - message->AddExtension(unittest::packed_sfixed32_extension, 609); - message->AddExtension(unittest::packed_sfixed64_extension, 610); - message->AddExtension(unittest::packed_float_extension , 611); - message->AddExtension(unittest::packed_double_extension , 612); - message->AddExtension(unittest::packed_bool_extension , true); - message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAR); - // add a second one of each field - message->AddExtension(unittest::packed_int32_extension , 701); - message->AddExtension(unittest::packed_int64_extension , 702); - message->AddExtension(unittest::packed_uint32_extension , 703); - message->AddExtension(unittest::packed_uint64_extension , 704); - message->AddExtension(unittest::packed_sint32_extension , 705); - message->AddExtension(unittest::packed_sint64_extension , 706); - message->AddExtension(unittest::packed_fixed32_extension , 707); - message->AddExtension(unittest::packed_fixed64_extension , 708); - message->AddExtension(unittest::packed_sfixed32_extension, 709); - message->AddExtension(unittest::packed_sfixed64_extension, 710); - message->AddExtension(unittest::packed_float_extension , 711); - message->AddExtension(unittest::packed_double_extension , 712); - message->AddExtension(unittest::packed_bool_extension , false); - message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAZ); -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyPackedExtensions(unittest::TestPackedExtensions* message) { - message->SetExtension(unittest::packed_int32_extension , 1, 801); - message->SetExtension(unittest::packed_int64_extension , 1, 802); - message->SetExtension(unittest::packed_uint32_extension , 1, 803); - message->SetExtension(unittest::packed_uint64_extension , 1, 804); - message->SetExtension(unittest::packed_sint32_extension , 1, 805); - message->SetExtension(unittest::packed_sint64_extension , 1, 806); - message->SetExtension(unittest::packed_fixed32_extension , 1, 807); - message->SetExtension(unittest::packed_fixed64_extension , 1, 808); - message->SetExtension(unittest::packed_sfixed32_extension, 1, 809); - message->SetExtension(unittest::packed_sfixed64_extension, 1, 810); - message->SetExtension(unittest::packed_float_extension , 1, 811); - message->SetExtension(unittest::packed_double_extension , 1, 812); - message->SetExtension(unittest::packed_bool_extension , 1, true); - message->SetExtension(unittest::packed_enum_extension , 1, - unittest::FOREIGN_FOO); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedExtensionsSet( - const unittest::TestPackedExtensions& message) { - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension )); - - EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0)); - EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0)); - EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0)); - EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0)); - EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0)); - EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0)); - EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0)); - EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0)); - EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0)); - EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0)); - EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0)); - EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR, - message.GetExtension(unittest::packed_enum_extension, 0)); - EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension , 1)); - EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension , 1)); - EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension , 1)); - EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension , 1)); - EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension , 1)); - EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension , 1)); - EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension , 1)); - EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension , 1)); - EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension, 1)); - EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension, 1)); - EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension , 1)); - EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension , 1)); - EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_BAZ, - message.GetExtension(unittest::packed_enum_extension, 1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedExtensionsClear( - const unittest::TestPackedExtensions& message) { - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension )); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectPackedExtensionsModified( - const unittest::TestPackedExtensions& message) { - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension )); - EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0)); - EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0)); - EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0)); - EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0)); - EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0)); - EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0)); - EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0)); - EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0)); - EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0)); - EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0)); - EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0)); - EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR, - message.GetExtension(unittest::packed_enum_extension, 0)); - - // Actually verify the second (modified) elements now. - EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension , 1)); - EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension , 1)); - EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension , 1)); - EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension , 1)); - EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension , 1)); - EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension , 1)); - EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension , 1)); - EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension , 1)); - EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension, 1)); - EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension, 1)); - EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension , 1)); - EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_FOO, - message.GetExtension(unittest::packed_enum_extension, 1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) { - // We set each field individually, serialize separately, and concatenate all - // the strings in canonical order to determine the expected serialization. - string expected; - unittest::TestFieldOrderings message; - message.set_my_int(1); // Field 1. - message.AppendToString(&expected); - message.Clear(); - message.SetExtension(unittest::my_extension_int, 23); // Field 5. - message.AppendToString(&expected); - message.Clear(); - message.set_my_string("foo"); // Field 11. - message.AppendToString(&expected); - message.Clear(); - message.SetExtension(unittest::my_extension_string, "bar"); // Field 50. - message.AppendToString(&expected); - message.Clear(); - message.set_my_float(1.0); // Field 101. - message.AppendToString(&expected); - message.Clear(); - - // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout. - EXPECT_TRUE(serialized == expected); -} - -void TestUtil::ExpectLastRepeatedsRemoved( - const unittest::TestAllTypes& message) { - ASSERT_EQ(1, message.repeated_int32_size ()); - ASSERT_EQ(1, message.repeated_int64_size ()); - ASSERT_EQ(1, message.repeated_uint32_size ()); - ASSERT_EQ(1, message.repeated_uint64_size ()); - ASSERT_EQ(1, message.repeated_sint32_size ()); - ASSERT_EQ(1, message.repeated_sint64_size ()); - ASSERT_EQ(1, message.repeated_fixed32_size ()); - ASSERT_EQ(1, message.repeated_fixed64_size ()); - ASSERT_EQ(1, message.repeated_sfixed32_size()); - ASSERT_EQ(1, message.repeated_sfixed64_size()); - ASSERT_EQ(1, message.repeated_float_size ()); - ASSERT_EQ(1, message.repeated_double_size ()); - ASSERT_EQ(1, message.repeated_bool_size ()); - ASSERT_EQ(1, message.repeated_string_size ()); - ASSERT_EQ(1, message.repeated_bytes_size ()); - - ASSERT_EQ(1, message.repeatedgroup_size ()); - ASSERT_EQ(1, message.repeated_nested_message_size ()); - ASSERT_EQ(1, message.repeated_foreign_message_size()); - ASSERT_EQ(1, message.repeated_import_message_size ()); - ASSERT_EQ(1, message.repeated_nested_enum_size ()); - ASSERT_EQ(1, message.repeated_foreign_enum_size ()); - ASSERT_EQ(1, message.repeated_import_enum_size ()); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - ASSERT_EQ(1, message.repeated_string_piece_size()); - ASSERT_EQ(1, message.repeated_cord_size()); -#endif - - // Test that the remaining element is the correct one. - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); -} - -void TestUtil::ExpectLastRepeatedExtensionsRemoved( - const unittest::TestAllExtensions& message) { - - // Test that one element was removed. - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_cord_extension)); - - // Test that the remaining element is the correct one. - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); -} - -void TestUtil::ExpectRepeatedsSwapped( - const unittest::TestAllTypes& message) { - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - ASSERT_EQ(2, message.repeated_string_piece_size()); - ASSERT_EQ(2, message.repeated_cord_size()); -#endif - - // Test that the first element and second element are flipped. - EXPECT_EQ(201 , message.repeated_int32 (1)); - EXPECT_EQ(202 , message.repeated_int64 (1)); - EXPECT_EQ(203 , message.repeated_uint32 (1)); - EXPECT_EQ(204 , message.repeated_uint64 (1)); - EXPECT_EQ(205 , message.repeated_sint32 (1)); - EXPECT_EQ(206 , message.repeated_sint64 (1)); - EXPECT_EQ(207 , message.repeated_fixed32 (1)); - EXPECT_EQ(208 , message.repeated_fixed64 (1)); - EXPECT_EQ(209 , message.repeated_sfixed32(1)); - EXPECT_EQ(210 , message.repeated_sfixed64(1)); - EXPECT_EQ(211 , message.repeated_float (1)); - EXPECT_EQ(212 , message.repeated_double (1)); - EXPECT_EQ(true , message.repeated_bool (1)); - EXPECT_EQ("215", message.repeated_string (1)); - EXPECT_EQ("216", message.repeated_bytes (1)); - - EXPECT_EQ(217, message.repeatedgroup (1).a()); - EXPECT_EQ(218, message.repeated_nested_message (1).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(1).c()); - EXPECT_EQ(220, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (1)); - - EXPECT_EQ(301 , message.repeated_int32 (0)); - EXPECT_EQ(302 , message.repeated_int64 (0)); - EXPECT_EQ(303 , message.repeated_uint32 (0)); - EXPECT_EQ(304 , message.repeated_uint64 (0)); - EXPECT_EQ(305 , message.repeated_sint32 (0)); - EXPECT_EQ(306 , message.repeated_sint64 (0)); - EXPECT_EQ(307 , message.repeated_fixed32 (0)); - EXPECT_EQ(308 , message.repeated_fixed64 (0)); - EXPECT_EQ(309 , message.repeated_sfixed32(0)); - EXPECT_EQ(310 , message.repeated_sfixed64(0)); - EXPECT_EQ(311 , message.repeated_float (0)); - EXPECT_EQ(312 , message.repeated_double (0)); - EXPECT_EQ(false, message.repeated_bool (0)); - EXPECT_EQ("315", message.repeated_string (0)); - EXPECT_EQ("316", message.repeated_bytes (0)); - - EXPECT_EQ(317, message.repeatedgroup (0).a()); - EXPECT_EQ(318, message.repeated_nested_message (0).bb()); - EXPECT_EQ(319, message.repeated_foreign_message(0).c()); - EXPECT_EQ(320, message.repeated_import_message (0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (0)); -} - -void TestUtil::ExpectRepeatedExtensionsSwapped( - const unittest::TestAllExtensions& message) { - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 1)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 1)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 1)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 1)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 1)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 1)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 1)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 1)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 1)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 1)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 1)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 1)); - - EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 0)); -} - -// =================================================================== - -TestUtil::ReflectionTester::ReflectionTester( - const Descriptor* base_descriptor) - : base_descriptor_(base_descriptor) { - - const DescriptorPool* pool = base_descriptor->file()->pool(); - - nested_b_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.NestedMessage.bb"); - foreign_c_ = - pool->FindFieldByName("protobuf_unittest.ForeignMessage.c"); - import_d_ = - pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d"); - nested_foo_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO"); - nested_bar_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAR"); - nested_baz_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAZ"); - foreign_foo_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_FOO"); - foreign_bar_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAR"); - foreign_baz_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAZ"); - import_foo_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_FOO"); - import_bar_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAR"); - import_baz_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAZ"); - - if (base_descriptor_->name() == "TestAllExtensions") { - group_a_ = - pool->FindFieldByName("protobuf_unittest.OptionalGroup_extension.a"); - repeated_group_a_ = - pool->FindFieldByName("protobuf_unittest.RepeatedGroup_extension.a"); - } else { - group_a_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.OptionalGroup.a"); - repeated_group_a_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.RepeatedGroup.a"); - } - - EXPECT_TRUE(group_a_ != NULL); - EXPECT_TRUE(repeated_group_a_ != NULL); - EXPECT_TRUE(nested_b_ != NULL); - EXPECT_TRUE(foreign_c_ != NULL); - EXPECT_TRUE(import_d_ != NULL); - EXPECT_TRUE(nested_foo_ != NULL); - EXPECT_TRUE(nested_bar_ != NULL); - EXPECT_TRUE(nested_baz_ != NULL); - EXPECT_TRUE(foreign_foo_ != NULL); - EXPECT_TRUE(foreign_bar_ != NULL); - EXPECT_TRUE(foreign_baz_ != NULL); - EXPECT_TRUE(import_foo_ != NULL); - EXPECT_TRUE(import_bar_ != NULL); - EXPECT_TRUE(import_baz_ != NULL); -} - -// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. -const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) { - const FieldDescriptor* result = NULL; - if (base_descriptor_->name() == "TestAllExtensions" || - base_descriptor_->name() == "TestPackedExtensions") { - result = base_descriptor_->file()->FindExtensionByName(name + "_extension"); - } else { - result = base_descriptor_->FindFieldByName(name); - } - GOOGLE_CHECK(result != NULL); - return result; -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message; - - reflection->SetInt32 (message, F("optional_int32" ), 101); - reflection->SetInt64 (message, F("optional_int64" ), 102); - reflection->SetUInt32(message, F("optional_uint32" ), 103); - reflection->SetUInt64(message, F("optional_uint64" ), 104); - reflection->SetInt32 (message, F("optional_sint32" ), 105); - reflection->SetInt64 (message, F("optional_sint64" ), 106); - reflection->SetUInt32(message, F("optional_fixed32" ), 107); - reflection->SetUInt64(message, F("optional_fixed64" ), 108); - reflection->SetInt32 (message, F("optional_sfixed32"), 109); - reflection->SetInt64 (message, F("optional_sfixed64"), 110); - reflection->SetFloat (message, F("optional_float" ), 111); - reflection->SetDouble(message, F("optional_double" ), 112); - reflection->SetBool (message, F("optional_bool" ), true); - reflection->SetString(message, F("optional_string" ), "115"); - reflection->SetString(message, F("optional_bytes" ), "116"); - - sub_message = reflection->MutableMessage(message, F("optionalgroup")); - sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117); - sub_message = reflection->MutableMessage(message, F("optional_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118); - sub_message = reflection->MutableMessage(message, F("optional_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119); - sub_message = reflection->MutableMessage(message, F("optional_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120); - - reflection->SetEnum(message, F("optional_nested_enum" ), nested_baz_); - reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_); - reflection->SetEnum(message, F("optional_import_enum" ), import_baz_); - - reflection->SetString(message, F("optional_string_piece"), "124"); - reflection->SetString(message, F("optional_cord"), "125"); - - // ----------------------------------------------------------------- - - reflection->AddInt32 (message, F("repeated_int32" ), 201); - reflection->AddInt64 (message, F("repeated_int64" ), 202); - reflection->AddUInt32(message, F("repeated_uint32" ), 203); - reflection->AddUInt64(message, F("repeated_uint64" ), 204); - reflection->AddInt32 (message, F("repeated_sint32" ), 205); - reflection->AddInt64 (message, F("repeated_sint64" ), 206); - reflection->AddUInt32(message, F("repeated_fixed32" ), 207); - reflection->AddUInt64(message, F("repeated_fixed64" ), 208); - reflection->AddInt32 (message, F("repeated_sfixed32"), 209); - reflection->AddInt64 (message, F("repeated_sfixed64"), 210); - reflection->AddFloat (message, F("repeated_float" ), 211); - reflection->AddDouble(message, F("repeated_double" ), 212); - reflection->AddBool (message, F("repeated_bool" ), true); - reflection->AddString(message, F("repeated_string" ), "215"); - reflection->AddString(message, F("repeated_bytes" ), "216"); - - sub_message = reflection->AddMessage(message, F("repeatedgroup")); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217); - sub_message = reflection->AddMessage(message, F("repeated_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218); - sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219); - sub_message = reflection->AddMessage(message, F("repeated_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220); - - reflection->AddEnum(message, F("repeated_nested_enum" ), nested_bar_); - reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_); - reflection->AddEnum(message, F("repeated_import_enum" ), import_bar_); - - reflection->AddString(message, F("repeated_string_piece"), "224"); - reflection->AddString(message, F("repeated_cord"), "225"); - - // Add a second one of each field. - reflection->AddInt32 (message, F("repeated_int32" ), 301); - reflection->AddInt64 (message, F("repeated_int64" ), 302); - reflection->AddUInt32(message, F("repeated_uint32" ), 303); - reflection->AddUInt64(message, F("repeated_uint64" ), 304); - reflection->AddInt32 (message, F("repeated_sint32" ), 305); - reflection->AddInt64 (message, F("repeated_sint64" ), 306); - reflection->AddUInt32(message, F("repeated_fixed32" ), 307); - reflection->AddUInt64(message, F("repeated_fixed64" ), 308); - reflection->AddInt32 (message, F("repeated_sfixed32"), 309); - reflection->AddInt64 (message, F("repeated_sfixed64"), 310); - reflection->AddFloat (message, F("repeated_float" ), 311); - reflection->AddDouble(message, F("repeated_double" ), 312); - reflection->AddBool (message, F("repeated_bool" ), false); - reflection->AddString(message, F("repeated_string" ), "315"); - reflection->AddString(message, F("repeated_bytes" ), "316"); - - sub_message = reflection->AddMessage(message, F("repeatedgroup")); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317); - sub_message = reflection->AddMessage(message, F("repeated_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318); - sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319); - sub_message = reflection->AddMessage(message, F("repeated_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320); - - reflection->AddEnum(message, F("repeated_nested_enum" ), nested_baz_); - reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_); - reflection->AddEnum(message, F("repeated_import_enum" ), import_baz_); - - reflection->AddString(message, F("repeated_string_piece"), "324"); - reflection->AddString(message, F("repeated_cord"), "325"); - - // ----------------------------------------------------------------- - - reflection->SetInt32 (message, F("default_int32" ), 401); - reflection->SetInt64 (message, F("default_int64" ), 402); - reflection->SetUInt32(message, F("default_uint32" ), 403); - reflection->SetUInt64(message, F("default_uint64" ), 404); - reflection->SetInt32 (message, F("default_sint32" ), 405); - reflection->SetInt64 (message, F("default_sint64" ), 406); - reflection->SetUInt32(message, F("default_fixed32" ), 407); - reflection->SetUInt64(message, F("default_fixed64" ), 408); - reflection->SetInt32 (message, F("default_sfixed32"), 409); - reflection->SetInt64 (message, F("default_sfixed64"), 410); - reflection->SetFloat (message, F("default_float" ), 411); - reflection->SetDouble(message, F("default_double" ), 412); - reflection->SetBool (message, F("default_bool" ), false); - reflection->SetString(message, F("default_string" ), "415"); - reflection->SetString(message, F("default_bytes" ), "416"); - - reflection->SetEnum(message, F("default_nested_enum" ), nested_foo_); - reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_); - reflection->SetEnum(message, F("default_import_enum" ), import_foo_); - - reflection->SetString(message, F("default_string_piece"), "424"); - reflection->SetString(message, F("default_cord"), "425"); -} - -void TestUtil::ReflectionTester::SetPackedFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - reflection->AddInt32 (message, F("packed_int32" ), 601); - reflection->AddInt64 (message, F("packed_int64" ), 602); - reflection->AddUInt32(message, F("packed_uint32" ), 603); - reflection->AddUInt64(message, F("packed_uint64" ), 604); - reflection->AddInt32 (message, F("packed_sint32" ), 605); - reflection->AddInt64 (message, F("packed_sint64" ), 606); - reflection->AddUInt32(message, F("packed_fixed32" ), 607); - reflection->AddUInt64(message, F("packed_fixed64" ), 608); - reflection->AddInt32 (message, F("packed_sfixed32"), 609); - reflection->AddInt64 (message, F("packed_sfixed64"), 610); - reflection->AddFloat (message, F("packed_float" ), 611); - reflection->AddDouble(message, F("packed_double" ), 612); - reflection->AddBool (message, F("packed_bool" ), true); - reflection->AddEnum (message, F("packed_enum" ), foreign_bar_); - - reflection->AddInt32 (message, F("packed_int32" ), 701); - reflection->AddInt64 (message, F("packed_int64" ), 702); - reflection->AddUInt32(message, F("packed_uint32" ), 703); - reflection->AddUInt64(message, F("packed_uint64" ), 704); - reflection->AddInt32 (message, F("packed_sint32" ), 705); - reflection->AddInt64 (message, F("packed_sint64" ), 706); - reflection->AddUInt32(message, F("packed_fixed32" ), 707); - reflection->AddUInt64(message, F("packed_fixed64" ), 708); - reflection->AddInt32 (message, F("packed_sfixed32"), 709); - reflection->AddInt64 (message, F("packed_sfixed64"), 710); - reflection->AddFloat (message, F("packed_float" ), 711); - reflection->AddDouble(message, F("packed_double" ), 712); - reflection->AddBool (message, F("packed_bool" ), false); - reflection->AddEnum (message, F("packed_enum" ), foreign_baz_); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection( - const Message& message) { - // We have to split this into three function otherwise it creates a stack - // frame so large that it triggers a warning. - ExpectAllFieldsSetViaReflection1(message); - ExpectAllFieldsSetViaReflection2(message); - ExpectAllFieldsSetViaReflection3(message); -} - -void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - const Message* sub_message; - - EXPECT_TRUE(reflection->HasField(message, F("optional_int32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_int64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_uint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_uint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_float" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_double" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_bool" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_string" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_bytes" ))); - - EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" ))); - - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); - - EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" ))); - - EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_cord"))); - - EXPECT_EQ(101 , reflection->GetInt32 (message, F("optional_int32" ))); - EXPECT_EQ(102 , reflection->GetInt64 (message, F("optional_int64" ))); - EXPECT_EQ(103 , reflection->GetUInt32(message, F("optional_uint32" ))); - EXPECT_EQ(104 , reflection->GetUInt64(message, F("optional_uint64" ))); - EXPECT_EQ(105 , reflection->GetInt32 (message, F("optional_sint32" ))); - EXPECT_EQ(106 , reflection->GetInt64 (message, F("optional_sint64" ))); - EXPECT_EQ(107 , reflection->GetUInt32(message, F("optional_fixed32" ))); - EXPECT_EQ(108 , reflection->GetUInt64(message, F("optional_fixed64" ))); - EXPECT_EQ(109 , reflection->GetInt32 (message, F("optional_sfixed32"))); - EXPECT_EQ(110 , reflection->GetInt64 (message, F("optional_sfixed64"))); - EXPECT_EQ(111 , reflection->GetFloat (message, F("optional_float" ))); - EXPECT_EQ(112 , reflection->GetDouble(message, F("optional_double" ))); - EXPECT_EQ(true , reflection->GetBool (message, F("optional_bool" ))); - EXPECT_EQ("115", reflection->GetString(message, F("optional_string" ))); - EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes" ))); - - EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch)); - EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); - - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" ))); - EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum"))); - EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" ))); - - EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece"))); - EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); - - EXPECT_EQ("125", reflection->GetString(message, F("optional_cord"))); - EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch)); -} - -void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - const Message* sub_message; - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes" ))); - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum" ))); - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord"))); - - EXPECT_EQ(201 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 0)); - EXPECT_EQ(202 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 0)); - EXPECT_EQ(203 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 0)); - EXPECT_EQ(204 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 0)); - EXPECT_EQ(205 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 0)); - EXPECT_EQ(206 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 0)); - EXPECT_EQ(207 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0)); - EXPECT_EQ(208 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0)); - EXPECT_EQ(209 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0)); - EXPECT_EQ(210 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0)); - EXPECT_EQ(211 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 0)); - EXPECT_EQ(212 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 0)); - EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("repeated_bool" ), 0)); - EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string" ), 0)); - EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes" ), 0)); - - EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch)); - EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch)); - - sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0); - EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0); - EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0); - EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0); - EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0)); - EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0)); - EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0)); - - EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0)); - EXPECT_EQ("224", reflection->GetRepeatedStringReference( - message, F("repeated_string_piece"), 0, &scratch)); - - EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0)); - EXPECT_EQ("225", reflection->GetRepeatedStringReference( - message, F("repeated_cord"), 0, &scratch)); - - EXPECT_EQ(301 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 1)); - EXPECT_EQ(302 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 1)); - EXPECT_EQ(303 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 1)); - EXPECT_EQ(304 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 1)); - EXPECT_EQ(305 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 1)); - EXPECT_EQ(306 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 1)); - EXPECT_EQ(307 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1)); - EXPECT_EQ(308 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1)); - EXPECT_EQ(309 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1)); - EXPECT_EQ(310 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1)); - EXPECT_EQ(311 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 1)); - EXPECT_EQ(312 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 1)); - EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("repeated_bool" ), 1)); - EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string" ), 1)); - EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes" ), 1)); - - EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"), - 1, &scratch)); - EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), - 1, &scratch)); - - sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1); - EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1); - EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1); - EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1); - EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1)); - EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1)); - EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1)); - - EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1)); - EXPECT_EQ("324", reflection->GetRepeatedStringReference( - message, F("repeated_string_piece"), 1, &scratch)); - - EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1)); - EXPECT_EQ("325", reflection->GetRepeatedStringReference( - message, F("repeated_cord"), 1, &scratch)); -} - -void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - - // ----------------------------------------------------------------- - - EXPECT_TRUE(reflection->HasField(message, F("default_int32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_int64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_uint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_uint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32"))); - EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64"))); - EXPECT_TRUE(reflection->HasField(message, F("default_float" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_double" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_bool" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_string" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_bytes" ))); - - EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum"))); - EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" ))); - - EXPECT_TRUE(reflection->HasField(message, F("default_string_piece"))); - EXPECT_TRUE(reflection->HasField(message, F("default_cord"))); - - EXPECT_EQ(401 , reflection->GetInt32 (message, F("default_int32" ))); - EXPECT_EQ(402 , reflection->GetInt64 (message, F("default_int64" ))); - EXPECT_EQ(403 , reflection->GetUInt32(message, F("default_uint32" ))); - EXPECT_EQ(404 , reflection->GetUInt64(message, F("default_uint64" ))); - EXPECT_EQ(405 , reflection->GetInt32 (message, F("default_sint32" ))); - EXPECT_EQ(406 , reflection->GetInt64 (message, F("default_sint64" ))); - EXPECT_EQ(407 , reflection->GetUInt32(message, F("default_fixed32" ))); - EXPECT_EQ(408 , reflection->GetUInt64(message, F("default_fixed64" ))); - EXPECT_EQ(409 , reflection->GetInt32 (message, F("default_sfixed32"))); - EXPECT_EQ(410 , reflection->GetInt64 (message, F("default_sfixed64"))); - EXPECT_EQ(411 , reflection->GetFloat (message, F("default_float" ))); - EXPECT_EQ(412 , reflection->GetDouble(message, F("default_double" ))); - EXPECT_EQ(false, reflection->GetBool (message, F("default_bool" ))); - EXPECT_EQ("415", reflection->GetString(message, F("default_string" ))); - EXPECT_EQ("416", reflection->GetString(message, F("default_bytes" ))); - - EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch)); - EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); - - EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" ))); - EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum"))); - EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" ))); - - EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece"))); - EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"), - &scratch)); - - EXPECT_EQ("425", reflection->GetString(message, F("default_cord"))); - EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch)); -} - -void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum" ))); - - EXPECT_EQ(601 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 0)); - EXPECT_EQ(602 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 0)); - EXPECT_EQ(603 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 0)); - EXPECT_EQ(604 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 0)); - EXPECT_EQ(605 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 0)); - EXPECT_EQ(606 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 0)); - EXPECT_EQ(607 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 0)); - EXPECT_EQ(608 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 0)); - EXPECT_EQ(609 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 0)); - EXPECT_EQ(610 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0)); - EXPECT_EQ(611 , reflection->GetRepeatedFloat (message, F("packed_float" ), 0)); - EXPECT_EQ(612 , reflection->GetRepeatedDouble(message, F("packed_double" ), 0)); - EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("packed_bool" ), 0)); - EXPECT_EQ(foreign_bar_, - reflection->GetRepeatedEnum(message, F("packed_enum"), 0)); - - EXPECT_EQ(701 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 1)); - EXPECT_EQ(702 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 1)); - EXPECT_EQ(703 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 1)); - EXPECT_EQ(704 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 1)); - EXPECT_EQ(705 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 1)); - EXPECT_EQ(706 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 1)); - EXPECT_EQ(707 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 1)); - EXPECT_EQ(708 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 1)); - EXPECT_EQ(709 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 1)); - EXPECT_EQ(710 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1)); - EXPECT_EQ(711 , reflection->GetRepeatedFloat (message, F("packed_float" ), 1)); - EXPECT_EQ(712 , reflection->GetRepeatedDouble(message, F("packed_double" ), 1)); - EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("packed_bool" ), 1)); - EXPECT_EQ(foreign_baz_, - reflection->GetRepeatedEnum(message, F("packed_enum"), 1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ExpectClearViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - const Message* sub_message; - - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(reflection->HasField(message, F("optional_int32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_int64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_uint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_uint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_float" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_double" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_bool" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_string" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_bytes" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optionalgroup" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_cord"))); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_int32" ))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_int64" ))); - EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_uint32" ))); - EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_uint64" ))); - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sint32" ))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sint64" ))); - EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_fixed32" ))); - EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_fixed64" ))); - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sfixed32"))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sfixed64"))); - EXPECT_EQ(0 , reflection->GetFloat (message, F("optional_float" ))); - EXPECT_EQ(0 , reflection->GetDouble(message, F("optional_double" ))); - EXPECT_EQ(false, reflection->GetBool (message, F("optional_bool" ))); - EXPECT_EQ("" , reflection->GetString(message, F("optional_string" ))); - EXPECT_EQ("" , reflection->GetString(message, F("optional_bytes" ))); - - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch)); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); - - // Embedded messages should also be clear. - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" ))); - EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum"))); - EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" ))); - - EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece"))); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); - - EXPECT_EQ("", reflection->GetString(message, F("optional_cord"))); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch)); - - // Repeated fields are empty. - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes" ))); - - EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum" ))); - - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord"))); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(reflection->HasField(message, F("default_int32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_int64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_uint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_uint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32"))); - EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64"))); - EXPECT_FALSE(reflection->HasField(message, F("default_float" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_double" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_bool" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_string" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_bytes" ))); - - EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum"))); - EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" ))); - - EXPECT_FALSE(reflection->HasField(message, F("default_string_piece"))); - EXPECT_FALSE(reflection->HasField(message, F("default_cord"))); - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , reflection->GetInt32 (message, F("default_int32" ))); - EXPECT_EQ( 42 , reflection->GetInt64 (message, F("default_int64" ))); - EXPECT_EQ( 43 , reflection->GetUInt32(message, F("default_uint32" ))); - EXPECT_EQ( 44 , reflection->GetUInt64(message, F("default_uint64" ))); - EXPECT_EQ(-45 , reflection->GetInt32 (message, F("default_sint32" ))); - EXPECT_EQ( 46 , reflection->GetInt64 (message, F("default_sint64" ))); - EXPECT_EQ( 47 , reflection->GetUInt32(message, F("default_fixed32" ))); - EXPECT_EQ( 48 , reflection->GetUInt64(message, F("default_fixed64" ))); - EXPECT_EQ( 49 , reflection->GetInt32 (message, F("default_sfixed32"))); - EXPECT_EQ(-50 , reflection->GetInt64 (message, F("default_sfixed64"))); - EXPECT_EQ( 51.5 , reflection->GetFloat (message, F("default_float" ))); - EXPECT_EQ( 52e3 , reflection->GetDouble(message, F("default_double" ))); - EXPECT_EQ(true , reflection->GetBool (message, F("default_bool" ))); - EXPECT_EQ("hello", reflection->GetString(message, F("default_string" ))); - EXPECT_EQ("world", reflection->GetString(message, F("default_bytes" ))); - - EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch)); - EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); - - EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" ))); - EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum"))); - EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" ))); - - EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece"))); - EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch)); - - EXPECT_EQ("123", reflection->GetString(message, F("default_cord"))); - EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch)); -} - -void TestUtil::ReflectionTester::ExpectPackedClearViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum" ))); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message; - - reflection->SetRepeatedInt32 (message, F("repeated_int32" ), 1, 501); - reflection->SetRepeatedInt64 (message, F("repeated_int64" ), 1, 502); - reflection->SetRepeatedUInt32(message, F("repeated_uint32" ), 1, 503); - reflection->SetRepeatedUInt64(message, F("repeated_uint64" ), 1, 504); - reflection->SetRepeatedInt32 (message, F("repeated_sint32" ), 1, 505); - reflection->SetRepeatedInt64 (message, F("repeated_sint64" ), 1, 506); - reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507); - reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508); - reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509); - reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510); - reflection->SetRepeatedFloat (message, F("repeated_float" ), 1, 511); - reflection->SetRepeatedDouble(message, F("repeated_double" ), 1, 512); - reflection->SetRepeatedBool (message, F("repeated_bool" ), 1, true); - reflection->SetRepeatedString(message, F("repeated_string" ), 1, "515"); - reflection->SetRepeatedString(message, F("repeated_bytes" ), 1, "516"); - - sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520); - - reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1, nested_foo_); - reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_); - reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1, import_foo_); - - reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524"); - reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525"); -} - -void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - reflection->SetRepeatedInt32 (message, F("packed_int32" ), 1, 801); - reflection->SetRepeatedInt64 (message, F("packed_int64" ), 1, 802); - reflection->SetRepeatedUInt32(message, F("packed_uint32" ), 1, 803); - reflection->SetRepeatedUInt64(message, F("packed_uint64" ), 1, 804); - reflection->SetRepeatedInt32 (message, F("packed_sint32" ), 1, 805); - reflection->SetRepeatedInt64 (message, F("packed_sint64" ), 1, 806); - reflection->SetRepeatedUInt32(message, F("packed_fixed32" ), 1, 807); - reflection->SetRepeatedUInt64(message, F("packed_fixed64" ), 1, 808); - reflection->SetRepeatedInt32 (message, F("packed_sfixed32"), 1, 809); - reflection->SetRepeatedInt64 (message, F("packed_sfixed64"), 1, 810); - reflection->SetRepeatedFloat (message, F("packed_float" ), 1, 811); - reflection->SetRepeatedDouble(message, F("packed_double" ), 1, 812); - reflection->SetRepeatedBool (message, F("packed_bool" ), 1, true); - reflection->SetRepeatedEnum (message, F("packed_enum" ), 1, foreign_foo_); -} - -void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - - vector output; - reflection->ListFields(*message, &output); - for (int i=0; iis_repeated()) continue; - - reflection->RemoveLast(message, field); - } -} - -void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - - vector output; - reflection->ListFields(*message, &output); - for (int i=0; iis_repeated()) continue; - - reflection->SwapElements(message, field, 0, 1); - } -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/test_util.h b/Resources/NetHook/google/protobuf/test_util.h deleted file mode 100644 index 25165f3a..00000000 --- a/Resources/NetHook/google/protobuf/test_util.h +++ /dev/null @@ -1,174 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_TEST_UTIL_H__ -#define GOOGLE_PROTOBUF_TEST_UTIL_H__ - -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -namespace unittest = protobuf_unittest; -namespace unittest_import = protobuf_unittest_import; - -class TestUtil { - public: - // Set every field in the message to a unique value. - static void SetAllFields(unittest::TestAllTypes* message); - static void SetAllExtensions(unittest::TestAllExtensions* message); - static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message); - static void SetPackedFields(unittest::TestPackedTypes* message); - static void SetPackedExtensions(unittest::TestPackedExtensions* message); - static void SetUnpackedFields(unittest::TestUnpackedTypes* message); - - // Use the repeated versions of the set_*() accessors to modify all the - // repeated fields of the messsage (which should already have been - // initialized with Set*Fields()). Set*Fields() itself only tests - // the add_*() accessors. - static void ModifyRepeatedFields(unittest::TestAllTypes* message); - static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message); - static void ModifyPackedFields(unittest::TestPackedTypes* message); - static void ModifyPackedExtensions(unittest::TestPackedExtensions* message); - - // Check that all fields have the values that they should have after - // Set*Fields() is called. - static void ExpectAllFieldsSet(const unittest::TestAllTypes& message); - static void ExpectAllExtensionsSet( - const unittest::TestAllExtensions& message); - static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message); - static void ExpectPackedExtensionsSet( - const unittest::TestPackedExtensions& message); - static void ExpectUnpackedFieldsSet( - const unittest::TestUnpackedTypes& message); - - // Expect that the message is modified as would be expected from - // Modify*Fields(). - static void ExpectRepeatedFieldsModified( - const unittest::TestAllTypes& message); - static void ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensions& message); - static void ExpectPackedFieldsModified( - const unittest::TestPackedTypes& message); - static void ExpectPackedExtensionsModified( - const unittest::TestPackedExtensions& message); - - // Check that all fields have their default values. - static void ExpectClear(const unittest::TestAllTypes& message); - static void ExpectExtensionsClear(const unittest::TestAllExtensions& message); - static void ExpectPackedClear(const unittest::TestPackedTypes& message); - static void ExpectPackedExtensionsClear( - const unittest::TestPackedExtensions& message); - - // Check that the passed-in serialization is the canonical serialization we - // expect for a TestFieldOrderings message filled in by - // SetAllFieldsAndExtensions(). - static void ExpectAllFieldsAndExtensionsInOrder(const string& serialized); - - // Check that all repeated fields have had their last elements removed. - static void ExpectLastRepeatedsRemoved( - const unittest::TestAllTypes& message); - static void ExpectLastRepeatedExtensionsRemoved( - const unittest::TestAllExtensions& message); - - // Check that all repeated fields have had their first and last elements - // swapped. - static void ExpectRepeatedsSwapped(const unittest::TestAllTypes& message); - static void ExpectRepeatedExtensionsSwapped( - const unittest::TestAllExtensions& message); - - // Like above, but use the reflection interface. - class ReflectionTester { - public: - // base_descriptor must be a descriptor for TestAllTypes or - // TestAllExtensions. In the former case, ReflectionTester fetches from - // it the FieldDescriptors needed to use the reflection interface. In - // the latter case, ReflectionTester searches for extension fields in - // its file. - explicit ReflectionTester(const Descriptor* base_descriptor); - - void SetAllFieldsViaReflection(Message* message); - void ModifyRepeatedFieldsViaReflection(Message* message); - void ExpectAllFieldsSetViaReflection(const Message& message); - void ExpectClearViaReflection(const Message& message); - - void SetPackedFieldsViaReflection(Message* message); - void ModifyPackedFieldsViaReflection(Message* message); - void ExpectPackedFieldsSetViaReflection(const Message& message); - void ExpectPackedClearViaReflection(const Message& message); - - void RemoveLastRepeatedsViaReflection(Message* message); - void SwapRepeatedsViaReflection(Message* message); - - private: - const FieldDescriptor* F(const string& name); - - const Descriptor* base_descriptor_; - - const FieldDescriptor* group_a_; - const FieldDescriptor* repeated_group_a_; - const FieldDescriptor* nested_b_; - const FieldDescriptor* foreign_c_; - const FieldDescriptor* import_d_; - - const EnumValueDescriptor* nested_foo_; - const EnumValueDescriptor* nested_bar_; - const EnumValueDescriptor* nested_baz_; - const EnumValueDescriptor* foreign_foo_; - const EnumValueDescriptor* foreign_bar_; - const EnumValueDescriptor* foreign_baz_; - const EnumValueDescriptor* import_foo_; - const EnumValueDescriptor* import_bar_; - const EnumValueDescriptor* import_baz_; - - // We have to split this into three function otherwise it creates a stack - // frame so large that it triggers a warning. - void ExpectAllFieldsSetViaReflection1(const Message& message); - void ExpectAllFieldsSetViaReflection2(const Message& message); - void ExpectAllFieldsSetViaReflection3(const Message& message); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester); - }; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_TEST_UTIL_H__ diff --git a/Resources/NetHook/google/protobuf/test_util_lite.cc b/Resources/NetHook/google/protobuf/test_util_lite.cc deleted file mode 100644 index d7140e0c..00000000 --- a/Resources/NetHook/google/protobuf/test_util_lite.cc +++ /dev/null @@ -1,1502 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include - - -#define EXPECT_TRUE GOOGLE_CHECK -#define ASSERT_TRUE GOOGLE_CHECK -#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) -#define EXPECT_EQ GOOGLE_CHECK_EQ -#define ASSERT_EQ GOOGLE_CHECK_EQ - -namespace google { -namespace protobuf { - -void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) { - message->set_optional_int32 (101); - message->set_optional_int64 (102); - message->set_optional_uint32 (103); - message->set_optional_uint64 (104); - message->set_optional_sint32 (105); - message->set_optional_sint64 (106); - message->set_optional_fixed32 (107); - message->set_optional_fixed64 (108); - message->set_optional_sfixed32(109); - message->set_optional_sfixed64(110); - message->set_optional_float (111); - message->set_optional_double (112); - message->set_optional_bool (true); - message->set_optional_string ("115"); - message->set_optional_bytes ("116"); - - message->mutable_optionalgroup ()->set_a(117); - message->mutable_optional_nested_message ()->set_bb(118); - message->mutable_optional_foreign_message()->set_c(119); - message->mutable_optional_import_message ()->set_d(120); - - message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ ); - message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ ); - message->set_optional_import_enum (unittest_import::IMPORT_LITE_BAZ); - - - // ----------------------------------------------------------------- - - message->add_repeated_int32 (201); - message->add_repeated_int64 (202); - message->add_repeated_uint32 (203); - message->add_repeated_uint64 (204); - message->add_repeated_sint32 (205); - message->add_repeated_sint64 (206); - message->add_repeated_fixed32 (207); - message->add_repeated_fixed64 (208); - message->add_repeated_sfixed32(209); - message->add_repeated_sfixed64(210); - message->add_repeated_float (211); - message->add_repeated_double (212); - message->add_repeated_bool (true); - message->add_repeated_string ("215"); - message->add_repeated_bytes ("216"); - - message->add_repeatedgroup ()->set_a(217); - message->add_repeated_nested_message ()->set_bb(218); - message->add_repeated_foreign_message()->set_c(219); - message->add_repeated_import_message ()->set_d(220); - - message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR ); - message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR ); - message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAR); - - - // Add a second one of each field. - message->add_repeated_int32 (301); - message->add_repeated_int64 (302); - message->add_repeated_uint32 (303); - message->add_repeated_uint64 (304); - message->add_repeated_sint32 (305); - message->add_repeated_sint64 (306); - message->add_repeated_fixed32 (307); - message->add_repeated_fixed64 (308); - message->add_repeated_sfixed32(309); - message->add_repeated_sfixed64(310); - message->add_repeated_float (311); - message->add_repeated_double (312); - message->add_repeated_bool (false); - message->add_repeated_string ("315"); - message->add_repeated_bytes ("316"); - - message->add_repeatedgroup ()->set_a(317); - message->add_repeated_nested_message ()->set_bb(318); - message->add_repeated_foreign_message()->set_c(319); - message->add_repeated_import_message ()->set_d(320); - - message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ ); - message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ ); - message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAZ); - - - // ----------------------------------------------------------------- - - message->set_default_int32 (401); - message->set_default_int64 (402); - message->set_default_uint32 (403); - message->set_default_uint64 (404); - message->set_default_sint32 (405); - message->set_default_sint64 (406); - message->set_default_fixed32 (407); - message->set_default_fixed64 (408); - message->set_default_sfixed32(409); - message->set_default_sfixed64(410); - message->set_default_float (411); - message->set_default_double (412); - message->set_default_bool (false); - message->set_default_string ("415"); - message->set_default_bytes ("416"); - - message->set_default_nested_enum (unittest::TestAllTypesLite::FOO ); - message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO ); - message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) { - message->set_repeated_int32 (1, 501); - message->set_repeated_int64 (1, 502); - message->set_repeated_uint32 (1, 503); - message->set_repeated_uint64 (1, 504); - message->set_repeated_sint32 (1, 505); - message->set_repeated_sint64 (1, 506); - message->set_repeated_fixed32 (1, 507); - message->set_repeated_fixed64 (1, 508); - message->set_repeated_sfixed32(1, 509); - message->set_repeated_sfixed64(1, 510); - message->set_repeated_float (1, 511); - message->set_repeated_double (1, 512); - message->set_repeated_bool (1, true); - message->set_repeated_string (1, "515"); - message->set_repeated_bytes (1, "516"); - - message->mutable_repeatedgroup (1)->set_a(517); - message->mutable_repeated_nested_message (1)->set_bb(518); - message->mutable_repeated_foreign_message(1)->set_c(519); - message->mutable_repeated_import_message (1)->set_d(520); - - message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO ); - message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO ); - message->set_repeated_import_enum (1, unittest_import::IMPORT_LITE_FOO); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectAllFieldsSet( - const unittest::TestAllTypesLite& message) { - EXPECT_TRUE(message.has_optional_int32 ()); - EXPECT_TRUE(message.has_optional_int64 ()); - EXPECT_TRUE(message.has_optional_uint32 ()); - EXPECT_TRUE(message.has_optional_uint64 ()); - EXPECT_TRUE(message.has_optional_sint32 ()); - EXPECT_TRUE(message.has_optional_sint64 ()); - EXPECT_TRUE(message.has_optional_fixed32 ()); - EXPECT_TRUE(message.has_optional_fixed64 ()); - EXPECT_TRUE(message.has_optional_sfixed32()); - EXPECT_TRUE(message.has_optional_sfixed64()); - EXPECT_TRUE(message.has_optional_float ()); - EXPECT_TRUE(message.has_optional_double ()); - EXPECT_TRUE(message.has_optional_bool ()); - EXPECT_TRUE(message.has_optional_string ()); - EXPECT_TRUE(message.has_optional_bytes ()); - - EXPECT_TRUE(message.has_optionalgroup ()); - EXPECT_TRUE(message.has_optional_nested_message ()); - EXPECT_TRUE(message.has_optional_foreign_message()); - EXPECT_TRUE(message.has_optional_import_message ()); - - EXPECT_TRUE(message.optionalgroup ().has_a()); - EXPECT_TRUE(message.optional_nested_message ().has_bb()); - EXPECT_TRUE(message.optional_foreign_message().has_c()); - EXPECT_TRUE(message.optional_import_message ().has_d()); - - EXPECT_TRUE(message.has_optional_nested_enum ()); - EXPECT_TRUE(message.has_optional_foreign_enum()); - EXPECT_TRUE(message.has_optional_import_enum ()); - - - EXPECT_EQ(101 , message.optional_int32 ()); - EXPECT_EQ(102 , message.optional_int64 ()); - EXPECT_EQ(103 , message.optional_uint32 ()); - EXPECT_EQ(104 , message.optional_uint64 ()); - EXPECT_EQ(105 , message.optional_sint32 ()); - EXPECT_EQ(106 , message.optional_sint64 ()); - EXPECT_EQ(107 , message.optional_fixed32 ()); - EXPECT_EQ(108 , message.optional_fixed64 ()); - EXPECT_EQ(109 , message.optional_sfixed32()); - EXPECT_EQ(110 , message.optional_sfixed64()); - EXPECT_EQ(111 , message.optional_float ()); - EXPECT_EQ(112 , message.optional_double ()); - EXPECT_EQ(true , message.optional_bool ()); - EXPECT_EQ("115", message.optional_string ()); - EXPECT_EQ("116", message.optional_bytes ()); - - EXPECT_EQ(117, message.optionalgroup ().a()); - EXPECT_EQ(118, message.optional_nested_message ().bb()); - EXPECT_EQ(119, message.optional_foreign_message().c()); - EXPECT_EQ(120, message.optional_import_message ().d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.optional_import_enum ()); - - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); - - EXPECT_EQ(301 , message.repeated_int32 (1)); - EXPECT_EQ(302 , message.repeated_int64 (1)); - EXPECT_EQ(303 , message.repeated_uint32 (1)); - EXPECT_EQ(304 , message.repeated_uint64 (1)); - EXPECT_EQ(305 , message.repeated_sint32 (1)); - EXPECT_EQ(306 , message.repeated_sint64 (1)); - EXPECT_EQ(307 , message.repeated_fixed32 (1)); - EXPECT_EQ(308 , message.repeated_fixed64 (1)); - EXPECT_EQ(309 , message.repeated_sfixed32(1)); - EXPECT_EQ(310 , message.repeated_sfixed64(1)); - EXPECT_EQ(311 , message.repeated_float (1)); - EXPECT_EQ(312 , message.repeated_double (1)); - EXPECT_EQ(false, message.repeated_bool (1)); - EXPECT_EQ("315", message.repeated_string (1)); - EXPECT_EQ("316", message.repeated_bytes (1)); - - EXPECT_EQ(317, message.repeatedgroup (1).a()); - EXPECT_EQ(318, message.repeated_nested_message (1).bb()); - EXPECT_EQ(319, message.repeated_foreign_message(1).c()); - EXPECT_EQ(320, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.repeated_import_enum (1)); - - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.has_default_int32 ()); - EXPECT_TRUE(message.has_default_int64 ()); - EXPECT_TRUE(message.has_default_uint32 ()); - EXPECT_TRUE(message.has_default_uint64 ()); - EXPECT_TRUE(message.has_default_sint32 ()); - EXPECT_TRUE(message.has_default_sint64 ()); - EXPECT_TRUE(message.has_default_fixed32 ()); - EXPECT_TRUE(message.has_default_fixed64 ()); - EXPECT_TRUE(message.has_default_sfixed32()); - EXPECT_TRUE(message.has_default_sfixed64()); - EXPECT_TRUE(message.has_default_float ()); - EXPECT_TRUE(message.has_default_double ()); - EXPECT_TRUE(message.has_default_bool ()); - EXPECT_TRUE(message.has_default_string ()); - EXPECT_TRUE(message.has_default_bytes ()); - - EXPECT_TRUE(message.has_default_nested_enum ()); - EXPECT_TRUE(message.has_default_foreign_enum()); - EXPECT_TRUE(message.has_default_import_enum ()); - - - EXPECT_EQ(401 , message.default_int32 ()); - EXPECT_EQ(402 , message.default_int64 ()); - EXPECT_EQ(403 , message.default_uint32 ()); - EXPECT_EQ(404 , message.default_uint64 ()); - EXPECT_EQ(405 , message.default_sint32 ()); - EXPECT_EQ(406 , message.default_sint64 ()); - EXPECT_EQ(407 , message.default_fixed32 ()); - EXPECT_EQ(408 , message.default_fixed64 ()); - EXPECT_EQ(409 , message.default_sfixed32()); - EXPECT_EQ(410 , message.default_sfixed64()); - EXPECT_EQ(411 , message.default_float ()); - EXPECT_EQ(412 , message.default_double ()); - EXPECT_EQ(false, message.default_bool ()); - EXPECT_EQ("415", message.default_string ()); - EXPECT_EQ("416", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) { - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.has_optional_int32 ()); - EXPECT_FALSE(message.has_optional_int64 ()); - EXPECT_FALSE(message.has_optional_uint32 ()); - EXPECT_FALSE(message.has_optional_uint64 ()); - EXPECT_FALSE(message.has_optional_sint32 ()); - EXPECT_FALSE(message.has_optional_sint64 ()); - EXPECT_FALSE(message.has_optional_fixed32 ()); - EXPECT_FALSE(message.has_optional_fixed64 ()); - EXPECT_FALSE(message.has_optional_sfixed32()); - EXPECT_FALSE(message.has_optional_sfixed64()); - EXPECT_FALSE(message.has_optional_float ()); - EXPECT_FALSE(message.has_optional_double ()); - EXPECT_FALSE(message.has_optional_bool ()); - EXPECT_FALSE(message.has_optional_string ()); - EXPECT_FALSE(message.has_optional_bytes ()); - - EXPECT_FALSE(message.has_optionalgroup ()); - EXPECT_FALSE(message.has_optional_nested_message ()); - EXPECT_FALSE(message.has_optional_foreign_message()); - EXPECT_FALSE(message.has_optional_import_message ()); - - EXPECT_FALSE(message.has_optional_nested_enum ()); - EXPECT_FALSE(message.has_optional_foreign_enum()); - EXPECT_FALSE(message.has_optional_import_enum ()); - - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.optional_int32 ()); - EXPECT_EQ(0 , message.optional_int64 ()); - EXPECT_EQ(0 , message.optional_uint32 ()); - EXPECT_EQ(0 , message.optional_uint64 ()); - EXPECT_EQ(0 , message.optional_sint32 ()); - EXPECT_EQ(0 , message.optional_sint64 ()); - EXPECT_EQ(0 , message.optional_fixed32 ()); - EXPECT_EQ(0 , message.optional_fixed64 ()); - EXPECT_EQ(0 , message.optional_sfixed32()); - EXPECT_EQ(0 , message.optional_sfixed64()); - EXPECT_EQ(0 , message.optional_float ()); - EXPECT_EQ(0 , message.optional_double ()); - EXPECT_EQ(false, message.optional_bool ()); - EXPECT_EQ("" , message.optional_string ()); - EXPECT_EQ("" , message.optional_bytes ()); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.optionalgroup ().has_a()); - EXPECT_FALSE(message.optional_nested_message ().has_bb()); - EXPECT_FALSE(message.optional_foreign_message().has_c()); - EXPECT_FALSE(message.optional_import_message ().has_d()); - - EXPECT_EQ(0, message.optionalgroup ().a()); - EXPECT_EQ(0, message.optional_nested_message ().bb()); - EXPECT_EQ(0, message.optional_foreign_message().c()); - EXPECT_EQ(0, message.optional_import_message ().d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.optional_import_enum ()); - - - // Repeated fields are empty. - EXPECT_EQ(0, message.repeated_int32_size ()); - EXPECT_EQ(0, message.repeated_int64_size ()); - EXPECT_EQ(0, message.repeated_uint32_size ()); - EXPECT_EQ(0, message.repeated_uint64_size ()); - EXPECT_EQ(0, message.repeated_sint32_size ()); - EXPECT_EQ(0, message.repeated_sint64_size ()); - EXPECT_EQ(0, message.repeated_fixed32_size ()); - EXPECT_EQ(0, message.repeated_fixed64_size ()); - EXPECT_EQ(0, message.repeated_sfixed32_size()); - EXPECT_EQ(0, message.repeated_sfixed64_size()); - EXPECT_EQ(0, message.repeated_float_size ()); - EXPECT_EQ(0, message.repeated_double_size ()); - EXPECT_EQ(0, message.repeated_bool_size ()); - EXPECT_EQ(0, message.repeated_string_size ()); - EXPECT_EQ(0, message.repeated_bytes_size ()); - - EXPECT_EQ(0, message.repeatedgroup_size ()); - EXPECT_EQ(0, message.repeated_nested_message_size ()); - EXPECT_EQ(0, message.repeated_foreign_message_size()); - EXPECT_EQ(0, message.repeated_import_message_size ()); - EXPECT_EQ(0, message.repeated_nested_enum_size ()); - EXPECT_EQ(0, message.repeated_foreign_enum_size ()); - EXPECT_EQ(0, message.repeated_import_enum_size ()); - - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.has_default_int32 ()); - EXPECT_FALSE(message.has_default_int64 ()); - EXPECT_FALSE(message.has_default_uint32 ()); - EXPECT_FALSE(message.has_default_uint64 ()); - EXPECT_FALSE(message.has_default_sint32 ()); - EXPECT_FALSE(message.has_default_sint64 ()); - EXPECT_FALSE(message.has_default_fixed32 ()); - EXPECT_FALSE(message.has_default_fixed64 ()); - EXPECT_FALSE(message.has_default_sfixed32()); - EXPECT_FALSE(message.has_default_sfixed64()); - EXPECT_FALSE(message.has_default_float ()); - EXPECT_FALSE(message.has_default_double ()); - EXPECT_FALSE(message.has_default_bool ()); - EXPECT_FALSE(message.has_default_string ()); - EXPECT_FALSE(message.has_default_bytes ()); - - EXPECT_FALSE(message.has_default_nested_enum ()); - EXPECT_FALSE(message.has_default_foreign_enum()); - EXPECT_FALSE(message.has_default_import_enum ()); - - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.default_int32 ()); - EXPECT_EQ( 42 , message.default_int64 ()); - EXPECT_EQ( 43 , message.default_uint32 ()); - EXPECT_EQ( 44 , message.default_uint64 ()); - EXPECT_EQ(-45 , message.default_sint32 ()); - EXPECT_EQ( 46 , message.default_sint64 ()); - EXPECT_EQ( 47 , message.default_fixed32 ()); - EXPECT_EQ( 48 , message.default_fixed64 ()); - EXPECT_EQ( 49 , message.default_sfixed32()); - EXPECT_EQ(-50 , message.default_sfixed64()); - EXPECT_EQ( 51.5 , message.default_float ()); - EXPECT_EQ( 52e3 , message.default_double ()); - EXPECT_EQ(true , message.default_bool ()); - EXPECT_EQ("hello", message.default_string ()); - EXPECT_EQ("world", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectRepeatedFieldsModified( - const unittest::TestAllTypesLite& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); - - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.repeated_int32 (1)); - EXPECT_EQ(502 , message.repeated_int64 (1)); - EXPECT_EQ(503 , message.repeated_uint32 (1)); - EXPECT_EQ(504 , message.repeated_uint64 (1)); - EXPECT_EQ(505 , message.repeated_sint32 (1)); - EXPECT_EQ(506 , message.repeated_sint64 (1)); - EXPECT_EQ(507 , message.repeated_fixed32 (1)); - EXPECT_EQ(508 , message.repeated_fixed64 (1)); - EXPECT_EQ(509 , message.repeated_sfixed32(1)); - EXPECT_EQ(510 , message.repeated_sfixed64(1)); - EXPECT_EQ(511 , message.repeated_float (1)); - EXPECT_EQ(512 , message.repeated_double (1)); - EXPECT_EQ(true , message.repeated_bool (1)); - EXPECT_EQ("515", message.repeated_string (1)); - EXPECT_EQ("516", message.repeated_bytes (1)); - - EXPECT_EQ(517, message.repeatedgroup (1).a()); - EXPECT_EQ(518, message.repeated_nested_message (1).bb()); - EXPECT_EQ(519, message.repeated_foreign_message(1).c()); - EXPECT_EQ(520, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum (1)); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) { - message->add_packed_int32 (601); - message->add_packed_int64 (602); - message->add_packed_uint32 (603); - message->add_packed_uint64 (604); - message->add_packed_sint32 (605); - message->add_packed_sint64 (606); - message->add_packed_fixed32 (607); - message->add_packed_fixed64 (608); - message->add_packed_sfixed32(609); - message->add_packed_sfixed64(610); - message->add_packed_float (611); - message->add_packed_double (612); - message->add_packed_bool (true); - message->add_packed_enum (unittest::FOREIGN_LITE_BAR); - // add a second one of each field - message->add_packed_int32 (701); - message->add_packed_int64 (702); - message->add_packed_uint32 (703); - message->add_packed_uint64 (704); - message->add_packed_sint32 (705); - message->add_packed_sint64 (706); - message->add_packed_fixed32 (707); - message->add_packed_fixed64 (708); - message->add_packed_sfixed32(709); - message->add_packed_sfixed64(710); - message->add_packed_float (711); - message->add_packed_double (712); - message->add_packed_bool (false); - message->add_packed_enum (unittest::FOREIGN_LITE_BAZ); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) { - message->set_packed_int32 (1, 801); - message->set_packed_int64 (1, 802); - message->set_packed_uint32 (1, 803); - message->set_packed_uint64 (1, 804); - message->set_packed_sint32 (1, 805); - message->set_packed_sint64 (1, 806); - message->set_packed_fixed32 (1, 807); - message->set_packed_fixed64 (1, 808); - message->set_packed_sfixed32(1, 809); - message->set_packed_sfixed64(1, 810); - message->set_packed_float (1, 811); - message->set_packed_double (1, 812); - message->set_packed_bool (1, true); - message->set_packed_enum (1, unittest::FOREIGN_LITE_FOO); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedFieldsSet( - const unittest::TestPackedTypesLite& message) { - ASSERT_EQ(2, message.packed_int32_size ()); - ASSERT_EQ(2, message.packed_int64_size ()); - ASSERT_EQ(2, message.packed_uint32_size ()); - ASSERT_EQ(2, message.packed_uint64_size ()); - ASSERT_EQ(2, message.packed_sint32_size ()); - ASSERT_EQ(2, message.packed_sint64_size ()); - ASSERT_EQ(2, message.packed_fixed32_size ()); - ASSERT_EQ(2, message.packed_fixed64_size ()); - ASSERT_EQ(2, message.packed_sfixed32_size()); - ASSERT_EQ(2, message.packed_sfixed64_size()); - ASSERT_EQ(2, message.packed_float_size ()); - ASSERT_EQ(2, message.packed_double_size ()); - ASSERT_EQ(2, message.packed_bool_size ()); - ASSERT_EQ(2, message.packed_enum_size ()); - - EXPECT_EQ(601 , message.packed_int32 (0)); - EXPECT_EQ(602 , message.packed_int64 (0)); - EXPECT_EQ(603 , message.packed_uint32 (0)); - EXPECT_EQ(604 , message.packed_uint64 (0)); - EXPECT_EQ(605 , message.packed_sint32 (0)); - EXPECT_EQ(606 , message.packed_sint64 (0)); - EXPECT_EQ(607 , message.packed_fixed32 (0)); - EXPECT_EQ(608 , message.packed_fixed64 (0)); - EXPECT_EQ(609 , message.packed_sfixed32(0)); - EXPECT_EQ(610 , message.packed_sfixed64(0)); - EXPECT_EQ(611 , message.packed_float (0)); - EXPECT_EQ(612 , message.packed_double (0)); - EXPECT_EQ(true , message.packed_bool (0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); - - EXPECT_EQ(701 , message.packed_int32 (1)); - EXPECT_EQ(702 , message.packed_int64 (1)); - EXPECT_EQ(703 , message.packed_uint32 (1)); - EXPECT_EQ(704 , message.packed_uint64 (1)); - EXPECT_EQ(705 , message.packed_sint32 (1)); - EXPECT_EQ(706 , message.packed_sint64 (1)); - EXPECT_EQ(707 , message.packed_fixed32 (1)); - EXPECT_EQ(708 , message.packed_fixed64 (1)); - EXPECT_EQ(709 , message.packed_sfixed32(1)); - EXPECT_EQ(710 , message.packed_sfixed64(1)); - EXPECT_EQ(711 , message.packed_float (1)); - EXPECT_EQ(712 , message.packed_double (1)); - EXPECT_EQ(false, message.packed_bool (1)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1)); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedClear( - const unittest::TestPackedTypesLite& message) { - // Packed repeated fields are empty. - EXPECT_EQ(0, message.packed_int32_size ()); - EXPECT_EQ(0, message.packed_int64_size ()); - EXPECT_EQ(0, message.packed_uint32_size ()); - EXPECT_EQ(0, message.packed_uint64_size ()); - EXPECT_EQ(0, message.packed_sint32_size ()); - EXPECT_EQ(0, message.packed_sint64_size ()); - EXPECT_EQ(0, message.packed_fixed32_size ()); - EXPECT_EQ(0, message.packed_fixed64_size ()); - EXPECT_EQ(0, message.packed_sfixed32_size()); - EXPECT_EQ(0, message.packed_sfixed64_size()); - EXPECT_EQ(0, message.packed_float_size ()); - EXPECT_EQ(0, message.packed_double_size ()); - EXPECT_EQ(0, message.packed_bool_size ()); - EXPECT_EQ(0, message.packed_enum_size ()); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedFieldsModified( - const unittest::TestPackedTypesLite& message) { - // Do the same for packed repeated fields. - ASSERT_EQ(2, message.packed_int32_size ()); - ASSERT_EQ(2, message.packed_int64_size ()); - ASSERT_EQ(2, message.packed_uint32_size ()); - ASSERT_EQ(2, message.packed_uint64_size ()); - ASSERT_EQ(2, message.packed_sint32_size ()); - ASSERT_EQ(2, message.packed_sint64_size ()); - ASSERT_EQ(2, message.packed_fixed32_size ()); - ASSERT_EQ(2, message.packed_fixed64_size ()); - ASSERT_EQ(2, message.packed_sfixed32_size()); - ASSERT_EQ(2, message.packed_sfixed64_size()); - ASSERT_EQ(2, message.packed_float_size ()); - ASSERT_EQ(2, message.packed_double_size ()); - ASSERT_EQ(2, message.packed_bool_size ()); - ASSERT_EQ(2, message.packed_enum_size ()); - - EXPECT_EQ(601 , message.packed_int32 (0)); - EXPECT_EQ(602 , message.packed_int64 (0)); - EXPECT_EQ(603 , message.packed_uint32 (0)); - EXPECT_EQ(604 , message.packed_uint64 (0)); - EXPECT_EQ(605 , message.packed_sint32 (0)); - EXPECT_EQ(606 , message.packed_sint64 (0)); - EXPECT_EQ(607 , message.packed_fixed32 (0)); - EXPECT_EQ(608 , message.packed_fixed64 (0)); - EXPECT_EQ(609 , message.packed_sfixed32(0)); - EXPECT_EQ(610 , message.packed_sfixed64(0)); - EXPECT_EQ(611 , message.packed_float (0)); - EXPECT_EQ(612 , message.packed_double (0)); - EXPECT_EQ(true , message.packed_bool (0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); - // Actually verify the second (modified) elements now. - EXPECT_EQ(801 , message.packed_int32 (1)); - EXPECT_EQ(802 , message.packed_int64 (1)); - EXPECT_EQ(803 , message.packed_uint32 (1)); - EXPECT_EQ(804 , message.packed_uint64 (1)); - EXPECT_EQ(805 , message.packed_sint32 (1)); - EXPECT_EQ(806 , message.packed_sint64 (1)); - EXPECT_EQ(807 , message.packed_fixed32 (1)); - EXPECT_EQ(808 , message.packed_fixed64 (1)); - EXPECT_EQ(809 , message.packed_sfixed32(1)); - EXPECT_EQ(810 , message.packed_sfixed64(1)); - EXPECT_EQ(811 , message.packed_float (1)); - EXPECT_EQ(812 , message.packed_double (1)); - EXPECT_EQ(true , message.packed_bool (1)); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_enum(1)); -} - -// =================================================================== -// Extensions -// -// All this code is exactly equivalent to the above code except that it's -// manipulating extension fields instead of normal ones. -// -// I gave up on the 80-char limit here. Sorry. - -void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) { - message->SetExtension(unittest::optional_int32_extension_lite , 101); - message->SetExtension(unittest::optional_int64_extension_lite , 102); - message->SetExtension(unittest::optional_uint32_extension_lite , 103); - message->SetExtension(unittest::optional_uint64_extension_lite , 104); - message->SetExtension(unittest::optional_sint32_extension_lite , 105); - message->SetExtension(unittest::optional_sint64_extension_lite , 106); - message->SetExtension(unittest::optional_fixed32_extension_lite , 107); - message->SetExtension(unittest::optional_fixed64_extension_lite , 108); - message->SetExtension(unittest::optional_sfixed32_extension_lite, 109); - message->SetExtension(unittest::optional_sfixed64_extension_lite, 110); - message->SetExtension(unittest::optional_float_extension_lite , 111); - message->SetExtension(unittest::optional_double_extension_lite , 112); - message->SetExtension(unittest::optional_bool_extension_lite , true); - message->SetExtension(unittest::optional_string_extension_lite , "115"); - message->SetExtension(unittest::optional_bytes_extension_lite , "116"); - - message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117); - message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118); - message->MutableExtension(unittest::optional_foreign_message_extension_lite)->set_c(119); - message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120); - - message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); - message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); - message->SetExtension(unittest::optional_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); - - - // ----------------------------------------------------------------- - - message->AddExtension(unittest::repeated_int32_extension_lite , 201); - message->AddExtension(unittest::repeated_int64_extension_lite , 202); - message->AddExtension(unittest::repeated_uint32_extension_lite , 203); - message->AddExtension(unittest::repeated_uint64_extension_lite , 204); - message->AddExtension(unittest::repeated_sint32_extension_lite , 205); - message->AddExtension(unittest::repeated_sint64_extension_lite , 206); - message->AddExtension(unittest::repeated_fixed32_extension_lite , 207); - message->AddExtension(unittest::repeated_fixed64_extension_lite , 208); - message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209); - message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210); - message->AddExtension(unittest::repeated_float_extension_lite , 211); - message->AddExtension(unittest::repeated_double_extension_lite , 212); - message->AddExtension(unittest::repeated_bool_extension_lite , true); - message->AddExtension(unittest::repeated_string_extension_lite , "215"); - message->AddExtension(unittest::repeated_bytes_extension_lite , "216"); - - message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(217); - message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218); - message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219); - message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220); - - message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR ); - message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR ); - message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAR); - - - // Add a second one of each field. - message->AddExtension(unittest::repeated_int32_extension_lite , 301); - message->AddExtension(unittest::repeated_int64_extension_lite , 302); - message->AddExtension(unittest::repeated_uint32_extension_lite , 303); - message->AddExtension(unittest::repeated_uint64_extension_lite , 304); - message->AddExtension(unittest::repeated_sint32_extension_lite , 305); - message->AddExtension(unittest::repeated_sint64_extension_lite , 306); - message->AddExtension(unittest::repeated_fixed32_extension_lite , 307); - message->AddExtension(unittest::repeated_fixed64_extension_lite , 308); - message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309); - message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310); - message->AddExtension(unittest::repeated_float_extension_lite , 311); - message->AddExtension(unittest::repeated_double_extension_lite , 312); - message->AddExtension(unittest::repeated_bool_extension_lite , false); - message->AddExtension(unittest::repeated_string_extension_lite , "315"); - message->AddExtension(unittest::repeated_bytes_extension_lite , "316"); - - message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(317); - message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318); - message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319); - message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320); - - message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); - message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); - message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); - - - // ----------------------------------------------------------------- - - message->SetExtension(unittest::default_int32_extension_lite , 401); - message->SetExtension(unittest::default_int64_extension_lite , 402); - message->SetExtension(unittest::default_uint32_extension_lite , 403); - message->SetExtension(unittest::default_uint64_extension_lite , 404); - message->SetExtension(unittest::default_sint32_extension_lite , 405); - message->SetExtension(unittest::default_sint64_extension_lite , 406); - message->SetExtension(unittest::default_fixed32_extension_lite , 407); - message->SetExtension(unittest::default_fixed64_extension_lite , 408); - message->SetExtension(unittest::default_sfixed32_extension_lite, 409); - message->SetExtension(unittest::default_sfixed64_extension_lite, 410); - message->SetExtension(unittest::default_float_extension_lite , 411); - message->SetExtension(unittest::default_double_extension_lite , 412); - message->SetExtension(unittest::default_bool_extension_lite , false); - message->SetExtension(unittest::default_string_extension_lite , "415"); - message->SetExtension(unittest::default_bytes_extension_lite , "416"); - - message->SetExtension(unittest::default_nested_enum_extension_lite , unittest::TestAllTypesLite::FOO ); - message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO ); - message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ModifyRepeatedExtensions( - unittest::TestAllExtensionsLite* message) { - message->SetExtension(unittest::repeated_int32_extension_lite , 1, 501); - message->SetExtension(unittest::repeated_int64_extension_lite , 1, 502); - message->SetExtension(unittest::repeated_uint32_extension_lite , 1, 503); - message->SetExtension(unittest::repeated_uint64_extension_lite , 1, 504); - message->SetExtension(unittest::repeated_sint32_extension_lite , 1, 505); - message->SetExtension(unittest::repeated_sint64_extension_lite , 1, 506); - message->SetExtension(unittest::repeated_fixed32_extension_lite , 1, 507); - message->SetExtension(unittest::repeated_fixed64_extension_lite , 1, 508); - message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509); - message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510); - message->SetExtension(unittest::repeated_float_extension_lite , 1, 511); - message->SetExtension(unittest::repeated_double_extension_lite , 1, 512); - message->SetExtension(unittest::repeated_bool_extension_lite , 1, true); - message->SetExtension(unittest::repeated_string_extension_lite , 1, "515"); - message->SetExtension(unittest::repeated_bytes_extension_lite , 1, "516"); - - message->MutableExtension(unittest::repeatedgroup_extension_lite , 1)->set_a(517); - message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518); - message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519); - message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520); - - message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO ); - message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO ); - message->SetExtension(unittest::repeated_import_enum_extension_lite , 1, unittest_import::IMPORT_LITE_FOO); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectAllExtensionsSet( - const unittest::TestAllExtensionsLite& message) { - EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite )); - - EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite )); - - EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); - EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); - EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c()); - EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); - - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension_lite )); - - - EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension_lite )); - EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension_lite )); - EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension_lite )); - EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension_lite )); - EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension_lite )); - EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension_lite )); - EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension_lite )); - EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension_lite )); - EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); - EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); - EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension_lite )); - EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension_lite )); - EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension_lite )); - EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite )); - EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite )); - - EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); - EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); - EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite).c()); - EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite )); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::optional_import_enum_extension_lite )); - - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); - - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); - - - EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); - EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); - EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); - EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); - EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); - EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); - EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); - EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); - EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); - EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); - EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); - EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); - EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension_lite , 1)); - EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension_lite , 1)); - EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); - - EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); - EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); - EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); - EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); - - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite )); - - EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension_lite )); - EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); - EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension_lite )); - - - EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension_lite )); - EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension_lite )); - EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension_lite )); - EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension_lite )); - EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension_lite )); - EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension_lite )); - EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension_lite )); - EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension_lite )); - EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension_lite)); - EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension_lite)); - EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension_lite )); - EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension_lite )); - EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite )); - EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension_lite )); - EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension_lite )); - - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::default_nested_enum_extension_lite )); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::default_foreign_enum_extension_lite)); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite )); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectExtensionsClear( - const unittest::TestAllExtensionsLite& message) { - string serialized; - ASSERT_TRUE(message.SerializeToString(&serialized)); - EXPECT_EQ("", serialized); - EXPECT_EQ(0, message.ByteSize()); - - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite )); - - EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite )); - - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension_lite )); - - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension_lite )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension_lite )); - EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension_lite )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension_lite )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension_lite )); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); - EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); - EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c()); - EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); - - EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite).c()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite )); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::optional_import_enum_extension_lite )); - - - // Repeated fields are empty. - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); - - EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); - - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite )); - - EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension_lite )); - EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); - EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension_lite )); - - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension_lite )); - EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension_lite )); - EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension_lite )); - EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension_lite )); - EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension_lite )); - EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension_lite )); - EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension_lite )); - EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension_lite )); - EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension_lite)); - EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension_lite)); - EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension_lite )); - EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension_lite )); - EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension_lite )); - EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension_lite )); - EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension_lite )); - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::default_nested_enum_extension_lite )); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::default_foreign_enum_extension_lite)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite )); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensionsLite& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); - - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); - EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); - - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); - EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); - EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); - EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); - EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); - EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); - EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); - EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); - EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); - EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); - EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); - EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 1)); - EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension_lite , 1)); - EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); - - EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); - EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); - EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); - EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); - - EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); - EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); - -} - -// ------------------------------------------------------------------- - -void TestUtilLite::SetPackedExtensions( - unittest::TestPackedExtensionsLite* message) { - message->AddExtension(unittest::packed_int32_extension_lite , 601); - message->AddExtension(unittest::packed_int64_extension_lite , 602); - message->AddExtension(unittest::packed_uint32_extension_lite , 603); - message->AddExtension(unittest::packed_uint64_extension_lite , 604); - message->AddExtension(unittest::packed_sint32_extension_lite , 605); - message->AddExtension(unittest::packed_sint64_extension_lite , 606); - message->AddExtension(unittest::packed_fixed32_extension_lite , 607); - message->AddExtension(unittest::packed_fixed64_extension_lite , 608); - message->AddExtension(unittest::packed_sfixed32_extension_lite, 609); - message->AddExtension(unittest::packed_sfixed64_extension_lite, 610); - message->AddExtension(unittest::packed_float_extension_lite , 611); - message->AddExtension(unittest::packed_double_extension_lite , 612); - message->AddExtension(unittest::packed_bool_extension_lite , true); - message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAR); - // add a second one of each field - message->AddExtension(unittest::packed_int32_extension_lite , 701); - message->AddExtension(unittest::packed_int64_extension_lite , 702); - message->AddExtension(unittest::packed_uint32_extension_lite , 703); - message->AddExtension(unittest::packed_uint64_extension_lite , 704); - message->AddExtension(unittest::packed_sint32_extension_lite , 705); - message->AddExtension(unittest::packed_sint64_extension_lite , 706); - message->AddExtension(unittest::packed_fixed32_extension_lite , 707); - message->AddExtension(unittest::packed_fixed64_extension_lite , 708); - message->AddExtension(unittest::packed_sfixed32_extension_lite, 709); - message->AddExtension(unittest::packed_sfixed64_extension_lite, 710); - message->AddExtension(unittest::packed_float_extension_lite , 711); - message->AddExtension(unittest::packed_double_extension_lite , 712); - message->AddExtension(unittest::packed_bool_extension_lite , false); - message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAZ); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ModifyPackedExtensions( - unittest::TestPackedExtensionsLite* message) { - message->SetExtension(unittest::packed_int32_extension_lite , 1, 801); - message->SetExtension(unittest::packed_int64_extension_lite , 1, 802); - message->SetExtension(unittest::packed_uint32_extension_lite , 1, 803); - message->SetExtension(unittest::packed_uint64_extension_lite , 1, 804); - message->SetExtension(unittest::packed_sint32_extension_lite , 1, 805); - message->SetExtension(unittest::packed_sint64_extension_lite , 1, 806); - message->SetExtension(unittest::packed_fixed32_extension_lite , 1, 807); - message->SetExtension(unittest::packed_fixed64_extension_lite , 1, 808); - message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809); - message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810); - message->SetExtension(unittest::packed_float_extension_lite , 1, 811); - message->SetExtension(unittest::packed_double_extension_lite , 1, 812); - message->SetExtension(unittest::packed_bool_extension_lite , 1, true); - message->SetExtension(unittest::packed_enum_extension_lite , 1, - unittest::FOREIGN_LITE_FOO); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedExtensionsSet( - const unittest::TestPackedExtensionsLite& message) { - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); - - EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); - EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); - EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); - EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); - EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); - EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); - EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); - EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); - EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); - EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); - EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); - EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR, - message.GetExtension(unittest::packed_enum_extension_lite, 0)); - EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); - EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); - EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); - EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); - EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); - EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); - EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); - EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); - EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); - EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); - EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension_lite , 1)); - EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension_lite , 1)); - EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension_lite , 1)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, - message.GetExtension(unittest::packed_enum_extension_lite, 1)); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedExtensionsClear( - const unittest::TestPackedExtensionsLite& message) { - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite )); - EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite )); -} - -// ------------------------------------------------------------------- - -void TestUtilLite::ExpectPackedExtensionsModified( - const unittest::TestPackedExtensionsLite& message) { - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); - ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); - EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); - EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); - EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); - EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); - EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); - EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); - EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); - EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); - EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); - EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); - EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); - EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); - EXPECT_EQ(unittest::FOREIGN_LITE_BAR, - message.GetExtension(unittest::packed_enum_extension_lite, 0)); - - // Actually verify the second (modified) elements now. - EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); - EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); - EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); - EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); - EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); - EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); - EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); - EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); - EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); - EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); - EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension_lite , 1)); - EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension_lite , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 1)); - EXPECT_EQ(unittest::FOREIGN_LITE_FOO, - message.GetExtension(unittest::packed_enum_extension_lite, 1)); -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/test_util_lite.h b/Resources/NetHook/google/protobuf/test_util_lite.h deleted file mode 100644 index ca35aaa4..00000000 --- a/Resources/NetHook/google/protobuf/test_util_lite.h +++ /dev/null @@ -1,101 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ -#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ - -#include - -namespace google { -namespace protobuf { - -namespace unittest = protobuf_unittest; -namespace unittest_import = protobuf_unittest_import; - -class TestUtilLite { - public: - // Set every field in the message to a unique value. - static void SetAllFields(unittest::TestAllTypesLite* message); - static void SetAllExtensions(unittest::TestAllExtensionsLite* message); - static void SetPackedFields(unittest::TestPackedTypesLite* message); - static void SetPackedExtensions(unittest::TestPackedExtensionsLite* message); - - // Use the repeated versions of the set_*() accessors to modify all the - // repeated fields of the messsage (which should already have been - // initialized with Set*Fields()). Set*Fields() itself only tests - // the add_*() accessors. - static void ModifyRepeatedFields(unittest::TestAllTypesLite* message); - static void ModifyRepeatedExtensions( - unittest::TestAllExtensionsLite* message); - static void ModifyPackedFields(unittest::TestPackedTypesLite* message); - static void ModifyPackedExtensions( - unittest::TestPackedExtensionsLite* message); - - // Check that all fields have the values that they should have after - // Set*Fields() is called. - static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message); - static void ExpectAllExtensionsSet( - const unittest::TestAllExtensionsLite& message); - static void ExpectPackedFieldsSet( - const unittest::TestPackedTypesLite& message); - static void ExpectPackedExtensionsSet( - const unittest::TestPackedExtensionsLite& message); - - // Expect that the message is modified as would be expected from - // Modify*Fields(). - static void ExpectRepeatedFieldsModified( - const unittest::TestAllTypesLite& message); - static void ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensionsLite& message); - static void ExpectPackedFieldsModified( - const unittest::TestPackedTypesLite& message); - static void ExpectPackedExtensionsModified( - const unittest::TestPackedExtensionsLite& message); - - // Check that all fields have their default values. - static void ExpectClear(const unittest::TestAllTypesLite& message); - static void ExpectExtensionsClear( - const unittest::TestAllExtensionsLite& message); - static void ExpectPackedClear(const unittest::TestPackedTypesLite& message); - static void ExpectPackedExtensionsClear( - const unittest::TestPackedExtensionsLite& message); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ diff --git a/Resources/NetHook/google/protobuf/text_format.cc b/Resources/NetHook/google/protobuf/text_format.cc deleted file mode 100644 index 137cbcee..00000000 --- a/Resources/NetHook/google/protobuf/text_format.cc +++ /dev/null @@ -1,1241 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -string Message::DebugString() const { - string debug_string; - - TextFormat::PrintToString(*this, &debug_string); - - return debug_string; -} - -string Message::ShortDebugString() const { - string debug_string; - - TextFormat::Printer printer; - printer.SetSingleLineMode(true); - - printer.PrintToString(*this, &debug_string); - // Single line mode currently might have an extra space at the end. - if (debug_string.size() > 0 && - debug_string[debug_string.size() - 1] == ' ') { - debug_string.resize(debug_string.size() - 1); - } - - return debug_string; -} - -string Message::Utf8DebugString() const { - string debug_string; - - TextFormat::Printer printer; - printer.SetUseUtf8StringEscaping(true); - - printer.PrintToString(*this, &debug_string); - - return debug_string; -} - -void Message::PrintDebugString() const { - printf("%s", DebugString().c_str()); -} - - -// =========================================================================== -// Internal class for parsing an ASCII representation of a Protocol Message. -// This class makes use of the Protocol Message compiler's tokenizer found -// in //google/protobuf/io/tokenizer.h. Note that class's Parse -// method is *not* thread-safe and should only be used in a single thread at -// a time. - -// Makes code slightly more readable. The meaning of "DO(foo)" is -// "Execute foo and fail if it fails.", where failure is indicated by -// returning false. Borrowed from parser.cc (Thanks Kenton!). -#define DO(STATEMENT) if (STATEMENT) {} else return false - -class TextFormat::Parser::ParserImpl { - public: - - // Determines if repeated values for a non-repeated field are - // permitted, e.g., the string "foo: 1 foo: 2" for a - // required/optional field named "foo". - enum SingularOverwritePolicy { - ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained - FORBID_SINGULAR_OVERWRITES = 1, // an error is issued - }; - - ParserImpl(const Descriptor* root_message_type, - io::ZeroCopyInputStream* input_stream, - io::ErrorCollector* error_collector, - SingularOverwritePolicy singular_overwrite_policy) - : error_collector_(error_collector), - tokenizer_error_collector_(this), - tokenizer_(input_stream, &tokenizer_error_collector_), - root_message_type_(root_message_type), - singular_overwrite_policy_(singular_overwrite_policy), - had_errors_(false) { - // For backwards-compatibility with proto1, we need to allow the 'f' suffix - // for floats. - tokenizer_.set_allow_f_after_float(true); - - // '#' starts a comment. - tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); - - // Consume the starting token. - tokenizer_.Next(); - } - ~ParserImpl() { } - - // Parses the ASCII representation specified in input and saves the - // information into the output pointer (a Message). Returns - // false if an error occurs (an error will also be logged to - // GOOGLE_LOG(ERROR)). - bool Parse(Message* output) { - // Consume fields until we cannot do so anymore. - while(true) { - if (LookingAtType(io::Tokenizer::TYPE_END)) { - return !had_errors_; - } - - DO(ConsumeField(output)); - } - } - - bool ParseField(const FieldDescriptor* field, Message* output) { - bool suc; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - suc = ConsumeFieldMessage(output, output->GetReflection(), field); - } else { - suc = ConsumeFieldValue(output, output->GetReflection(), field); - } - return suc && LookingAtType(io::Tokenizer::TYPE_END); - } - - void ReportError(int line, int col, const string& message) { - had_errors_ = true; - if (error_collector_ == NULL) { - if (line >= 0) { - GOOGLE_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() - << ": " << (line + 1) << ":" - << (col + 1) << ": " << message; - } else { - GOOGLE_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() - << ": " << message; - } - } else { - error_collector_->AddError(line, col, message); - } - } - - void ReportWarning(int line, int col, const string& message) { - if (error_collector_ == NULL) { - if (line >= 0) { - GOOGLE_LOG(WARNING) << "Warning parsing text-format " - << root_message_type_->full_name() - << ": " << (line + 1) << ":" - << (col + 1) << ": " << message; - } else { - GOOGLE_LOG(WARNING) << "Warning parsing text-format " - << root_message_type_->full_name() - << ": " << message; - } - } else { - error_collector_->AddWarning(line, col, message); - } - } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); - - // Reports an error with the given message with information indicating - // the position (as derived from the current token). - void ReportError(const string& message) { - ReportError(tokenizer_.current().line, tokenizer_.current().column, - message); - } - - // Reports a warning with the given message with information indicating - // the position (as derived from the current token). - void ReportWarning(const string& message) { - ReportWarning(tokenizer_.current().line, tokenizer_.current().column, - message); - } - - // Consumes the specified message with the given starting delimeter. - // This method checks to see that the end delimeter at the conclusion of - // the consumption matches the starting delimeter passed in here. - bool ConsumeMessage(Message* message, const string delimeter) { - while (!LookingAt(">") && !LookingAt("}")) { - DO(ConsumeField(message)); - } - - // Confirm that we have a valid ending delimeter. - DO(Consume(delimeter)); - - return true; - } - - // Consumes the current field (as returned by the tokenizer) on the - // passed in message. - bool ConsumeField(Message* message) { - const Reflection* reflection = message->GetReflection(); - const Descriptor* descriptor = message->GetDescriptor(); - - string field_name; - - const FieldDescriptor* field = NULL; - - if (TryConsume("[")) { - // Extension. - DO(ConsumeIdentifier(&field_name)); - while (TryConsume(".")) { - string part; - DO(ConsumeIdentifier(&part)); - field_name += "."; - field_name += part; - } - DO(Consume("]")); - - field = reflection->FindKnownExtensionByName(field_name); - - if (field == NULL) { - ReportError("Extension \"" + field_name + "\" is not defined or " - "is not an extension of \"" + - descriptor->full_name() + "\"."); - return false; - } - } else { - DO(ConsumeIdentifier(&field_name)); - - field = descriptor->FindFieldByName(field_name); - // Group names are expected to be capitalized as they appear in the - // .proto file, which actually matches their type names, not their field - // names. - if (field == NULL) { - string lower_field_name = field_name; - LowerString(&lower_field_name); - field = descriptor->FindFieldByName(lower_field_name); - // If the case-insensitive match worked but the field is NOT a group, - if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { - field = NULL; - } - } - // Again, special-case group names as described above. - if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP - && field->message_type()->name() != field_name) { - field = NULL; - } - - if (field == NULL) { - ReportError("Message type \"" + descriptor->full_name() + - "\" has no field named \"" + field_name + "\"."); - return false; - } - } - - // Fail if the field is not repeated and it has already been specified. - if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) && - !field->is_repeated() && reflection->HasField(*message, field)) { - ReportError("Non-repeated field \"" + field_name + - "\" is specified multiple times."); - return false; - } - - // Perform special handling for embedded message types. - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // ':' is optional here. - TryConsume(":"); - DO(ConsumeFieldMessage(message, reflection, field)); - } else { - DO(Consume(":")); - DO(ConsumeFieldValue(message, reflection, field)); - } - - if (field->options().deprecated()) { - ReportWarning("text format contains deprecated field \"" - + field_name + "\""); - } - - return true; - } - - bool ConsumeFieldMessage(Message* message, - const Reflection* reflection, - const FieldDescriptor* field) { - string delimeter; - if (TryConsume("<")) { - delimeter = ">"; - } else { - DO(Consume("{")); - delimeter = "}"; - } - - if (field->is_repeated()) { - DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); - } else { - DO(ConsumeMessage(reflection->MutableMessage(message, field), - delimeter)); - } - return true; - } - - bool ConsumeFieldValue(Message* message, - const Reflection* reflection, - const FieldDescriptor* field) { - -// Define an easy to use macro for setting fields. This macro checks -// to see if the field is repeated (in which case we need to use the Add -// methods or not (in which case we need to use the Set methods). -#define SET_FIELD(CPPTYPE, VALUE) \ - if (field->is_repeated()) { \ - reflection->Add##CPPTYPE(message, field, VALUE); \ - } else { \ - reflection->Set##CPPTYPE(message, field, VALUE); \ - } \ - - switch(field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: { - int64 value; - DO(ConsumeSignedInteger(&value, kint32max)); - SET_FIELD(Int32, static_cast(value)); - break; - } - - case FieldDescriptor::CPPTYPE_UINT32: { - uint64 value; - DO(ConsumeUnsignedInteger(&value, kuint32max)); - SET_FIELD(UInt32, static_cast(value)); - break; - } - - case FieldDescriptor::CPPTYPE_INT64: { - int64 value; - DO(ConsumeSignedInteger(&value, kint64max)); - SET_FIELD(Int64, value); - break; - } - - case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value; - DO(ConsumeUnsignedInteger(&value, kuint64max)); - SET_FIELD(UInt64, value); - break; - } - - case FieldDescriptor::CPPTYPE_FLOAT: { - double value; - DO(ConsumeDouble(&value)); - SET_FIELD(Float, static_cast(value)); - break; - } - - case FieldDescriptor::CPPTYPE_DOUBLE: { - double value; - DO(ConsumeDouble(&value)); - SET_FIELD(Double, value); - break; - } - - case FieldDescriptor::CPPTYPE_STRING: { - string value; - DO(ConsumeString(&value)); - SET_FIELD(String, value); - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: { - string value; - DO(ConsumeIdentifier(&value)); - - if (value == "true") { - SET_FIELD(Bool, true); - } else if (value == "false") { - SET_FIELD(Bool, false); - } else { - ReportError("Invalid value for boolean field \"" + field->name() - + "\". Value: \"" + value + "\"."); - return false; - } - break; - } - - case FieldDescriptor::CPPTYPE_ENUM: { - string value; - DO(ConsumeIdentifier(&value)); - - // Find the enumeration value. - const EnumDescriptor* enum_type = field->enum_type(); - const EnumValueDescriptor* enum_value - = enum_type->FindValueByName(value); - - if (enum_value == NULL) { - ReportError("Unknown enumeration value of \"" + value + "\" for " - "field \"" + field->name() + "\"."); - return false; - } - - SET_FIELD(Enum, enum_value); - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: { - // We should never get here. Put here instead of a default - // so that if new types are added, we get a nice compiler warning. - GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; - break; - } - } -#undef SET_FIELD - return true; - } - - // Returns true if the current token's text is equal to that specified. - bool LookingAt(const string& text) { - return tokenizer_.current().text == text; - } - - // Returns true if the current token's type is equal to that specified. - bool LookingAtType(io::Tokenizer::TokenType token_type) { - return tokenizer_.current().type == token_type; - } - - // Consumes an identifier and saves its value in the identifier parameter. - // Returns false if the token is not of type IDENTFIER. - bool ConsumeIdentifier(string* identifier) { - if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - ReportError("Expected identifier."); - return false; - } - - *identifier = tokenizer_.current().text; - - tokenizer_.Next(); - return true; - } - - // Consumes a string and saves its value in the text parameter. - // Returns false if the token is not of type STRING. - bool ConsumeString(string* text) { - if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { - ReportError("Expected string."); - return false; - } - - text->clear(); - while (LookingAtType(io::Tokenizer::TYPE_STRING)) { - io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); - - tokenizer_.Next(); - } - - return true; - } - - // Consumes a uint64 and saves its value in the value parameter. - // Returns false if the token is not of type INTEGER. - bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { - if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - ReportError("Expected integer."); - return false; - } - - if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, - max_value, value)) { - ReportError("Integer out of range."); - return false; - } - - tokenizer_.Next(); - return true; - } - - // Consumes an int64 and saves its value in the value parameter. - // Note that since the tokenizer does not support negative numbers, - // we actually may consume an additional token (for the minus sign) in this - // method. Returns false if the token is not an integer - // (signed or otherwise). - bool ConsumeSignedInteger(int64* value, uint64 max_value) { - bool negative = false; - - if (TryConsume("-")) { - negative = true; - // Two's complement always allows one more negative integer than - // positive. - ++max_value; - } - - uint64 unsigned_value; - - DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); - - *value = static_cast(unsigned_value); - - if (negative) { - *value = -*value; - } - - return true; - } - - // Consumes a double and saves its value in the value parameter. - // Note that since the tokenizer does not support negative numbers, - // we actually may consume an additional token (for the minus sign) in this - // method. Returns false if the token is not a double - // (signed or otherwise). - bool ConsumeDouble(double* value) { - bool negative = false; - - if (TryConsume("-")) { - negative = true; - } - - // A double can actually be an integer, according to the tokenizer. - // Therefore, we must check both cases here. - if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - // We have found an integer value for the double. - uint64 integer_value; - DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); - - *value = static_cast(integer_value); - } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { - // We have found a float value for the double. - *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); - - // Mark the current token as consumed. - tokenizer_.Next(); - } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - string text = tokenizer_.current().text; - LowerString(&text); - if (text == "inf" || text == "infinity") { - *value = std::numeric_limits::infinity(); - tokenizer_.Next(); - } else if (text == "nan") { - *value = std::numeric_limits::quiet_NaN(); - tokenizer_.Next(); - } else { - ReportError("Expected double."); - return false; - } - } else { - ReportError("Expected double."); - return false; - } - - if (negative) { - *value = -*value; - } - - return true; - } - - // Consumes a token and confirms that it matches that specified in the - // value parameter. Returns false if the token found does not match that - // which was specified. - bool Consume(const string& value) { - const string& current_value = tokenizer_.current().text; - - if (current_value != value) { - ReportError("Expected \"" + value + "\", found \"" + current_value - + "\"."); - return false; - } - - tokenizer_.Next(); - - return true; - } - - // Attempts to consume the supplied value. Returns false if a the - // token found does not match the value specified. - bool TryConsume(const string& value) { - if (tokenizer_.current().text == value) { - tokenizer_.Next(); - return true; - } else { - return false; - } - } - - // An internal instance of the Tokenizer's error collector, used to - // collect any base-level parse errors and feed them to the ParserImpl. - class ParserErrorCollector : public io::ErrorCollector { - public: - explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : - parser_(parser) { } - - virtual ~ParserErrorCollector() { }; - - virtual void AddError(int line, int column, const string& message) { - parser_->ReportError(line, column, message); - } - - virtual void AddWarning(int line, int column, const string& message) { - parser_->ReportWarning(line, column, message); - } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); - TextFormat::Parser::ParserImpl* parser_; - }; - - io::ErrorCollector* error_collector_; - ParserErrorCollector tokenizer_error_collector_; - io::Tokenizer tokenizer_; - const Descriptor* root_message_type_; - SingularOverwritePolicy singular_overwrite_policy_; - bool had_errors_; -}; - -#undef DO - -// =========================================================================== -// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted -// from the Printer found in //google/protobuf/io/printer.h -class TextFormat::Printer::TextGenerator { - public: - explicit TextGenerator(io::ZeroCopyOutputStream* output, - int initial_indent_level) - : output_(output), - buffer_(NULL), - buffer_size_(0), - at_start_of_line_(true), - failed_(false), - indent_(""), - initial_indent_level_(initial_indent_level) { - indent_.resize(initial_indent_level_ * 2, ' '); - } - - ~TextGenerator() { - // Only BackUp() if we're sure we've successfully called Next() at least - // once. - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } - } - - // Indent text by two spaces. After calling Indent(), two spaces will be - // inserted at the beginning of each line of text. Indent() may be called - // multiple times to produce deeper indents. - void Indent() { - indent_ += " "; - } - - // Reduces the current indent level by two spaces, or crashes if the indent - // level is zero. - void Outdent() { - if (indent_.empty() || - indent_.size() < initial_indent_level_ * 2) { - GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; - return; - } - - indent_.resize(indent_.size() - 2); - } - - // Print text to the output stream. - void Print(const string& str) { - Print(str.data(), str.size()); - } - - // Print text to the output stream. - void Print(const char* text) { - Print(text, strlen(text)); - } - - // Print text to the output stream. - void Print(const char* text, int size) { - int pos = 0; // The number of bytes we've written so far. - - for (int i = 0; i < size; i++) { - if (text[i] == '\n') { - // Saw newline. If there is more text, we may need to insert an indent - // here. So, write what we have so far, including the '\n'. - Write(text + pos, i - pos + 1); - pos = i + 1; - - // Setting this true will cause the next Write() to insert an indent - // first. - at_start_of_line_ = true; - } - } - - // Write the rest. - Write(text + pos, size - pos); - } - - // True if any write to the underlying stream failed. (We don't just - // crash in this case because this is an I/O failure, not a programming - // error.) - bool failed() const { return failed_; } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); - - void Write(const char* data, int size) { - if (failed_) return; - if (size == 0) return; - - if (at_start_of_line_) { - // Insert an indent. - at_start_of_line_ = false; - Write(indent_.data(), indent_.size()); - if (failed_) return; - } - - while (size > buffer_size_) { - // Data exceeds space in the buffer. Copy what we can and request a - // new buffer. - memcpy(buffer_, data, buffer_size_); - data += buffer_size_; - size -= buffer_size_; - void* void_buffer; - failed_ = !output_->Next(&void_buffer, &buffer_size_); - if (failed_) return; - buffer_ = reinterpret_cast(void_buffer); - } - - // Buffer is big enough to receive the data; copy it. - memcpy(buffer_, data, size); - buffer_ += size; - buffer_size_ -= size; - } - - io::ZeroCopyOutputStream* const output_; - char* buffer_; - int buffer_size_; - bool at_start_of_line_; - bool failed_; - - string indent_; - int initial_indent_level_; -}; - -// =========================================================================== - -TextFormat::Parser::Parser() - : error_collector_(NULL), - allow_partial_(false) {} - -TextFormat::Parser::~Parser() {} - -bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, - Message* output) { - output->Clear(); - ParserImpl parser(output->GetDescriptor(), input, error_collector_, - ParserImpl::FORBID_SINGULAR_OVERWRITES); - return MergeUsingImpl(input, output, &parser); -} - -bool TextFormat::Parser::ParseFromString(const string& input, - Message* output) { - io::ArrayInputStream input_stream(input.data(), input.size()); - return Parse(&input_stream, output); -} - -bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, - Message* output) { - ParserImpl parser(output->GetDescriptor(), input, error_collector_, - ParserImpl::ALLOW_SINGULAR_OVERWRITES); - return MergeUsingImpl(input, output, &parser); -} - -bool TextFormat::Parser::MergeFromString(const string& input, - Message* output) { - io::ArrayInputStream input_stream(input.data(), input.size()); - return Merge(&input_stream, output); -} - -bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, - Message* output, - ParserImpl* parser_impl) { - if (!parser_impl->Parse(output)) return false; - if (!allow_partial_ && !output->IsInitialized()) { - vector missing_fields; - output->FindInitializationErrors(&missing_fields); - parser_impl->ReportError(-1, 0, "Message missing required fields: " + - JoinStrings(missing_fields, ", ")); - return false; - } - return true; -} - -bool TextFormat::Parser::ParseFieldValueFromString( - const string& input, - const FieldDescriptor* field, - Message* output) { - io::ArrayInputStream input_stream(input.data(), input.size()); - ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, - ParserImpl::ALLOW_SINGULAR_OVERWRITES); - return parser.ParseField(field, output); -} - -/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, - Message* output) { - return Parser().Parse(input, output); -} - -/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, - Message* output) { - return Parser().Merge(input, output); -} - -/* static */ bool TextFormat::ParseFromString(const string& input, - Message* output) { - return Parser().ParseFromString(input, output); -} - -/* static */ bool TextFormat::MergeFromString(const string& input, - Message* output) { - return Parser().MergeFromString(input, output); -} - -// =========================================================================== - -TextFormat::Printer::Printer() - : initial_indent_level_(0), - single_line_mode_(false), - use_short_repeated_primitives_(false), - utf8_string_escaping_(false) {} - -TextFormat::Printer::~Printer() {} - -bool TextFormat::Printer::PrintToString(const Message& message, - string* output) { - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - - bool result = Print(message, &output_stream); - - return result; -} - -bool TextFormat::Printer::PrintUnknownFieldsToString( - const UnknownFieldSet& unknown_fields, - string* output) { - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - return PrintUnknownFields(unknown_fields, &output_stream); -} - -bool TextFormat::Printer::Print(const Message& message, - io::ZeroCopyOutputStream* output) { - TextGenerator generator(output, initial_indent_level_); - - Print(message, generator); - - // Output false if the generator failed internally. - return !generator.failed(); -} - -bool TextFormat::Printer::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output) { - TextGenerator generator(output, initial_indent_level_); - - PrintUnknownFields(unknown_fields, generator); - - // Output false if the generator failed internally. - return !generator.failed(); -} - -void TextFormat::Printer::Print(const Message& message, - TextGenerator& generator) { - const Reflection* reflection = message.GetReflection(); - vector fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - PrintField(message, reflection, fields[i], generator); - } - PrintUnknownFields(reflection->GetUnknownFields(message), generator); -} - -void TextFormat::Printer::PrintFieldValueToString( - const Message& message, - const FieldDescriptor* field, - int index, - string* output) { - - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - TextGenerator generator(&output_stream, initial_indent_level_); - - PrintFieldValue(message, message.GetReflection(), field, index, generator); -} - -void TextFormat::Printer::PrintField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) { - if (use_short_repeated_primitives_ && - field->is_repeated() && - field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && - field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - PrintShortRepeatedField(message, reflection, field, generator); - return; - } - - int count = 0; - - if (field->is_repeated()) { - count = reflection->FieldSize(message, field); - } else if (reflection->HasField(message, field)) { - count = 1; - } - - for (int j = 0; j < count; ++j) { - PrintFieldName(message, reflection, field, generator); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (single_line_mode_) { - generator.Print(" { "); - } else { - generator.Print(" {\n"); - generator.Indent(); - } - } else { - generator.Print(": "); - } - - // Write the field value. - int field_index = j; - if (!field->is_repeated()) { - field_index = -1; - } - - PrintFieldValue(message, reflection, field, field_index, generator); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (single_line_mode_) { - generator.Print("} "); - } else { - generator.Outdent(); - generator.Print("}\n"); - } - } else { - if (single_line_mode_) { - generator.Print(" "); - } else { - generator.Print("\n"); - } - } - } -} - -void TextFormat::Printer::PrintShortRepeatedField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) { - // Print primitive repeated field in short form. - PrintFieldName(message, reflection, field, generator); - - int size = reflection->FieldSize(message, field); - generator.Print(": ["); - for (int i = 0; i < size; i++) { - if (i > 0) generator.Print(", "); - PrintFieldValue(message, reflection, field, i, generator); - } - if (single_line_mode_) { - generator.Print("] "); - } else { - generator.Print("]\n"); - } -} - -void TextFormat::Printer::PrintFieldName(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) { - if (field->is_extension()) { - generator.Print("["); - // We special-case MessageSet elements for compatibility with proto1. - if (field->containing_type()->options().message_set_wire_format() - && field->type() == FieldDescriptor::TYPE_MESSAGE - && field->is_optional() - && field->extension_scope() == field->message_type()) { - generator.Print(field->message_type()->full_name()); - } else { - generator.Print(field->full_name()); - } - generator.Print("]"); - } else { - if (field->type() == FieldDescriptor::TYPE_GROUP) { - // Groups must be serialized with their original capitalization. - generator.Print(field->message_type()->name()); - } else { - generator.Print(field->name()); - } - } -} - -void TextFormat::Printer::PrintFieldValue( - const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator) { - GOOGLE_DCHECK(field->is_repeated() || (index == -1)) - << "Index must be -1 for non-repeated fields"; - - switch (field->cpp_type()) { -#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - generator.Print(TO_STRING(field->is_repeated() ? \ - reflection->GetRepeated##METHOD(message, field, index) : \ - reflection->Get##METHOD(message, field))); \ - break; \ - - OUTPUT_FIELD( INT32, Int32, SimpleItoa); - OUTPUT_FIELD( INT64, Int64, SimpleItoa); - OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); - OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); - OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); - OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); -#undef OUTPUT_FIELD - - case FieldDescriptor::CPPTYPE_STRING: { - string scratch; - const string& value = field->is_repeated() ? - reflection->GetRepeatedStringReference( - message, field, index, &scratch) : - reflection->GetStringReference(message, field, &scratch); - - generator.Print("\""); - if (utf8_string_escaping_) { - generator.Print(strings::Utf8SafeCEscape(value)); - } else { - generator.Print(CEscape(value)); - } - generator.Print("\""); - - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: - if (field->is_repeated()) { - generator.Print(reflection->GetRepeatedBool(message, field, index) - ? "true" : "false"); - } else { - generator.Print(reflection->GetBool(message, field) - ? "true" : "false"); - } - break; - - case FieldDescriptor::CPPTYPE_ENUM: - generator.Print(field->is_repeated() ? - reflection->GetRepeatedEnum(message, field, index)->name() : - reflection->GetEnum(message, field)->name()); - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - Print(field->is_repeated() ? - reflection->GetRepeatedMessage(message, field, index) : - reflection->GetMessage(message, field), - generator); - break; - } -} - -/* static */ bool TextFormat::Print(const Message& message, - io::ZeroCopyOutputStream* output) { - return Printer().Print(message, output); -} - -/* static */ bool TextFormat::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output) { - return Printer().PrintUnknownFields(unknown_fields, output); -} - -/* static */ bool TextFormat::PrintToString( - const Message& message, string* output) { - return Printer().PrintToString(message, output); -} - -/* static */ bool TextFormat::PrintUnknownFieldsToString( - const UnknownFieldSet& unknown_fields, string* output) { - return Printer().PrintUnknownFieldsToString(unknown_fields, output); -} - -/* static */ void TextFormat::PrintFieldValueToString( - const Message& message, - const FieldDescriptor* field, - int index, - string* output) { - return Printer().PrintFieldValueToString(message, field, index, output); -} - -/* static */ bool TextFormat::ParseFieldValueFromString( - const string& input, - const FieldDescriptor* field, - Message* message) { - return Parser().ParseFieldValueFromString(input, field, message); -} - -// Prints an integer as hex with a fixed number of digits dependent on the -// integer type. -template -static string PaddedHex(IntType value) { - string result; - result.reserve(sizeof(value) * 2); - for (int i = sizeof(value) * 2 - 1; i >= 0; i--) { - result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F)); - } - return result; -} - -void TextFormat::Printer::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, TextGenerator& generator) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - string field_number = SimpleItoa(field.number()); - - switch (field.type()) { - case UnknownField::TYPE_VARINT: - generator.Print(field_number); - generator.Print(": "); - generator.Print(SimpleItoa(field.varint())); - if (single_line_mode_) { - generator.Print(" "); - } else { - generator.Print("\n"); - } - break; - case UnknownField::TYPE_FIXED32: { - generator.Print(field_number); - generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); - if (single_line_mode_) { - generator.Print(" "); - } else { - generator.Print("\n"); - } - break; - } - case UnknownField::TYPE_FIXED64: { - generator.Print(field_number); - generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); - if (single_line_mode_) { - generator.Print(" "); - } else { - generator.Print("\n"); - } - break; - } - case UnknownField::TYPE_LENGTH_DELIMITED: { - generator.Print(field_number); - const string& value = field.length_delimited(); - UnknownFieldSet embedded_unknown_fields; - if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { - // This field is parseable as a Message. - // So it is probably an embedded message. - if (single_line_mode_) { - generator.Print(" { "); - } else { - generator.Print(" {\n"); - generator.Indent(); - } - PrintUnknownFields(embedded_unknown_fields, generator); - if (single_line_mode_) { - generator.Print("} "); - } else { - generator.Outdent(); - generator.Print("}\n"); - } - } else { - // This field is not parseable as a Message. - // So it is probably just a plain string. - generator.Print(": \""); - generator.Print(CEscape(value)); - generator.Print("\""); - if (single_line_mode_) { - generator.Print(" "); - } else { - generator.Print("\n"); - } - } - break; - } - case UnknownField::TYPE_GROUP: - generator.Print(field_number); - if (single_line_mode_) { - generator.Print(" { "); - } else { - generator.Print(" {\n"); - generator.Indent(); - } - PrintUnknownFields(field.group(), generator); - if (single_line_mode_) { - generator.Print("} "); - } else { - generator.Outdent(); - generator.Print("}\n"); - } - break; - } - } -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/text_format.h b/Resources/NetHook/google/protobuf/text_format.h deleted file mode 100644 index e78e1042..00000000 --- a/Resources/NetHook/google/protobuf/text_format.h +++ /dev/null @@ -1,264 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Utilities for printing and parsing protocol messages in a human-readable, -// text-based format. - -#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ -#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ - -#include -#include -#include - -namespace google { -namespace protobuf { - -namespace io { - class ErrorCollector; // tokenizer.h -} - -// This class implements protocol buffer text format. Printing and parsing -// protocol messages in text format is useful for debugging and human editing -// of messages. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT TextFormat { - public: - // Outputs a textual representation of the given message to the given - // output stream. - static bool Print(const Message& message, io::ZeroCopyOutputStream* output); - - // Print the fields in an UnknownFieldSet. They are printed by tag number - // only. Embedded messages are heuristically identified by attempting to - // parse them. - static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output); - - // Like Print(), but outputs directly to a string. - static bool PrintToString(const Message& message, string* output); - - // Like PrintUnknownFields(), but outputs directly to a string. - static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, - string* output); - - // Outputs a textual representation of the value of the field supplied on - // the message supplied. For non-repeated fields, an index of -1 must - // be supplied. Note that this method will print the default value for a - // field if it is not set. - static void PrintFieldValueToString(const Message& message, - const FieldDescriptor* field, - int index, - string* output); - - // Class for those users which require more fine-grained control over how - // a protobuffer message is printed out. - class LIBPROTOBUF_EXPORT Printer { - public: - Printer(); - ~Printer(); - - // Like TextFormat::Print - bool Print(const Message& message, io::ZeroCopyOutputStream* output); - // Like TextFormat::PrintUnknownFields - bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output); - // Like TextFormat::PrintToString - bool PrintToString(const Message& message, string* output); - // Like TextFormat::PrintUnknownFieldsToString - bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, - string* output); - // Like TextFormat::PrintFieldValueToString - void PrintFieldValueToString(const Message& message, - const FieldDescriptor* field, - int index, - string* output); - - // Adjust the initial indent level of all output. Each indent level is - // equal to two spaces. - void SetInitialIndentLevel(int indent_level) { - initial_indent_level_ = indent_level; - } - - // If printing in single line mode, then the entire message will be output - // on a single line with no line breaks. - void SetSingleLineMode(bool single_line_mode) { - single_line_mode_ = single_line_mode; - } - - // Set true to print repeated primitives in a format like: - // field_name: [1, 2, 3, 4] - // instead of printing each value on its own line. Short format applies - // only to primitive values -- i.e. everything except strings and - // sub-messages/groups. Note that at present this format is not recognized - // by the parser. - void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { - use_short_repeated_primitives_ = use_short_repeated_primitives; - } - - // Set true to output UTF-8 instead of ASCII. The only difference - // is that bytes >= 0x80 in string fields will not be escaped, - // because they are assumed to be part of UTF-8 multi-byte - // sequences. - void SetUseUtf8StringEscaping(bool as_utf8) { - utf8_string_escaping_ = as_utf8; - } - - private: - // Forward declaration of an internal class used to print the text - // output to the OutputStream (see text_format.cc for implementation). - class TextGenerator; - - // Internal Print method, used for writing to the OutputStream via - // the TextGenerator class. - void Print(const Message& message, - TextGenerator& generator); - - // Print a single field. - void PrintField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator); - - // Print a repeated primitive field in short form. - void PrintShortRepeatedField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator); - - // Print the name of a field -- i.e. everything that comes before the - // ':' for a single name/value pair. - void PrintFieldName(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator); - - // Outputs a textual representation of the value of the field supplied on - // the message supplied or the default value if not set. - void PrintFieldValue(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator); - - // Print the fields in an UnknownFieldSet. They are printed by tag number - // only. Embedded messages are heuristically identified by attempting to - // parse them. - void PrintUnknownFields(const UnknownFieldSet& unknown_fields, - TextGenerator& generator); - - int initial_indent_level_; - - bool single_line_mode_; - - bool use_short_repeated_primitives_; - - bool utf8_string_escaping_; - }; - - // Parses a text-format protocol message from the given input stream to - // the given message object. This function parses the format written - // by Print(). - static bool Parse(io::ZeroCopyInputStream* input, Message* output); - // Like Parse(), but reads directly from a string. - static bool ParseFromString(const string& input, Message* output); - - // Like Parse(), but the data is merged into the given message, as if - // using Message::MergeFrom(). - static bool Merge(io::ZeroCopyInputStream* input, Message* output); - // Like Merge(), but reads directly from a string. - static bool MergeFromString(const string& input, Message* output); - - // Parse the given text as a single field value and store it into the - // given field of the given message. If the field is a repeated field, - // the new value will be added to the end - static bool ParseFieldValueFromString(const string& input, - const FieldDescriptor* field, - Message* message); - - // For more control over parsing, use this class. - class LIBPROTOBUF_EXPORT Parser { - public: - Parser(); - ~Parser(); - - // Like TextFormat::Parse(). - bool Parse(io::ZeroCopyInputStream* input, Message* output); - // Like TextFormat::ParseFromString(). - bool ParseFromString(const string& input, Message* output); - // Like TextFormat::Merge(). - bool Merge(io::ZeroCopyInputStream* input, Message* output); - // Like TextFormat::MergeFromString(). - bool MergeFromString(const string& input, Message* output); - - // Set where to report parse errors. If NULL (the default), errors will - // be printed to stderr. - void RecordErrorsTo(io::ErrorCollector* error_collector) { - error_collector_ = error_collector; - } - - // Normally parsing fails if, after parsing, output->IsInitialized() - // returns false. Call AllowPartialMessage(true) to skip this check. - void AllowPartialMessage(bool allow) { - allow_partial_ = allow; - } - - // Like TextFormat::ParseFieldValueFromString - bool ParseFieldValueFromString(const string& input, - const FieldDescriptor* field, - Message* output); - - private: - // Forward declaration of an internal class used to parse text - // representations (see text_format.cc for implementation). - class ParserImpl; - - // Like TextFormat::Merge(). The provided implementation is used - // to do the parsing. - bool MergeUsingImpl(io::ZeroCopyInputStream* input, - Message* output, - ParserImpl* parser_impl); - - io::ErrorCollector* error_collector_; - bool allow_partial_; - }; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ diff --git a/Resources/NetHook/google/protobuf/text_format_unittest.cc b/Resources/NetHook/google/protobuf/text_format_unittest.cc deleted file mode 100644 index ddf8ff7f..00000000 --- a/Resources/NetHook/google/protobuf/text_format_unittest.cc +++ /dev/null @@ -1,1074 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. -namespace text_format_unittest { - -inline bool IsNaN(double value) { - // NaN is never equal to anything, even itself. - return value != value; -} - -// A basic string with different escapable characters for testing. -const string kEscapeTestString = - "\"A string with ' characters \n and \r newlines and \t tabs and \001 " - "slashes \\ and multiple spaces"; - -// A representation of the above string with all the characters escaped. -const string kEscapeTestStringEscaped = - "\"\\\"A string with \\' characters \\n and \\r newlines " - "and \\t tabs and \\001 slashes \\\\ and multiple spaces\""; - -class TextFormatTest : public testing::Test { - public: - static void SetUpTestCase() { - File::ReadFileToStringOrDie( - TestSourceDir() - + "/google/protobuf/testdata/text_format_unittest_data.txt", - &static_proto_debug_string_); - } - - TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {} - - protected: - // Debug string read from text_format_unittest_data.txt. - const string proto_debug_string_; - unittest::TestAllTypes proto_; - - private: - static string static_proto_debug_string_; -}; -string TextFormatTest::static_proto_debug_string_; - -class TextFormatExtensionsTest : public testing::Test { - public: - static void SetUpTestCase() { - File::ReadFileToStringOrDie( - TestSourceDir() - + "/google/protobuf/testdata/" - "text_format_unittest_extensions_data.txt", - &static_proto_debug_string_); - } - - TextFormatExtensionsTest() - : proto_debug_string_(static_proto_debug_string_) {} - - protected: - // Debug string read from text_format_unittest_data.txt. - const string proto_debug_string_; - unittest::TestAllExtensions proto_; - - private: - static string static_proto_debug_string_; -}; -string TextFormatExtensionsTest::static_proto_debug_string_; - - -TEST_F(TextFormatTest, Basic) { - TestUtil::SetAllFields(&proto_); - EXPECT_EQ(proto_debug_string_, proto_.DebugString()); -} - -TEST_F(TextFormatExtensionsTest, Extensions) { - TestUtil::SetAllExtensions(&proto_); - EXPECT_EQ(proto_debug_string_, proto_.DebugString()); -} - -TEST_F(TextFormatTest, ShortDebugString) { - proto_.set_optional_int32(1); - proto_.set_optional_string("hello"); - proto_.mutable_optional_nested_message()->set_bb(2); - proto_.mutable_optional_foreign_message(); - - EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" " - "optional_nested_message { bb: 2 } " - "optional_foreign_message { }", - proto_.ShortDebugString()); -} - -TEST_F(TextFormatTest, ShortPrimitiveRepeateds) { - proto_.set_optional_int32(123); - proto_.add_repeated_int32(456); - proto_.add_repeated_int32(789); - proto_.add_repeated_string("foo"); - proto_.add_repeated_string("bar"); - proto_.add_repeated_nested_message()->set_bb(2); - proto_.add_repeated_nested_message()->set_bb(3); - proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO); - proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR); - - TextFormat::Printer printer; - printer.SetUseShortRepeatedPrimitives(true); - string text; - printer.PrintToString(proto_, &text); - - EXPECT_EQ("optional_int32: 123\n" - "repeated_int32: [456, 789]\n" - "repeated_string: \"foo\"\n" - "repeated_string: \"bar\"\n" - "repeated_nested_message {\n bb: 2\n}\n" - "repeated_nested_message {\n bb: 3\n}\n" - "repeated_nested_enum: [FOO, BAR]\n", - text); - - // Try in single-line mode. - printer.SetSingleLineMode(true); - printer.PrintToString(proto_, &text); - - EXPECT_EQ("optional_int32: 123 " - "repeated_int32: [456, 789] " - "repeated_string: \"foo\" " - "repeated_string: \"bar\" " - "repeated_nested_message { bb: 2 } " - "repeated_nested_message { bb: 3 } " - "repeated_nested_enum: [FOO, BAR] ", - text); -} - - -TEST_F(TextFormatTest, StringEscape) { - // Set the string value to test. - proto_.set_optional_string(kEscapeTestString); - - // Get the DebugString from the proto. - string debug_string = proto_.DebugString(); - string utf8_debug_string = proto_.Utf8DebugString(); - - // Hardcode a correct value to test against. - string correct_string = "optional_string: " - + kEscapeTestStringEscaped - + "\n"; - - // Compare. - EXPECT_EQ(correct_string, debug_string); - // UTF-8 string is the same as non-UTF-8 because - // the protocol buffer contains no UTF-8 text. - EXPECT_EQ(correct_string, utf8_debug_string); - - string expected_short_debug_string = "optional_string: " - + kEscapeTestStringEscaped; - EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString()); -} - -TEST_F(TextFormatTest, Utf8DebugString) { - // Set the string value to test. - proto_.set_optional_string("\350\260\267\346\255\214"); - - // Get the DebugString from the proto. - string debug_string = proto_.DebugString(); - string utf8_debug_string = proto_.Utf8DebugString(); - - // Hardcode a correct value to test against. - string correct_utf8_string = "optional_string: " - "\"\350\260\267\346\255\214\"" - "\n"; - string correct_string = "optional_string: " - "\"\\350\\260\\267\\346\\255\\214\"" - "\n"; - - // Compare. - EXPECT_EQ(correct_utf8_string, utf8_debug_string); - EXPECT_EQ(correct_string, debug_string); -} - -TEST_F(TextFormatTest, PrintUnknownFields) { - // Test printing of unknown fields in a message. - - unittest::TestEmptyMessage message; - UnknownFieldSet* unknown_fields = message.mutable_unknown_fields(); - - unknown_fields->AddVarint(5, 1); - unknown_fields->AddFixed32(5, 2); - unknown_fields->AddFixed64(5, 3); - unknown_fields->AddLengthDelimited(5, "4"); - unknown_fields->AddGroup(5)->AddVarint(10, 5); - - unknown_fields->AddVarint(8, 1); - unknown_fields->AddVarint(8, 2); - unknown_fields->AddVarint(8, 3); - - EXPECT_EQ( - "5: 1\n" - "5: 0x00000002\n" - "5: 0x0000000000000003\n" - "5: \"4\"\n" - "5 {\n" - " 10: 5\n" - "}\n" - "8: 1\n" - "8: 2\n" - "8: 3\n", - message.DebugString()); -} - -TEST_F(TextFormatTest, PrintUnknownMessage) { - // Test heuristic printing of messages in an UnknownFieldSet. - - protobuf_unittest::TestAllTypes message; - - // Cases which should not be interpreted as sub-messages. - - // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message - // it should be followed by 8 bytes. Since this string only has two - // subsequent bytes, it should be treated as a string. - message.add_repeated_string("abc"); - - // 'd' happens to be a valid ENDGROUP tag. So, - // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but - // the ConsumedEntireMessage() check should fail. - message.add_repeated_string("def"); - - // A zero-length string should never be interpreted as a message even though - // it is technically valid as one. - message.add_repeated_string(""); - - // Case which should be interpreted as a sub-message. - - // An actual nested message with content should always be interpreted as a - // nested message. - message.add_repeated_nested_message()->set_bb(123); - - string data; - message.SerializeToString(&data); - - string text; - UnknownFieldSet unknown_fields; - EXPECT_TRUE(unknown_fields.ParseFromString(data)); - EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text)); - EXPECT_EQ( - "44: \"abc\"\n" - "44: \"def\"\n" - "44: \"\"\n" - "48 {\n" - " 1: 123\n" - "}\n", - text); -} - -TEST_F(TextFormatTest, PrintMessageWithIndent) { - // Test adding an initial indent to printing. - - protobuf_unittest::TestAllTypes message; - - message.add_repeated_string("abc"); - message.add_repeated_string("def"); - message.add_repeated_nested_message()->set_bb(123); - - string text; - TextFormat::Printer printer; - printer.SetInitialIndentLevel(1); - EXPECT_TRUE(printer.PrintToString(message, &text)); - EXPECT_EQ( - " repeated_string: \"abc\"\n" - " repeated_string: \"def\"\n" - " repeated_nested_message {\n" - " bb: 123\n" - " }\n", - text); -} - -TEST_F(TextFormatTest, PrintMessageSingleLine) { - // Test printing a message on a single line. - - protobuf_unittest::TestAllTypes message; - - message.add_repeated_string("abc"); - message.add_repeated_string("def"); - message.add_repeated_nested_message()->set_bb(123); - - string text; - TextFormat::Printer printer; - printer.SetInitialIndentLevel(1); - printer.SetSingleLineMode(true); - EXPECT_TRUE(printer.PrintToString(message, &text)); - EXPECT_EQ( - " repeated_string: \"abc\" repeated_string: \"def\" " - "repeated_nested_message { bb: 123 } ", - text); -} - -TEST_F(TextFormatTest, ParseBasic) { - io::ArrayInputStream input_stream(proto_debug_string_.data(), - proto_debug_string_.size()); - TextFormat::Parse(&input_stream, &proto_); - TestUtil::ExpectAllFieldsSet(proto_); -} - -TEST_F(TextFormatExtensionsTest, ParseExtensions) { - io::ArrayInputStream input_stream(proto_debug_string_.data(), - proto_debug_string_.size()); - TextFormat::Parse(&input_stream, &proto_); - TestUtil::ExpectAllExtensionsSet(proto_); -} - -TEST_F(TextFormatTest, ParseStringEscape) { - // Create a parse string with escpaed characters in it. - string parse_string = "optional_string: " - + kEscapeTestStringEscaped - + "\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(kEscapeTestString, proto_.optional_string()); -} - -TEST_F(TextFormatTest, ParseConcatenatedString) { - // Create a parse string with multiple parts on one line. - string parse_string = "optional_string: \"foo\" \"bar\"\n"; - - io::ArrayInputStream input_stream1(parse_string.data(), - parse_string.size()); - TextFormat::Parse(&input_stream1, &proto_); - - // Compare. - EXPECT_EQ("foobar", proto_.optional_string()); - - // Create a parse string with multiple parts on seperate lines. - parse_string = "optional_string: \"foo\"\n" - "\"bar\"\n"; - - io::ArrayInputStream input_stream2(parse_string.data(), - parse_string.size()); - TextFormat::Parse(&input_stream2, &proto_); - - // Compare. - EXPECT_EQ("foobar", proto_.optional_string()); -} - -TEST_F(TextFormatTest, ParseFloatWithSuffix) { - // Test that we can parse a floating-point value with 'f' appended to the - // end. This is needed for backwards-compatibility with proto1. - - // Have it parse a float with the 'f' suffix. - string parse_string = "optional_float: 1.0f\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(1.0, proto_.optional_float()); -} - -TEST_F(TextFormatTest, Comments) { - // Test that comments are ignored. - - string parse_string = "optional_int32: 1 # a comment\n" - "optional_int64: 2 # another comment"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(1, proto_.optional_int32()); - EXPECT_EQ(2, proto_.optional_int64()); -} - -TEST_F(TextFormatTest, OptionalColon) { - // Test that we can place a ':' after the field name of a nested message, - // even though we don't have to. - - string parse_string = "optional_nested_message: { bb: 1}\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_TRUE(proto_.has_optional_nested_message()); - EXPECT_EQ(1, proto_.optional_nested_message().bb()); -} - -// Some platforms (e.g. Windows) insist on padding the exponent to three -// digits when one or two would be just fine. -static string RemoveRedundantZeros(string text) { - text = StringReplace(text, "e+0", "e+", true); - text = StringReplace(text, "e-0", "e-", true); - return text; -} - -TEST_F(TextFormatTest, PrintExotic) { - unittest::TestAllTypes message; - - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and - // 9223372036854775808 is outside the range of int64. However, it is not - // outside the range of uint64. Confusingly, this means that everything - // works if we make the literal unsigned, even though we are negating it. - message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808)); - message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615)); - message.add_repeated_double(123.456); - message.add_repeated_double(1.23e21); - message.add_repeated_double(1.23e-18); - message.add_repeated_double(std::numeric_limits::infinity()); - message.add_repeated_double(-std::numeric_limits::infinity()); - message.add_repeated_double(std::numeric_limits::quiet_NaN()); - message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12)); - - // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this - // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of - // the value differed from strtod()'s parsing. That is to say, the - // following assertion fails on MinGW: - // assert(1.23e22 == strtod("1.23e22", NULL)); - // As a result, SimpleDtoa() would print the value as - // "1.2300000000000001e+22" to make sure strtod() produce the exact same - // result. Our goal is to test runtime parsing, not compile-time parsing, - // so this wasn't our problem. It was found that using 1.23e21 did not - // have this problem, so we switched to that instead. - - EXPECT_EQ( - "repeated_int64: -9223372036854775808\n" - "repeated_uint64: 18446744073709551615\n" - "repeated_double: 123.456\n" - "repeated_double: 1.23e+21\n" - "repeated_double: 1.23e-18\n" - "repeated_double: inf\n" - "repeated_double: -inf\n" - "repeated_double: nan\n" - "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n", - RemoveRedundantZeros(message.DebugString())); -} - -TEST_F(TextFormatTest, PrintFloatPrecision) { - unittest::TestAllTypes message; - - message.add_repeated_float(1.2); - message.add_repeated_float(1.23); - message.add_repeated_float(1.234); - message.add_repeated_float(1.2345); - message.add_repeated_float(1.23456); - message.add_repeated_float(1.2e10); - message.add_repeated_float(1.23e10); - message.add_repeated_float(1.234e10); - message.add_repeated_float(1.2345e10); - message.add_repeated_float(1.23456e10); - message.add_repeated_double(1.2); - message.add_repeated_double(1.23); - message.add_repeated_double(1.234); - message.add_repeated_double(1.2345); - message.add_repeated_double(1.23456); - message.add_repeated_double(1.234567); - message.add_repeated_double(1.2345678); - message.add_repeated_double(1.23456789); - message.add_repeated_double(1.234567898); - message.add_repeated_double(1.2345678987); - message.add_repeated_double(1.23456789876); - message.add_repeated_double(1.234567898765); - message.add_repeated_double(1.2345678987654); - message.add_repeated_double(1.23456789876543); - message.add_repeated_double(1.2e100); - message.add_repeated_double(1.23e100); - message.add_repeated_double(1.234e100); - message.add_repeated_double(1.2345e100); - message.add_repeated_double(1.23456e100); - message.add_repeated_double(1.234567e100); - message.add_repeated_double(1.2345678e100); - message.add_repeated_double(1.23456789e100); - message.add_repeated_double(1.234567898e100); - message.add_repeated_double(1.2345678987e100); - message.add_repeated_double(1.23456789876e100); - message.add_repeated_double(1.234567898765e100); - message.add_repeated_double(1.2345678987654e100); - message.add_repeated_double(1.23456789876543e100); - - EXPECT_EQ( - "repeated_float: 1.2\n" - "repeated_float: 1.23\n" - "repeated_float: 1.234\n" - "repeated_float: 1.2345\n" - "repeated_float: 1.23456\n" - "repeated_float: 1.2e+10\n" - "repeated_float: 1.23e+10\n" - "repeated_float: 1.234e+10\n" - "repeated_float: 1.2345e+10\n" - "repeated_float: 1.23456e+10\n" - "repeated_double: 1.2\n" - "repeated_double: 1.23\n" - "repeated_double: 1.234\n" - "repeated_double: 1.2345\n" - "repeated_double: 1.23456\n" - "repeated_double: 1.234567\n" - "repeated_double: 1.2345678\n" - "repeated_double: 1.23456789\n" - "repeated_double: 1.234567898\n" - "repeated_double: 1.2345678987\n" - "repeated_double: 1.23456789876\n" - "repeated_double: 1.234567898765\n" - "repeated_double: 1.2345678987654\n" - "repeated_double: 1.23456789876543\n" - "repeated_double: 1.2e+100\n" - "repeated_double: 1.23e+100\n" - "repeated_double: 1.234e+100\n" - "repeated_double: 1.2345e+100\n" - "repeated_double: 1.23456e+100\n" - "repeated_double: 1.234567e+100\n" - "repeated_double: 1.2345678e+100\n" - "repeated_double: 1.23456789e+100\n" - "repeated_double: 1.234567898e+100\n" - "repeated_double: 1.2345678987e+100\n" - "repeated_double: 1.23456789876e+100\n" - "repeated_double: 1.234567898765e+100\n" - "repeated_double: 1.2345678987654e+100\n" - "repeated_double: 1.23456789876543e+100\n", - RemoveRedundantZeros(message.DebugString())); -} - - -TEST_F(TextFormatTest, AllowPartial) { - unittest::TestRequired message; - TextFormat::Parser parser; - parser.AllowPartialMessage(true); - EXPECT_TRUE(parser.ParseFromString("a: 1", &message)); - EXPECT_EQ(1, message.a()); - EXPECT_FALSE(message.has_b()); - EXPECT_FALSE(message.has_c()); -} - -TEST_F(TextFormatTest, ParseExotic) { - unittest::TestAllTypes message; - ASSERT_TRUE(TextFormat::ParseFromString( - "repeated_int32: -1\n" - "repeated_int32: -2147483648\n" - "repeated_int64: -1\n" - "repeated_int64: -9223372036854775808\n" - "repeated_uint32: 4294967295\n" - "repeated_uint32: 2147483648\n" - "repeated_uint64: 18446744073709551615\n" - "repeated_uint64: 9223372036854775808\n" - "repeated_double: 123.0\n" - "repeated_double: 123.5\n" - "repeated_double: 0.125\n" - "repeated_double: 1.23E17\n" - "repeated_double: 1.235E+22\n" - "repeated_double: 1.235e-18\n" - "repeated_double: 123.456789\n" - "repeated_double: inf\n" - "repeated_double: Infinity\n" - "repeated_double: -inf\n" - "repeated_double: -Infinity\n" - "repeated_double: nan\n" - "repeated_double: NaN\n" - "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n", - &message)); - - ASSERT_EQ(2, message.repeated_int32_size()); - EXPECT_EQ(-1, message.repeated_int32(0)); - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and 2147483648 is - // outside the range of int32. However, it is not outside the range of - // uint32. Confusingly, this means that everything works if we make the - // literal unsigned, even though we are negating it. - EXPECT_EQ(-2147483648u, message.repeated_int32(1)); - - ASSERT_EQ(2, message.repeated_int64_size()); - EXPECT_EQ(-1, message.repeated_int64(0)); - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and - // 9223372036854775808 is outside the range of int64. However, it is not - // outside the range of uint64. Confusingly, this means that everything - // works if we make the literal unsigned, even though we are negating it. - EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1)); - - ASSERT_EQ(2, message.repeated_uint32_size()); - EXPECT_EQ(4294967295u, message.repeated_uint32(0)); - EXPECT_EQ(2147483648u, message.repeated_uint32(1)); - - ASSERT_EQ(2, message.repeated_uint64_size()); - EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0)); - EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1)); - - ASSERT_EQ(13, message.repeated_double_size()); - EXPECT_EQ(123.0 , message.repeated_double(0)); - EXPECT_EQ(123.5 , message.repeated_double(1)); - EXPECT_EQ(0.125 , message.repeated_double(2)); - EXPECT_EQ(1.23E17 , message.repeated_double(3)); - EXPECT_EQ(1.235E22 , message.repeated_double(4)); - EXPECT_EQ(1.235E-18 , message.repeated_double(5)); - EXPECT_EQ(123.456789, message.repeated_double(6)); - EXPECT_EQ(message.repeated_double(7), numeric_limits::infinity()); - EXPECT_EQ(message.repeated_double(8), numeric_limits::infinity()); - EXPECT_EQ(message.repeated_double(9), -numeric_limits::infinity()); - EXPECT_EQ(message.repeated_double(10), -numeric_limits::infinity()); - EXPECT_TRUE(IsNaN(message.repeated_double(11))); - EXPECT_TRUE(IsNaN(message.repeated_double(12))); - - // Note: Since these string literals have \0's in them, we must explicitly - // pass their sizes to string's constructor. - ASSERT_EQ(1, message.repeated_string_size()); - EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12), - message.repeated_string(0)); -} - -class TextFormatParserTest : public testing::Test { - protected: - void ExpectFailure(const string& input, const string& message, int line, - int col) { - scoped_ptr proto(new unittest::TestAllTypes); - ExpectFailure(input, message, line, col, proto.get()); - } - - void ExpectFailure(const string& input, const string& message, int line, - int col, Message* proto) { - ExpectMessage(input, message, line, col, proto, false); - } - - void ExpectMessage(const string& input, const string& message, int line, - int col, Message* proto, bool expected_result) { - TextFormat::Parser parser; - MockErrorCollector error_collector; - parser.RecordErrorsTo(&error_collector); - EXPECT_EQ(parser.ParseFromString(input, proto), expected_result); - EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n", - error_collector.text_); - } - - // An error collector which simply concatenates all its errors into a big - // block of text which can be checked. - class MockErrorCollector : public io::ErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector ------------------------------------- - void AddError(int line, int column, const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", - line + 1, column + 1, message); - } - - void AddWarning(int line, int column, const string& message) { - AddError(line, column, "WARNING:" + message); - } - }; -}; - -TEST_F(TextFormatParserTest, ParseFieldValueFromString) { - scoped_ptr message(new unittest::TestAllTypes); - const Descriptor* d = message->GetDescriptor(); - -#define EXPECT_FIELD(name, value, valuestring) \ - EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ - valuestring, d->FindFieldByName("optional_" #name), message.get())); \ - EXPECT_EQ(value, message->optional_##name()); \ - EXPECT_TRUE(message->has_optional_##name()); - -#define EXPECT_FLOAT_FIELD(name, value, valuestring) \ - EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ - valuestring, d->FindFieldByName("optional_" #name), message.get())); \ - EXPECT_FLOAT_EQ(value, message->optional_##name()); \ - EXPECT_TRUE(message->has_optional_##name()); - -#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \ - EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ - valuestring, d->FindFieldByName("optional_" #name), message.get())); \ - EXPECT_DOUBLE_EQ(value, message->optional_##name()); \ - EXPECT_TRUE(message->has_optional_##name()); - -#define EXPECT_INVALID(name, valuestring) \ - EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \ - valuestring, d->FindFieldByName("optional_" #name), message.get())); - - // int32 - EXPECT_FIELD(int32, 1, "1"); - EXPECT_FIELD(int32, -1, "-1"); - EXPECT_FIELD(int32, 0x1234, "0x1234"); - EXPECT_INVALID(int32, "a"); - EXPECT_INVALID(int32, "999999999999999999999999999999999999"); - EXPECT_INVALID(int32, "1,2"); - - // int64 - EXPECT_FIELD(int64, 1, "1"); - EXPECT_FIELD(int64, -1, "-1"); - EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678"); - EXPECT_INVALID(int64, "a"); - EXPECT_INVALID(int64, "999999999999999999999999999999999999"); - EXPECT_INVALID(int64, "1,2"); - - // uint64 - EXPECT_FIELD(uint64, 1, "1"); - EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678"); - EXPECT_INVALID(uint64, "-1"); - EXPECT_INVALID(uint64, "a"); - EXPECT_INVALID(uint64, "999999999999999999999999999999999999"); - EXPECT_INVALID(uint64, "1,2"); - - // fixed32 - EXPECT_FIELD(fixed32, 1, "1"); - EXPECT_FIELD(fixed32, 0x12345678, "0x12345678"); - EXPECT_INVALID(fixed32, "-1"); - EXPECT_INVALID(fixed32, "a"); - EXPECT_INVALID(fixed32, "999999999999999999999999999999999999"); - EXPECT_INVALID(fixed32, "1,2"); - - // fixed64 - EXPECT_FIELD(fixed64, 1, "1"); - EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678"); - EXPECT_INVALID(fixed64, "-1"); - EXPECT_INVALID(fixed64, "a"); - EXPECT_INVALID(fixed64, "999999999999999999999999999999999999"); - EXPECT_INVALID(fixed64, "1,2"); - - // bool - EXPECT_FIELD(bool, true, "true"); - EXPECT_FIELD(bool, false, "false"); - EXPECT_INVALID(bool, "1"); - EXPECT_INVALID(bool, "on"); - EXPECT_INVALID(bool, "a"); - EXPECT_INVALID(bool, "True"); - - // float - EXPECT_FIELD(float, 1, "1"); - EXPECT_FLOAT_FIELD(float, 1.5, "1.5"); - EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3"); - EXPECT_FLOAT_FIELD(float, -4.55, "-4.55"); - EXPECT_INVALID(float, "a"); - EXPECT_INVALID(float, "1,2"); - - // double - EXPECT_FIELD(double, 1, "1"); - EXPECT_FIELD(double, -1, "-1"); - EXPECT_DOUBLE_FIELD(double, 2.3, "2.3"); - EXPECT_DOUBLE_FIELD(double, 3e5, "3e5"); - EXPECT_INVALID(double, "a"); - EXPECT_INVALID(double, "1,2"); - - // string - EXPECT_FIELD(string, "hello", "\"hello\""); - EXPECT_FIELD(string, "-1.87", "'-1.87'"); - EXPECT_INVALID(string, "hello"); // without quote for value - - // enum - EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR"); - EXPECT_INVALID(nested_enum, "1"); // number not supported - EXPECT_INVALID(nested_enum, "FOOBAR"); - - // message - EXPECT_TRUE(TextFormat::ParseFieldValueFromString( - "", d->FindFieldByName("optional_nested_message"), message.get())); - EXPECT_EQ(12, message->optional_nested_message().bb()); \ - EXPECT_TRUE(message->has_optional_nested_message()); - EXPECT_INVALID(nested_message, "any"); - -#undef EXPECT_FIELD -#undef EXPECT_FLOAT_FIELD -#undef EXPECT_DOUBLE_FIELD -#undef EXPECT_INVALID -} - - -TEST_F(TextFormatParserTest, InvalidToken) { - ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", - 2, 1); - - ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20); - ExpectFailure("\"some string\"", "Expected identifier.", 1, 1); -} - -TEST_F(TextFormatParserTest, InvalidFieldName) { - ExpectFailure( - "invalid_field: somevalue\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"invalid_field\".", - 1, 14); -} - -TEST_F(TextFormatParserTest, InvalidCapitalization) { - // We require that group names be exactly as they appear in the .proto. - ExpectFailure( - "optionalgroup {\na: 15\n}\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"optionalgroup\".", - 1, 15); - ExpectFailure( - "OPTIONALgroup {\na: 15\n}\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"OPTIONALgroup\".", - 1, 15); - ExpectFailure( - "Optional_Double: 10.0\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"Optional_Double\".", - 1, 16); -} - -TEST_F(TextFormatParserTest, InvalidFieldValues) { - // Invalid values for a double/float field. - ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: true\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: !\n", "Expected double.", 1, 18); - ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", - 1, 17); - - // Invalid values for a signed integer field. - ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", - 1, 16); - ExpectFailure("optional_int32: 0x80000000\n", - "Integer out of range.", 1, 17); - ExpectFailure("optional_int32: -0x80000001\n", - "Integer out of range.", 1, 18); - ExpectFailure("optional_int64: 0x8000000000000000\n", - "Integer out of range.", 1, 17); - ExpectFailure("optional_int64: -0x8000000000000001\n", - "Integer out of range.", 1, 18); - - // Invalid values for an unsigned integer field. - ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", - 1, 17); - ExpectFailure("optional_uint32: 0x100000000\n", - "Integer out of range.", 1, 18); - ExpectFailure("optional_uint64: 0x10000000000000000\n", - "Integer out of range.", 1, 18); - - // Invalid values for a boolean field. - ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); - - ExpectFailure( - "optional_bool: meh\n", - "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", - 2, 1); - - ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", - 1, 15); - - // Invalid values for a string field. - ExpectFailure("optional_string: true\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: !\n", "Expected string.", 1, 18); - ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", - 1, 17); - - // Invalid values for an enumeration field. - ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.", - 1, 23); - - ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23); - ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23); - ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23); - - ExpectFailure( - "optional_nested_enum: grah\n", - "Unknown enumeration value of \"grah\" for field " - "\"optional_nested_enum\".", 2, 1); - - ExpectFailure( - "optional_nested_enum {\n \n}\n", - "Expected \":\", found \"{\".", 1, 22); -} - -TEST_F(TextFormatParserTest, MessageDelimeters) { - // Non-matching delimeters. - ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", - 3, 1); - - // Invalid delimeters. - ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", - 1, 15); - - // Unending message. - ExpectFailure("optional_nested_message {\n \nbb: 118\n", - "Expected identifier.", - 4, 1); -} - -TEST_F(TextFormatParserTest, UnknownExtension) { - // Non-matching delimeters. - ExpectFailure("[blahblah]: 123", - "Extension \"blahblah\" is not defined or is not an " - "extension of \"protobuf_unittest.TestAllTypes\".", - 1, 11); -} - -TEST_F(TextFormatParserTest, MissingRequired) { - unittest::TestRequired message; - ExpectFailure("a: 1", - "Message missing required fields: b, c", - 0, 1, &message); -} - -TEST_F(TextFormatParserTest, ParseDuplicateRequired) { - unittest::TestRequired message; - ExpectFailure("a: 1 b: 2 c: 3 a: 1", - "Non-repeated field \"a\" is specified multiple times.", - 1, 17, &message); -} - -TEST_F(TextFormatParserTest, ParseDuplicateOptional) { - unittest::ForeignMessage message; - ExpectFailure("c: 1 c: 2", - "Non-repeated field \"c\" is specified multiple times.", - 1, 7, &message); -} - -TEST_F(TextFormatParserTest, MergeDuplicateRequired) { - unittest::TestRequired message; - TextFormat::Parser parser; - EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message)); - EXPECT_EQ(4, message.a()); -} - -TEST_F(TextFormatParserTest, MergeDuplicateOptional) { - unittest::ForeignMessage message; - TextFormat::Parser parser; - EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message)); - EXPECT_EQ(2, message.c()); -} - -TEST_F(TextFormatParserTest, PrintErrorsToStderr) { - vector errors; - - { - ScopedMemoryLog log; - unittest::TestAllTypes proto; - EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto)); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " - "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field " - "named \"no_such_field\".", - errors[0]); -} - -TEST_F(TextFormatParserTest, FailsOnTokenizationError) { - vector errors; - - { - ScopedMemoryLog log; - unittest::TestAllTypes proto; - EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto)); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " - "1:1: Invalid control characters encountered in text.", - errors[0]); -} - -TEST_F(TextFormatParserTest, ParseDeprecatedField) { - unittest::TestDeprecatedFields message; - ExpectMessage("deprecated_int32: 42", - "WARNING:text format contains deprecated field " - "\"deprecated_int32\"", 1, 21, &message, true); -} - -class TextFormatMessageSetTest : public testing::Test { - protected: - static const char proto_debug_string_[]; -}; -const char TextFormatMessageSetTest::proto_debug_string_[] = -"message_set {\n" -" [protobuf_unittest.TestMessageSetExtension1] {\n" -" i: 23\n" -" }\n" -" [protobuf_unittest.TestMessageSetExtension2] {\n" -" str: \"foo\"\n" -" }\n" -"}\n"; - - -TEST_F(TextFormatMessageSetTest, Serialize) { - protobuf_unittest::TestMessageSetContainer proto; - protobuf_unittest::TestMessageSetExtension1* item_a = - proto.mutable_message_set()->MutableExtension( - protobuf_unittest::TestMessageSetExtension1::message_set_extension); - item_a->set_i(23); - protobuf_unittest::TestMessageSetExtension2* item_b = - proto.mutable_message_set()->MutableExtension( - protobuf_unittest::TestMessageSetExtension2::message_set_extension); - item_b->set_str("foo"); - EXPECT_EQ(proto_debug_string_, proto.DebugString()); -} - -TEST_F(TextFormatMessageSetTest, Deserialize) { - protobuf_unittest::TestMessageSetContainer proto; - ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto)); - EXPECT_EQ(23, proto.message_set().GetExtension( - protobuf_unittest::TestMessageSetExtension1::message_set_extension).i()); - EXPECT_EQ("foo", proto.message_set().GetExtension( - protobuf_unittest::TestMessageSetExtension2::message_set_extension).str()); - - // Ensure that these are the only entries present. - vector descriptors; - proto.message_set().GetReflection()->ListFields( - proto.message_set(), &descriptors); - EXPECT_EQ(2, descriptors.size()); -} - -} // namespace text_format_unittest -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/unittest.proto b/Resources/NetHook/google/protobuf/unittest.proto deleted file mode 100644 index d51fa1e7..00000000 --- a/Resources/NetHook/google/protobuf/unittest.proto +++ /dev/null @@ -1,612 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. - - -import "google/protobuf/unittest_import.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; - -option java_outer_classname = "UnittestProto"; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessage optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessage optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnum optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR ]; - optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum = 83 [default = IMPORT_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; -} - -message TestDeprecatedFields { - optional int32 deprecated_int32 = 1 [deprecated=true]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestAllExtensions { - extensions 1 to max; -} - -extend TestAllExtensions { - // Singular - optional int32 optional_int32_extension = 1; - optional int64 optional_int64_extension = 2; - optional uint32 optional_uint32_extension = 3; - optional uint64 optional_uint64_extension = 4; - optional sint32 optional_sint32_extension = 5; - optional sint64 optional_sint64_extension = 6; - optional fixed32 optional_fixed32_extension = 7; - optional fixed64 optional_fixed64_extension = 8; - optional sfixed32 optional_sfixed32_extension = 9; - optional sfixed64 optional_sfixed64_extension = 10; - optional float optional_float_extension = 11; - optional double optional_double_extension = 12; - optional bool optional_bool_extension = 13; - optional string optional_string_extension = 14; - optional bytes optional_bytes_extension = 15; - - optional group OptionalGroup_extension = 16 { - optional int32 a = 17; - } - - optional TestAllTypes.NestedMessage optional_nested_message_extension = 18; - optional ForeignMessage optional_foreign_message_extension = 19; - optional protobuf_unittest_import.ImportMessage - optional_import_message_extension = 20; - - optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21; - optional ForeignEnum optional_foreign_enum_extension = 22; - optional protobuf_unittest_import.ImportEnum - optional_import_enum_extension = 23; - - optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32_extension = 31; - repeated int64 repeated_int64_extension = 32; - repeated uint32 repeated_uint32_extension = 33; - repeated uint64 repeated_uint64_extension = 34; - repeated sint32 repeated_sint32_extension = 35; - repeated sint64 repeated_sint64_extension = 36; - repeated fixed32 repeated_fixed32_extension = 37; - repeated fixed64 repeated_fixed64_extension = 38; - repeated sfixed32 repeated_sfixed32_extension = 39; - repeated sfixed64 repeated_sfixed64_extension = 40; - repeated float repeated_float_extension = 41; - repeated double repeated_double_extension = 42; - repeated bool repeated_bool_extension = 43; - repeated string repeated_string_extension = 44; - repeated bytes repeated_bytes_extension = 45; - - repeated group RepeatedGroup_extension = 46 { - optional int32 a = 47; - } - - repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48; - repeated ForeignMessage repeated_foreign_message_extension = 49; - repeated protobuf_unittest_import.ImportMessage - repeated_import_message_extension = 50; - - repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; - repeated ForeignEnum repeated_foreign_enum_extension = 52; - repeated protobuf_unittest_import.ImportEnum - repeated_import_enum_extension = 53; - - repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32_extension = 61 [default = 41 ]; - optional int64 default_int64_extension = 62 [default = 42 ]; - optional uint32 default_uint32_extension = 63 [default = 43 ]; - optional uint64 default_uint64_extension = 64 [default = 44 ]; - optional sint32 default_sint32_extension = 65 [default = -45 ]; - optional sint64 default_sint64_extension = 66 [default = 46 ]; - optional fixed32 default_fixed32_extension = 67 [default = 47 ]; - optional fixed64 default_fixed64_extension = 68 [default = 48 ]; - optional sfixed32 default_sfixed32_extension = 69 [default = 49 ]; - optional sfixed64 default_sfixed64_extension = 70 [default = -50 ]; - optional float default_float_extension = 71 [default = 51.5 ]; - optional double default_double_extension = 72 [default = 52e3 ]; - optional bool default_bool_extension = 73 [default = true ]; - optional string default_string_extension = 74 [default = "hello"]; - optional bytes default_bytes_extension = 75 [default = "world"]; - - optional TestAllTypes.NestedEnum - default_nested_enum_extension = 81 [default = BAR]; - optional ForeignEnum - default_foreign_enum_extension = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum_extension = 83 [default = IMPORT_BAR]; - - optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, - default="abc"]; - optional string default_cord_extension = 85 [ctype=CORD, default="123"]; -} - -message TestNestedExtension { - extend TestAllExtensions { - // Check for bug where string extensions declared in tested scope did not - // compile. - optional string test = 1002 [default="test"]; - } -} - -// We have separate messages for testing required fields because it's -// annoying to have to fill in required fields in TestProto in order to -// do anything with it. Note that we don't need to test every type of -// required filed because the code output is basically identical to -// optional fields for all types. -message TestRequired { - required int32 a = 1; - optional int32 dummy2 = 2; - required int32 b = 3; - - extend TestAllExtensions { - optional TestRequired single = 1000; - repeated TestRequired multi = 1001; - } - - // Pad the field count to 32 so that we can test that IsInitialized() - // properly checks multiple elements of has_bits_. - optional int32 dummy4 = 4; - optional int32 dummy5 = 5; - optional int32 dummy6 = 6; - optional int32 dummy7 = 7; - optional int32 dummy8 = 8; - optional int32 dummy9 = 9; - optional int32 dummy10 = 10; - optional int32 dummy11 = 11; - optional int32 dummy12 = 12; - optional int32 dummy13 = 13; - optional int32 dummy14 = 14; - optional int32 dummy15 = 15; - optional int32 dummy16 = 16; - optional int32 dummy17 = 17; - optional int32 dummy18 = 18; - optional int32 dummy19 = 19; - optional int32 dummy20 = 20; - optional int32 dummy21 = 21; - optional int32 dummy22 = 22; - optional int32 dummy23 = 23; - optional int32 dummy24 = 24; - optional int32 dummy25 = 25; - optional int32 dummy26 = 26; - optional int32 dummy27 = 27; - optional int32 dummy28 = 28; - optional int32 dummy29 = 29; - optional int32 dummy30 = 30; - optional int32 dummy31 = 31; - optional int32 dummy32 = 32; - - required int32 c = 33; -} - -message TestRequiredForeign { - optional TestRequired optional_message = 1; - repeated TestRequired repeated_message = 2; - optional int32 dummy = 3; -} - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - optional TestAllTypes.NestedMessage foreign_nested = 1; -} - -// TestEmptyMessage is used to test unknown field support. -message TestEmptyMessage { -} - -// Like above, but declare all field numbers as potential extensions. No -// actual extensions should ever be defined for this type. -message TestEmptyMessageWithExtensions { - extensions 1 to max; -} - -message TestMultipleExtensionRanges { - extensions 42; - extensions 4143 to 4243; - extensions 65536 to max; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - optional int32 a = 1; - optional int32 bb = 268435455; -} - -message TestRecursiveMessage { - optional TestRecursiveMessage a = 1; - optional int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - optional TestMutualRecursionB bb = 1; -} - -message TestMutualRecursionB { - optional TestMutualRecursionA a = 1; - optional int32 optional_int32 = 2; -} - -// Test that groups have disjoint field numbers from their siblings and -// parents. This is NOT possible in proto1; only proto2. When attempting -// to compile with proto1, this will emit an error; so we only include it -// in protobuf_unittest_proto. -message TestDupFieldNumber { // NO_PROTO1 - optional int32 a = 1; // NO_PROTO1 - optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1 - optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1 -} // NO_PROTO1 - - -// Needed for a Python test. -message TestNestedMessageHasBits { - message NestedMessage { - repeated int32 nestedmessage_repeated_int32 = 1; - repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2; - } - optional NestedMessage optional_nested_message = 1; -} - - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - optional int32 PrimitiveField = 1; - optional string StringField = 2; - optional ForeignEnum EnumField = 3; - optional ForeignMessage MessageField = 4; - optional string StringPieceField = 5 [ctype=STRING_PIECE]; - optional string CordField = 6 [ctype=CORD]; - - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; - repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE]; - repeated string RepeatedCordField = 12 [ctype=CORD]; -} - - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - optional string my_string = 11; - extensions 2 to 10; - optional int64 my_int = 1; - extensions 12 to 100; - optional float my_float = 101; -} - - -extend TestFieldOrderings { - optional string my_extension_string = 50; - optional int32 my_extension_int = 5; -} - - -message TestExtremeDefaultValues { - optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; - optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF]; - optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF]; - optional int32 small_int32 = 4 [default = -0x7FFFFFFF]; - optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF]; - - // The default value here is UTF-8 for "\u1234". (We could also just type - // the UTF-8 text directly into this text file rather than escape it, but - // lots of people use editors that would be confused by this.) - optional string utf8_string = 6 [default = "\341\210\264"]; - - // Tests for single-precision floating-point values. - optional float zero_float = 7 [default = 0]; - optional float one_float = 8 [default = 1]; - optional float small_float = 9 [default = 1.5]; - optional float negative_one_float = 10 [default = -1]; - optional float negative_float = 11 [default = -1.5]; - // Using exponents - optional float large_float = 12 [default = 2E8]; - optional float small_negative_float = 13 [default = -8e-28]; - - // Text for nonfinite floating-point values. - optional double inf_double = 14 [default = inf]; - optional double neg_inf_double = 15 [default = -inf]; - optional double nan_double = 16 [default = nan]; - optional float inf_float = 17 [default = inf]; - optional float neg_inf_float = 18 [default = -inf]; - optional float nan_float = 19 [default = nan]; -} - -// Test String and Bytes: string is for valid UTF-8 strings -message OneString { - optional string data = 1; -} - -message OneBytes { - optional bytes data = 1; -} - -// Test messages for packed fields - -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// A message with the same fields as TestPackedTypes, but without packing. Used -// to test packed <-> unpacked wire compatibility. -message TestUnpackedTypes { - repeated int32 unpacked_int32 = 90 [packed = false]; - repeated int64 unpacked_int64 = 91 [packed = false]; - repeated uint32 unpacked_uint32 = 92 [packed = false]; - repeated uint64 unpacked_uint64 = 93 [packed = false]; - repeated sint32 unpacked_sint32 = 94 [packed = false]; - repeated sint64 unpacked_sint64 = 95 [packed = false]; - repeated fixed32 unpacked_fixed32 = 96 [packed = false]; - repeated fixed64 unpacked_fixed64 = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; - repeated float unpacked_float = 100 [packed = false]; - repeated double unpacked_double = 101 [packed = false]; - repeated bool unpacked_bool = 102 [packed = false]; - repeated ForeignEnum unpacked_enum = 103 [packed = false]; -} - -message TestPackedExtensions { - extensions 1 to max; -} - -extend TestPackedExtensions { - repeated int32 packed_int32_extension = 90 [packed = true]; - repeated int64 packed_int64_extension = 91 [packed = true]; - repeated uint32 packed_uint32_extension = 92 [packed = true]; - repeated uint64 packed_uint64_extension = 93 [packed = true]; - repeated sint32 packed_sint32_extension = 94 [packed = true]; - repeated sint64 packed_sint64_extension = 95 [packed = true]; - repeated fixed32 packed_fixed32_extension = 96 [packed = true]; - repeated fixed64 packed_fixed64_extension = 97 [packed = true]; - repeated sfixed32 packed_sfixed32_extension = 98 [packed = true]; - repeated sfixed64 packed_sfixed64_extension = 99 [packed = true]; - repeated float packed_float_extension = 100 [packed = true]; - repeated double packed_double_extension = 101 [packed = true]; - repeated bool packed_bool_extension = 102 [packed = true]; - repeated ForeignEnum packed_enum_extension = 103 [packed = true]; -} - -// Used by ExtensionSetTest/DynamicExtensions. The test actually builds -// a set of extensions to TestAllExtensions dynamically, based on the fields -// of this message type. -message TestDynamicExtensions { - enum DynamicEnumType { - DYNAMIC_FOO = 2200; - DYNAMIC_BAR = 2201; - DYNAMIC_BAZ = 2202; - } - message DynamicMessageType { - optional int32 dynamic_field = 2100; - } - - optional fixed32 scalar_extension = 2000; - optional ForeignEnum enum_extension = 2001; - optional DynamicEnumType dynamic_enum_extension = 2002; - - optional ForeignMessage message_extension = 2003; - optional DynamicMessageType dynamic_message_extension = 2004; - - repeated string repeated_extension = 2005; - repeated sint32 packed_extension = 2006 [packed = true]; -} - -message TestRepeatedScalarDifferentTagSizes { - // Parsing repeated fixed size values used to fail. This message needs to be - // used in order to get a tag of the right size; all of the repeated fields - // in TestAllTypes didn't trigger the check. - repeated fixed32 repeated_fixed32 = 12; - // Check for a varint type, just for good measure. - repeated int32 repeated_int32 = 13; - - // These have two-byte tags. - repeated fixed64 repeated_fixed64 = 2046; - repeated int64 repeated_int64 = 2047; - - // Three byte tags. - repeated float repeated_float = 262142; - repeated uint64 repeated_uint64 = 262143; -} - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} - -service TestService { - rpc Foo(FooRequest) returns (FooResponse); - rpc Bar(BarRequest) returns (BarResponse); -} - - -message BarRequest {} -message BarResponse {} diff --git a/Resources/NetHook/google/protobuf/unittest_custom_options.proto b/Resources/NetHook/google/protobuf/unittest_custom_options.proto deleted file mode 100644 index b6ee03da..00000000 --- a/Resources/NetHook/google/protobuf/unittest_custom_options.proto +++ /dev/null @@ -1,275 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: benjy@google.com (Benjy Weinberger) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file used to test the "custom options" feature of proto2. - - -// A custom file option (defined below). -option (file_opt1) = 9876543210; - -import "google/protobuf/descriptor.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -package protobuf_unittest; - - -// Some simple test custom options of various types. - -extend google.protobuf.FileOptions { - optional uint64 file_opt1 = 7736974; -} - -extend google.protobuf.MessageOptions { - optional int32 message_opt1 = 7739036; -} - -extend google.protobuf.FieldOptions { - optional fixed64 field_opt1 = 7740936; - // This is useful for testing that we correctly register default values for - // extension options. - optional int32 field_opt2 = 7753913 [default=42]; -} - -extend google.protobuf.EnumOptions { - optional sfixed32 enum_opt1 = 7753576; -} - -extend google.protobuf.EnumValueOptions { - optional int32 enum_value_opt1 = 1560678; -} - -extend google.protobuf.ServiceOptions { - optional sint64 service_opt1 = 7887650; -} - -enum MethodOpt1 { - METHODOPT1_VAL1 = 1; - METHODOPT1_VAL2 = 2; -} - -extend google.protobuf.MethodOptions { - optional MethodOpt1 method_opt1 = 7890860; -} - -// A test message with custom options at all possible locations (and also some -// regular options, to make sure they interact nicely). -message TestMessageWithCustomOptions { - option message_set_wire_format = false; - - option (message_opt1) = -56; - - optional string field1 = 1 [ctype=CORD, - (field_opt1)=8765432109]; - - enum AnEnum { - option (enum_opt1) = -789; - - ANENUM_VAL1 = 1; - ANENUM_VAL2 = 2 [(enum_value_opt1) = 123]; - } -} - - -// A test RPC service with custom options at all possible locations (and also -// some regular options, to make sure they interact nicely). -message CustomOptionFooRequest { -} - -message CustomOptionFooResponse { -} - -service TestServiceWithCustomOptions { - option (service_opt1) = -9876543210; - - rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) { - option (method_opt1) = METHODOPT1_VAL2; - } -} - - - -// Options of every possible field type, so we can test them all exhaustively. - -message DummyMessageContainingEnum { - enum TestEnumType { - TEST_OPTION_ENUM_TYPE1 = 22; - TEST_OPTION_ENUM_TYPE2 = -23; - } -} - -message DummyMessageInvalidAsOptionType { -} - -extend google.protobuf.MessageOptions { - optional bool bool_opt = 7706090; - optional int32 int32_opt = 7705709; - optional int64 int64_opt = 7705542; - optional uint32 uint32_opt = 7704880; - optional uint64 uint64_opt = 7702367; - optional sint32 sint32_opt = 7701568; - optional sint64 sint64_opt = 7700863; - optional fixed32 fixed32_opt = 7700307; - optional fixed64 fixed64_opt = 7700194; - optional sfixed32 sfixed32_opt = 7698645; - optional sfixed64 sfixed64_opt = 7685475; - optional float float_opt = 7675390; - optional double double_opt = 7673293; - optional string string_opt = 7673285; - optional bytes bytes_opt = 7673238; - optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233; - optional DummyMessageInvalidAsOptionType message_type_opt = 7665967; -} - -message CustomOptionMinIntegerValues { - option (bool_opt) = false; - option (int32_opt) = -0x80000000; - option (int64_opt) = -0x8000000000000000; - option (uint32_opt) = 0; - option (uint64_opt) = 0; - option (sint32_opt) = -0x80000000; - option (sint64_opt) = -0x8000000000000000; - option (fixed32_opt) = 0; - option (fixed64_opt) = 0; - option (sfixed32_opt) = -0x80000000; - option (sfixed64_opt) = -0x8000000000000000; -} - -message CustomOptionMaxIntegerValues { - option (bool_opt) = true; - option (int32_opt) = 0x7FFFFFFF; - option (int64_opt) = 0x7FFFFFFFFFFFFFFF; - option (uint32_opt) = 0xFFFFFFFF; - option (uint64_opt) = 0xFFFFFFFFFFFFFFFF; - option (sint32_opt) = 0x7FFFFFFF; - option (sint64_opt) = 0x7FFFFFFFFFFFFFFF; - option (fixed32_opt) = 0xFFFFFFFF; - option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF; - option (sfixed32_opt) = 0x7FFFFFFF; - option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF; -} - -message CustomOptionOtherValues { - option (int32_opt) = -100; // To test sign-extension. - option (float_opt) = 12.3456789; - option (double_opt) = 1.234567890123456789; - option (string_opt) = "Hello, \"World\""; - option (bytes_opt) = "Hello\0World"; - option (enum_opt) = TEST_OPTION_ENUM_TYPE2; -} - -message SettingRealsFromPositiveInts { - option (float_opt) = 12; - option (double_opt) = 154; -} - -message SettingRealsFromNegativeInts { - option (float_opt) = -12; - option (double_opt) = -154; -} - -// Options of complex message types, themselves combined and extended in -// various ways. - -message ComplexOptionType1 { - optional int32 foo = 1; - optional int32 foo2 = 2; - optional int32 foo3 = 3; - - extensions 100 to max; -} - -message ComplexOptionType2 { - optional ComplexOptionType1 bar = 1; - optional int32 baz = 2; - - message ComplexOptionType4 { - optional int32 waldo = 1; - - extend google.protobuf.MessageOptions { - optional ComplexOptionType4 complex_opt4 = 7633546; - } - } - - optional ComplexOptionType4 fred = 3; - - extensions 100 to max; -} - -message ComplexOptionType3 { - optional int32 qux = 1; - - optional group ComplexOptionType5 = 2 { - optional int32 plugh = 3; - } -} - -extend ComplexOptionType1 { - optional int32 quux = 7663707; - optional ComplexOptionType3 corge = 7663442; -} - -extend ComplexOptionType2 { - optional int32 grault = 7650927; - optional ComplexOptionType1 garply = 7649992; -} - -extend google.protobuf.MessageOptions { - optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756; - optional ComplexOptionType2 complex_opt2 = 7636949; - optional ComplexOptionType3 complex_opt3 = 7636463; - optional group ComplexOpt6 = 7595468 { - optional int32 xyzzy = 7593951; - } -} - -// Note that we try various different ways of naming the same extension. -message VariousComplexOptions { - option (.protobuf_unittest.complex_opt1).foo = 42; - option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324; - option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876; - option (complex_opt2).baz = 987; - option (complex_opt2).(grault) = 654; - option (complex_opt2).bar.foo = 743; - option (complex_opt2).bar.(quux) = 1999; - option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008; - option (complex_opt2).(garply).foo = 741; - option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998; - option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121; - option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971; - option (complex_opt2).fred.waldo = 321; - option (protobuf_unittest.complex_opt3).qux = 9; - option (complex_opt3).complexoptiontype5.plugh = 22; - option (complexopt6).xyzzy = 24; -} diff --git a/Resources/NetHook/google/protobuf/unittest_embed_optimize_for.proto b/Resources/NetHook/google/protobuf/unittest_embed_optimize_for.proto deleted file mode 100644 index fa176259..00000000 --- a/Resources/NetHook/google/protobuf/unittest_embed_optimize_for.proto +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which imports a proto file that uses optimize_for = CODE_SIZE. - -import "google/protobuf/unittest_optimize_for.proto"; - -package protobuf_unittest; - -// We optimize for speed here, but we are importing a proto that is optimized -// for code size. -option optimize_for = SPEED; - -message TestEmbedOptimizedForSize { - // Test that embedding a message which has optimize_for = CODE_SIZE into - // one optimized for speed works. - optional TestOptimizedForSize optional_message = 1; - repeated TestOptimizedForSize repeated_message = 2; -} diff --git a/Resources/NetHook/google/protobuf/unittest_empty.proto b/Resources/NetHook/google/protobuf/unittest_empty.proto deleted file mode 100644 index ab12d1fb..00000000 --- a/Resources/NetHook/google/protobuf/unittest_empty.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file intentionally left blank. (At one point this wouldn't compile -// correctly.) - diff --git a/Resources/NetHook/google/protobuf/unittest_enormous_descriptor.proto b/Resources/NetHook/google/protobuf/unittest_enormous_descriptor.proto deleted file mode 100644 index bc0b7c16..00000000 --- a/Resources/NetHook/google/protobuf/unittest_enormous_descriptor.proto +++ /dev/null @@ -1,1046 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file that has an extremely large descriptor. Used to test that -// descriptors over 64k don't break the string literal length limit in Java. - - -package google.protobuf; -option java_package = "com.google.protobuf"; - -// Avoid generating insanely long methods. -option optimize_for = CODE_SIZE; - -message TestEnormousDescriptor { - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; - optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; -} diff --git a/Resources/NetHook/google/protobuf/unittest_import.proto b/Resources/NetHook/google/protobuf/unittest_import.proto deleted file mode 100644 index cd533ecd..00000000 --- a/Resources/NetHook/google/protobuf/unittest_import.proto +++ /dev/null @@ -1,61 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which is imported by unittest.proto to test importing. - - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do -// "using namespace unittest_import = protobuf_unittest_import". -package protobuf_unittest_import; - -option optimize_for = SPEED; - -// Excercise the java_package option. -option java_package = "com.google.protobuf.test"; - -// Do not set a java_outer_classname here to verify that Proto2 works without -// one. - -message ImportMessage { - optional int32 d = 1; -} - -enum ImportEnum { - IMPORT_FOO = 7; - IMPORT_BAR = 8; - IMPORT_BAZ = 9; -} - diff --git a/Resources/NetHook/google/protobuf/unittest_import_lite.proto b/Resources/NetHook/google/protobuf/unittest_import_lite.proto deleted file mode 100644 index ebaab5c0..00000000 --- a/Resources/NetHook/google/protobuf/unittest_import_lite.proto +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME. - -package protobuf_unittest_import; - -option optimize_for = LITE_RUNTIME; - -option java_package = "com.google.protobuf"; - -message ImportMessageLite { - optional int32 d = 1; -} - -enum ImportEnumLite { - IMPORT_LITE_FOO = 7; - IMPORT_LITE_BAR = 8; - IMPORT_LITE_BAZ = 9; -} diff --git a/Resources/NetHook/google/protobuf/unittest_lite.proto b/Resources/NetHook/google/protobuf/unittest_lite.proto deleted file mode 100644 index cca6b497..00000000 --- a/Resources/NetHook/google/protobuf/unittest_lite.proto +++ /dev/null @@ -1,312 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// This is like unittest.proto but with optimize_for = LITE_RUNTIME. - -package protobuf_unittest; - -import "google/protobuf/unittest_import_lite.proto"; - -option optimize_for = LITE_RUNTIME; - -option java_package = "com.google.protobuf"; - -// Same as TestAllTypes but with the lite runtime. -message TestAllTypesLite { - message NestedMessage { - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessageLite optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessageLite - optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnumLite optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessageLite repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessageLite - repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnumLite repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR]; - optional ForeignEnumLite default_foreign_enum = 82 - [default = FOREIGN_LITE_BAR]; - optional protobuf_unittest_import.ImportEnumLite - default_import_enum = 83 [default = IMPORT_LITE_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; -} - -message ForeignMessageLite { - optional int32 c = 1; -} - -enum ForeignEnumLite { - FOREIGN_LITE_FOO = 4; - FOREIGN_LITE_BAR = 5; - FOREIGN_LITE_BAZ = 6; -} - -message TestPackedTypesLite { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnumLite packed_enum = 103 [packed = true]; -} - -message TestAllExtensionsLite { - extensions 1 to max; -} - -extend TestAllExtensionsLite { - // Singular - optional int32 optional_int32_extension_lite = 1; - optional int64 optional_int64_extension_lite = 2; - optional uint32 optional_uint32_extension_lite = 3; - optional uint64 optional_uint64_extension_lite = 4; - optional sint32 optional_sint32_extension_lite = 5; - optional sint64 optional_sint64_extension_lite = 6; - optional fixed32 optional_fixed32_extension_lite = 7; - optional fixed64 optional_fixed64_extension_lite = 8; - optional sfixed32 optional_sfixed32_extension_lite = 9; - optional sfixed64 optional_sfixed64_extension_lite = 10; - optional float optional_float_extension_lite = 11; - optional double optional_double_extension_lite = 12; - optional bool optional_bool_extension_lite = 13; - optional string optional_string_extension_lite = 14; - optional bytes optional_bytes_extension_lite = 15; - - optional group OptionalGroup_extension_lite = 16 { - optional int32 a = 17; - } - - optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite - = 18; - optional ForeignMessageLite optional_foreign_message_extension_lite = 19; - optional protobuf_unittest_import.ImportMessageLite - optional_import_message_extension_lite = 20; - - optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21; - optional ForeignEnumLite optional_foreign_enum_extension_lite = 22; - optional protobuf_unittest_import.ImportEnumLite - optional_import_enum_extension_lite = 23; - - optional string optional_string_piece_extension_lite = 24 - [ctype=STRING_PIECE]; - optional string optional_cord_extension_lite = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32_extension_lite = 31; - repeated int64 repeated_int64_extension_lite = 32; - repeated uint32 repeated_uint32_extension_lite = 33; - repeated uint64 repeated_uint64_extension_lite = 34; - repeated sint32 repeated_sint32_extension_lite = 35; - repeated sint64 repeated_sint64_extension_lite = 36; - repeated fixed32 repeated_fixed32_extension_lite = 37; - repeated fixed64 repeated_fixed64_extension_lite = 38; - repeated sfixed32 repeated_sfixed32_extension_lite = 39; - repeated sfixed64 repeated_sfixed64_extension_lite = 40; - repeated float repeated_float_extension_lite = 41; - repeated double repeated_double_extension_lite = 42; - repeated bool repeated_bool_extension_lite = 43; - repeated string repeated_string_extension_lite = 44; - repeated bytes repeated_bytes_extension_lite = 45; - - repeated group RepeatedGroup_extension_lite = 46 { - optional int32 a = 47; - } - - repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite - = 48; - repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49; - repeated protobuf_unittest_import.ImportMessageLite - repeated_import_message_extension_lite = 50; - - repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51; - repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52; - repeated protobuf_unittest_import.ImportEnumLite - repeated_import_enum_extension_lite = 53; - - repeated string repeated_string_piece_extension_lite = 54 - [ctype=STRING_PIECE]; - repeated string repeated_cord_extension_lite = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32_extension_lite = 61 [default = 41 ]; - optional int64 default_int64_extension_lite = 62 [default = 42 ]; - optional uint32 default_uint32_extension_lite = 63 [default = 43 ]; - optional uint64 default_uint64_extension_lite = 64 [default = 44 ]; - optional sint32 default_sint32_extension_lite = 65 [default = -45 ]; - optional sint64 default_sint64_extension_lite = 66 [default = 46 ]; - optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ]; - optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ]; - optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ]; - optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ]; - optional float default_float_extension_lite = 71 [default = 51.5 ]; - optional double default_double_extension_lite = 72 [default = 52e3 ]; - optional bool default_bool_extension_lite = 73 [default = true ]; - optional string default_string_extension_lite = 74 [default = "hello"]; - optional bytes default_bytes_extension_lite = 75 [default = "world"]; - - optional TestAllTypesLite.NestedEnum - default_nested_enum_extension_lite = 81 [default = BAR]; - optional ForeignEnumLite - default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR]; - optional protobuf_unittest_import.ImportEnumLite - default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR]; - - optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE, - default="abc"]; - optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"]; -} - -message TestPackedExtensionsLite { - extensions 1 to max; -} - -extend TestPackedExtensionsLite { - repeated int32 packed_int32_extension_lite = 90 [packed = true]; - repeated int64 packed_int64_extension_lite = 91 [packed = true]; - repeated uint32 packed_uint32_extension_lite = 92 [packed = true]; - repeated uint64 packed_uint64_extension_lite = 93 [packed = true]; - repeated sint32 packed_sint32_extension_lite = 94 [packed = true]; - repeated sint64 packed_sint64_extension_lite = 95 [packed = true]; - repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true]; - repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true]; - repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true]; - repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true]; - repeated float packed_float_extension_lite = 100 [packed = true]; - repeated double packed_double_extension_lite = 101 [packed = true]; - repeated bool packed_bool_extension_lite = 102 [packed = true]; - repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true]; -} - -message TestNestedExtensionLite { - extend TestAllExtensionsLite { - optional int32 nested_extension = 12345; - } -} - -// Test that deprecated fields work. We only verify that they compile (at one -// point this failed). -message TestDeprecatedLite { - optional int32 deprecated_field = 1 [deprecated = true]; -} diff --git a/Resources/NetHook/google/protobuf/unittest_lite_imports_nonlite.proto b/Resources/NetHook/google/protobuf/unittest_lite_imports_nonlite.proto deleted file mode 100644 index d52cb8cc..00000000 --- a/Resources/NetHook/google/protobuf/unittest_lite_imports_nonlite.proto +++ /dev/null @@ -1,43 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// -// Tests that a "lite" message can import a regular message. - -package protobuf_unittest; - -import "google/protobuf/unittest.proto"; - -option optimize_for = LITE_RUNTIME; - -message TestLiteImportsNonlite { - optional TestAllTypes message = 1; -} diff --git a/Resources/NetHook/google/protobuf/unittest_mset.proto b/Resources/NetHook/google/protobuf/unittest_mset.proto deleted file mode 100644 index 3497f09f..00000000 --- a/Resources/NetHook/google/protobuf/unittest_mset.proto +++ /dev/null @@ -1,72 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains messages for testing message_set_wire_format. - -package protobuf_unittest; - -option optimize_for = SPEED; - -// A message with message_set_wire_format. -message TestMessageSet { - option message_set_wire_format = true; - extensions 4 to max; -} - -message TestMessageSetContainer { - optional TestMessageSet message_set = 1; -} - -message TestMessageSetExtension1 { - extend TestMessageSet { - optional TestMessageSetExtension1 message_set_extension = 1545008; - } - optional int32 i = 15; -} - -message TestMessageSetExtension2 { - extend TestMessageSet { - optional TestMessageSetExtension2 message_set_extension = 1547769; - } - optional string str = 25; -} - -// MessageSet wire format is equivalent to this. -message RawMessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required bytes message = 3; - } -} - diff --git a/Resources/NetHook/google/protobuf/unittest_no_generic_services.proto b/Resources/NetHook/google/protobuf/unittest_no_generic_services.proto deleted file mode 100644 index fcae4214..00000000 --- a/Resources/NetHook/google/protobuf/unittest_no_generic_services.proto +++ /dev/null @@ -1,54 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) - -package google.protobuf.no_generic_services_test; - -option cc_generic_services = false; -option java_generic_services = false; -option py_generic_services = false; - -message TestMessage { - optional int32 a = 1; - extensions 1000 to max; -} - -enum TestEnum { - FOO = 1; -} - -extend TestMessage { - optional int32 test_extension = 1000; -} - -service TestService { - rpc Foo(TestMessage) returns(TestMessage); -} diff --git a/Resources/NetHook/google/protobuf/unittest_optimize_for.proto b/Resources/NetHook/google/protobuf/unittest_optimize_for.proto deleted file mode 100644 index feecbef8..00000000 --- a/Resources/NetHook/google/protobuf/unittest_optimize_for.proto +++ /dev/null @@ -1,61 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which uses optimize_for = CODE_SIZE. - -import "google/protobuf/unittest.proto"; - -package protobuf_unittest; - -option optimize_for = CODE_SIZE; - -message TestOptimizedForSize { - optional int32 i = 1; - optional ForeignMessage msg = 19; - - extensions 1000 to max; - - extend TestOptimizedForSize { - optional int32 test_extension = 1234; - optional TestRequiredOptimizedForSize test_extension2 = 1235; - } -} - -message TestRequiredOptimizedForSize { - required int32 x = 1; -} - -message TestOptionalOptimizedForSize { - optional TestRequiredOptimizedForSize o = 1; -} diff --git a/Resources/NetHook/google/protobuf/unknown_field_set.cc b/Resources/NetHook/google/protobuf/unknown_field_set.cc deleted file mode 100644 index e1f8b838..00000000 --- a/Resources/NetHook/google/protobuf/unknown_field_set.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -UnknownFieldSet::UnknownFieldSet() - : fields_(NULL) {} - -UnknownFieldSet::~UnknownFieldSet() { - Clear(); - delete fields_; -} - -void UnknownFieldSet::ClearFallback() { - GOOGLE_DCHECK(fields_ != NULL); - for (int i = 0; i < fields_->size(); i++) { - (*fields_)[i].Delete(); - } - fields_->clear(); -} - -void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { - for (int i = 0; i < other.field_count(); i++) { - AddField(other.field(i)); - } -} - -int UnknownFieldSet::SpaceUsedExcludingSelf() const { - if (fields_ == NULL) return 0; - - int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); - for (int i = 0; i < fields_->size(); i++) { - const UnknownField& field = (*fields_)[i]; - switch (field.type()) { - case UnknownField::TYPE_LENGTH_DELIMITED: - total_size += sizeof(*field.length_delimited_) + - internal::StringSpaceUsedExcludingSelf(*field.length_delimited_); - break; - case UnknownField::TYPE_GROUP: - total_size += field.group_->SpaceUsed(); - break; - default: - break; - } - } - return total_size; -} - -int UnknownFieldSet::SpaceUsed() const { - return sizeof(*this) + SpaceUsedExcludingSelf(); -} - -void UnknownFieldSet::AddVarint(int number, uint64 value) { - if (fields_ == NULL) fields_ = new vector; - UnknownField field; - field.number_ = number; - field.type_ = UnknownField::TYPE_VARINT; - field.varint_ = value; - fields_->push_back(field); -} - -void UnknownFieldSet::AddFixed32(int number, uint32 value) { - if (fields_ == NULL) fields_ = new vector; - UnknownField field; - field.number_ = number; - field.type_ = UnknownField::TYPE_FIXED32; - field.fixed32_ = value; - fields_->push_back(field); -} - -void UnknownFieldSet::AddFixed64(int number, uint64 value) { - if (fields_ == NULL) fields_ = new vector; - UnknownField field; - field.number_ = number; - field.type_ = UnknownField::TYPE_FIXED64; - field.fixed64_ = value; - fields_->push_back(field); -} - -string* UnknownFieldSet::AddLengthDelimited(int number) { - if (fields_ == NULL) fields_ = new vector; - UnknownField field; - field.number_ = number; - field.type_ = UnknownField::TYPE_LENGTH_DELIMITED; - field.length_delimited_ = new string; - fields_->push_back(field); - return field.length_delimited_; -} - -UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { - if (fields_ == NULL) fields_ = new vector; - UnknownField field; - field.number_ = number; - field.type_ = UnknownField::TYPE_GROUP; - field.group_ = new UnknownFieldSet; - fields_->push_back(field); - return field.group_; -} - -void UnknownFieldSet::AddField(const UnknownField& field) { - if (fields_ == NULL) fields_ = new vector; - fields_->push_back(field); - fields_->back().DeepCopy(); -} - -bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { - - UnknownFieldSet other; - if (internal::WireFormat::SkipMessage(input, &other) && - input->ConsumedEntireMessage()) { - MergeFrom(other); - return true; - } else { - return false; - } -} - -bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergeFromCodedStream(input); -} - -bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream coded_input(input); - return ParseFromCodedStream(&coded_input) && - coded_input.ConsumedEntireMessage(); -} - -bool UnknownFieldSet::ParseFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParseFromZeroCopyStream(&input); -} - -void UnknownField::Delete() { - switch (type()) { - case UnknownField::TYPE_LENGTH_DELIMITED: - delete length_delimited_; - break; - case UnknownField::TYPE_GROUP: - delete group_; - break; - default: - break; - } -} - -void UnknownField::DeepCopy() { - switch (type()) { - case UnknownField::TYPE_LENGTH_DELIMITED: - length_delimited_ = new string(*length_delimited_); - break; - case UnknownField::TYPE_GROUP: { - UnknownFieldSet* group = new UnknownFieldSet; - group->MergeFrom(*group_); - group_ = group; - break; - } - default: - break; - } -} - -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/unknown_field_set.h b/Resources/NetHook/google/protobuf/unknown_field_set.h deleted file mode 100644 index 84c2e2b6..00000000 --- a/Resources/NetHook/google/protobuf/unknown_field_set.h +++ /dev/null @@ -1,268 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Contains classes used to keep track of unrecognized fields seen while -// parsing a protocol message. - -#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ -#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ - -#include -#include -#include - -namespace google { -namespace protobuf { - -class Message; // message.h -class UnknownField; // below - -// An UnknownFieldSet contains fields that were encountered while parsing a -// message but were not defined by its type. Keeping track of these can be -// useful, especially in that they may be written if the message is serialized -// again without being cleared in between. This means that software which -// simply receives messages and forwards them to other servers does not need -// to be updated every time a new field is added to the message definition. -// -// To get the UnknownFieldSet attached to any message, call -// Reflection::GetUnknownFields(). -// -// This class is necessarily tied to the protocol buffer wire format, unlike -// the Reflection interface which is independent of any serialization scheme. -class LIBPROTOBUF_EXPORT UnknownFieldSet { - public: - UnknownFieldSet(); - ~UnknownFieldSet(); - - // Remove all fields. - inline void Clear(); - - // Is this set empty? - inline bool empty() const; - - // Merge the contents of some other UnknownFieldSet with this one. - void MergeFrom(const UnknownFieldSet& other); - - // Swaps the contents of some other UnknownFieldSet with this one. - inline void Swap(UnknownFieldSet* x); - - // Computes (an estimate of) the total number of bytes currently used for - // storing the unknown fields in memory. Does NOT include - // sizeof(*this) in the calculation. - int SpaceUsedExcludingSelf() const; - - // Version of SpaceUsed() including sizeof(*this). - int SpaceUsed() const; - - // Returns the number of fields present in the UnknownFieldSet. - inline int field_count() const; - // Get a field in the set, where 0 <= index < field_count(). The fields - // appear in the order in which they were added. - inline const UnknownField& field(int index) const; - // Get a mutable pointer to a field in the set, where - // 0 <= index < field_count(). The fields appear in the order in which - // they were added. - inline UnknownField* mutable_field(int index); - - // Adding fields --------------------------------------------------- - - void AddVarint(int number, uint64 value); - void AddFixed32(int number, uint32 value); - void AddFixed64(int number, uint64 value); - void AddLengthDelimited(int number, const string& value); - string* AddLengthDelimited(int number); - UnknownFieldSet* AddGroup(int number); - - // Adds an unknown field from another set. - void AddField(const UnknownField& field); - - // Parsing helpers ------------------------------------------------- - // These work exactly like the similarly-named methods of Message. - - bool MergeFromCodedStream(io::CodedInputStream* input); - bool ParseFromCodedStream(io::CodedInputStream* input); - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); - bool ParseFromArray(const void* data, int size); - inline bool ParseFromString(const string& data) { - return ParseFromArray(data.data(), data.size()); - } - - private: - void ClearFallback(); - - vector* fields_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); -}; - -// Represents one field in an UnknownFieldSet. -class LIBPROTOBUF_EXPORT UnknownField { - public: - enum Type { - TYPE_VARINT, - TYPE_FIXED32, - TYPE_FIXED64, - TYPE_LENGTH_DELIMITED, - TYPE_GROUP - }; - - // The field's tag number, as seen on the wire. - inline int number() const; - - // The field type. - inline Type type() const; - - // Accessors ------------------------------------------------------- - // Each method works only for UnknownFields of the corresponding type. - - inline uint64 varint() const; - inline uint32 fixed32() const; - inline uint64 fixed64() const; - inline const string& length_delimited() const; - inline const UnknownFieldSet& group() const; - - inline void set_varint(uint64 value); - inline void set_fixed32(uint32 value); - inline void set_fixed64(uint64 value); - inline void set_length_delimited(const string& value); - inline string* mutable_length_delimited(); - inline UnknownFieldSet* mutable_group(); - - private: - friend class UnknownFieldSet; - - // If this UnknownField contains a pointer, delete it. - void Delete(); - - // Make a deep copy of any pointers in this UnknownField. - void DeepCopy(); - - unsigned int number_ : 29; - unsigned int type_ : 3; - union { - uint64 varint_; - uint32 fixed32_; - uint64 fixed64_; - string* length_delimited_; - UnknownFieldSet* group_; - }; -}; - -// =================================================================== -// inline implementations - -inline void UnknownFieldSet::Clear() { - if (fields_ != NULL) { - ClearFallback(); - } -} - -inline bool UnknownFieldSet::empty() const { - return fields_ == NULL || fields_->empty(); -} - -inline void UnknownFieldSet::Swap(UnknownFieldSet* x) { - std::swap(fields_, x->fields_); -} - -inline int UnknownFieldSet::field_count() const { - return (fields_ == NULL) ? 0 : fields_->size(); -} -inline const UnknownField& UnknownFieldSet::field(int index) const { - return (*fields_)[index]; -} -inline UnknownField* UnknownFieldSet::mutable_field(int index) { - return &(*fields_)[index]; -} - -inline void UnknownFieldSet::AddLengthDelimited( - int number, const string& value) { - AddLengthDelimited(number)->assign(value); -} - -inline int UnknownField::number() const { return number_; } -inline UnknownField::Type UnknownField::type() const { - return static_cast(type_); -} - -inline uint64 UnknownField::varint () const { - GOOGLE_DCHECK_EQ(type_, TYPE_VARINT); - return varint_; -} -inline uint32 UnknownField::fixed32() const { - GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32); - return fixed32_; -} -inline uint64 UnknownField::fixed64() const { - GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64); - return fixed64_; -} -inline const string& UnknownField::length_delimited() const { - GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED); - return *length_delimited_; -} -inline const UnknownFieldSet& UnknownField::group() const { - GOOGLE_DCHECK_EQ(type_, TYPE_GROUP); - return *group_; -} - -inline void UnknownField::set_varint(uint64 value) { - GOOGLE_DCHECK_EQ(type_, TYPE_VARINT); - varint_ = value; -} -inline void UnknownField::set_fixed32(uint32 value) { - GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32); - fixed32_ = value; -} -inline void UnknownField::set_fixed64(uint64 value) { - GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64); - fixed64_ = value; -} -inline void UnknownField::set_length_delimited(const string& value) { - GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED); - length_delimited_->assign(value); -} -inline string* UnknownField::mutable_length_delimited() { - GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED); - return length_delimited_; -} -inline UnknownFieldSet* UnknownField::mutable_group() { - GOOGLE_DCHECK_EQ(type_, TYPE_GROUP); - return group_; -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ diff --git a/Resources/NetHook/google/protobuf/unknown_field_set_unittest.cc b/Resources/NetHook/google/protobuf/unknown_field_set_unittest.cc deleted file mode 100644 index 1235c9ee..00000000 --- a/Resources/NetHook/google/protobuf/unknown_field_set_unittest.cc +++ /dev/null @@ -1,512 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This test is testing a lot more than just the UnknownFieldSet class. It -// tests handling of unknown fields throughout the system. - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace google { -namespace protobuf { - -using internal::WireFormat; - -namespace { - -class UnknownFieldSetTest : public testing::Test { - protected: - virtual void SetUp() { - descriptor_ = unittest::TestAllTypes::descriptor(); - TestUtil::SetAllFields(&all_fields_); - all_fields_.SerializeToString(&all_fields_data_); - ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_)); - unknown_fields_ = empty_message_.mutable_unknown_fields(); - } - - const UnknownField* GetField(const string& name) { - const FieldDescriptor* field = descriptor_->FindFieldByName(name); - if (field == NULL) return NULL; - for (int i = 0; i < unknown_fields_->field_count(); i++) { - if (unknown_fields_->field(i).number() == field->number()) { - return &unknown_fields_->field(i); - } - } - return NULL; - } - - // Constructs a protocol buffer which contains fields with all the same - // numbers as all_fields_data_ except that each field is some other wire - // type. - string GetBizarroData() { - unittest::TestEmptyMessage bizarro_message; - UnknownFieldSet* bizarro_unknown_fields = - bizarro_message.mutable_unknown_fields(); - for (int i = 0; i < unknown_fields_->field_count(); i++) { - const UnknownField& unknown_field = unknown_fields_->field(i); - if (unknown_field.type() == UnknownField::TYPE_VARINT) { - bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1); - } else { - bizarro_unknown_fields->AddVarint(unknown_field.number(), 1); - } - } - - string data; - EXPECT_TRUE(bizarro_message.SerializeToString(&data)); - return data; - } - - const Descriptor* descriptor_; - unittest::TestAllTypes all_fields_; - string all_fields_data_; - - // An empty message that has been parsed from all_fields_data_. So, it has - // unknown fields of every type. - unittest::TestEmptyMessage empty_message_; - UnknownFieldSet* unknown_fields_; -}; - -TEST_F(UnknownFieldSetTest, AllFieldsPresent) { - // All fields of TestAllTypes should be present, in numeric order (because - // that's the order we parsed them in). Fields that are not valid field - // numbers of TestAllTypes should NOT be present. - - int pos = 0; - - for (int i = 0; i < 1000; i++) { - const FieldDescriptor* field = descriptor_->FindFieldByNumber(i); - if (field != NULL) { - ASSERT_LT(pos, unknown_fields_->field_count()); - EXPECT_EQ(i, unknown_fields_->field(pos++).number()); - if (field->is_repeated()) { - // Should have a second instance. - ASSERT_LT(pos, unknown_fields_->field_count()); - EXPECT_EQ(i, unknown_fields_->field(pos++).number()); - } - } - } - EXPECT_EQ(unknown_fields_->field_count(), pos); -} - -TEST_F(UnknownFieldSetTest, Varint) { - const UnknownField* field = GetField("optional_int32"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(UnknownField::TYPE_VARINT, field->type()); - EXPECT_EQ(all_fields_.optional_int32(), field->varint()); -} - -TEST_F(UnknownFieldSetTest, Fixed32) { - const UnknownField* field = GetField("optional_fixed32"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type()); - EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32()); -} - -TEST_F(UnknownFieldSetTest, Fixed64) { - const UnknownField* field = GetField("optional_fixed64"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type()); - EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64()); -} - -TEST_F(UnknownFieldSetTest, LengthDelimited) { - const UnknownField* field = GetField("optional_string"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type()); - EXPECT_EQ(all_fields_.optional_string(), field->length_delimited()); -} - -TEST_F(UnknownFieldSetTest, Group) { - const UnknownField* field = GetField("optionalgroup"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(UnknownField::TYPE_GROUP, field->type()); - ASSERT_EQ(1, field->group().field_count()); - - const UnknownField& nested_field = field->group().field(0); - const FieldDescriptor* nested_field_descriptor = - unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a"); - ASSERT_TRUE(nested_field_descriptor != NULL); - - EXPECT_EQ(nested_field_descriptor->number(), nested_field.number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type()); - EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint()); -} - -TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) { - int size = WireFormat::ComputeUnknownFieldsSize( - empty_message_.unknown_fields()); - string slow_buffer; - string fast_buffer; - slow_buffer.resize(size); - fast_buffer.resize(size); - - uint8* target = reinterpret_cast(string_as_array(&fast_buffer)); - uint8* result = WireFormat::SerializeUnknownFieldsToArray( - empty_message_.unknown_fields(), target); - EXPECT_EQ(size, result - target); - - { - io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1); - io::CodedOutputStream output_stream(&raw_stream); - WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(), - &output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - EXPECT_TRUE(fast_buffer == slow_buffer); -} - -TEST_F(UnknownFieldSetTest, Serialize) { - // Check that serializing the UnknownFieldSet produces the original data - // again. - - string data; - empty_message_.SerializeToString(&data); - - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(data == all_fields_data_); -} - -TEST_F(UnknownFieldSetTest, ParseViaReflection) { - // Make sure fields are properly parsed to the UnknownFieldSet when parsing - // via reflection. - - unittest::TestEmptyMessage message; - io::ArrayInputStream raw_input(all_fields_data_.data(), - all_fields_data_.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, SerializeViaReflection) { - // Make sure fields are properly written from the UnknownFieldSet when - // serializing via reflection. - - string data; - - { - io::StringOutputStream raw_output(&data); - io::CodedOutputStream output(&raw_output); - int size = WireFormat::ByteSize(empty_message_); - WireFormat::SerializeWithCachedSizes(empty_message_, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(data == all_fields_data_); -} - -TEST_F(UnknownFieldSetTest, CopyFrom) { - unittest::TestEmptyMessage message; - - message.CopyFrom(empty_message_); - - EXPECT_EQ(empty_message_.DebugString(), message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, Swap) { - unittest::TestEmptyMessage other_message; - ASSERT_TRUE(other_message.ParseFromString(GetBizarroData())); - - EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); - EXPECT_GT(other_message.unknown_fields().field_count(), 0); - const string debug_string = empty_message_.DebugString(); - const string other_debug_string = other_message.DebugString(); - EXPECT_NE(debug_string, other_debug_string); - - empty_message_.Swap(&other_message); - EXPECT_EQ(debug_string, other_message.DebugString()); - EXPECT_EQ(other_debug_string, empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, SwapWithSelf) { - const string debug_string = empty_message_.DebugString(); - EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); - - empty_message_.Swap(&empty_message_); - EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); - EXPECT_EQ(debug_string, empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, MergeFrom) { - unittest::TestEmptyMessage source, destination; - - destination.mutable_unknown_fields()->AddVarint(1, 1); - destination.mutable_unknown_fields()->AddVarint(3, 2); - source.mutable_unknown_fields()->AddVarint(2, 3); - source.mutable_unknown_fields()->AddVarint(3, 4); - - destination.MergeFrom(source); - - EXPECT_EQ( - // Note: The ordering of fields here depends on the ordering of adds - // and merging, above. - "1: 1\n" - "3: 2\n" - "2: 3\n" - "3: 4\n", - destination.DebugString()); -} - -TEST_F(UnknownFieldSetTest, Clear) { - // Clear the set. - empty_message_.Clear(); - EXPECT_EQ(0, unknown_fields_->field_count()); -} - -TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) { - // Test mixing known and unknown fields when parsing. - - unittest::TestEmptyMessage source; - source.mutable_unknown_fields()->AddVarint(123456, 654321); - string data; - ASSERT_TRUE(source.SerializeToString(&data)); - - unittest::TestAllTypes destination; - ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data)); - - TestUtil::ExpectAllFieldsSet(destination); - ASSERT_EQ(1, destination.unknown_fields().field_count()); - ASSERT_EQ(UnknownField::TYPE_VARINT, - destination.unknown_fields().field(0).type()); - EXPECT_EQ(654321, destination.unknown_fields().field(0).varint()); -} - -TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) { - // Test that fields of the wrong wire type are treated like unknown fields - // when parsing. - - unittest::TestAllTypes all_types_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - // All fields should have been interpreted as unknown, so the debug strings - // should be the same. - EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) { - // Same as WrongTypeTreatedAsUnknown but via the reflection interface. - - unittest::TestAllTypes all_types_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownExtensions) { - // Make sure fields are properly parsed to the UnknownFieldSet even when - // they are declared as extension numbers. - - unittest::TestEmptyMessageWithExtensions message; - ASSERT_TRUE(message.ParseFromString(all_fields_data_)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) { - // Same as UnknownExtensions except parsing via reflection. - - unittest::TestEmptyMessageWithExtensions message; - io::ArrayInputStream raw_input(all_fields_data_.data(), - all_fields_data_.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) { - // Test that fields of the wrong wire type are treated like unknown fields - // when parsing extensions. - - unittest::TestAllExtensions all_extensions_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - // All fields should have been interpreted as unknown, so the debug strings - // should be the same. - EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownEnumValue) { - using unittest::TestAllTypes; - using unittest::TestAllExtensions; - using unittest::TestEmptyMessage; - - const FieldDescriptor* singular_field = - TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum"); - const FieldDescriptor* repeated_field = - TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum"); - ASSERT_TRUE(singular_field != NULL); - ASSERT_TRUE(repeated_field != NULL); - - string data; - - { - TestEmptyMessage empty_message; - UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); - unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR); - unknown_fields->AddVarint(singular_field->number(), 5); // not valid - unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO); - unknown_fields->AddVarint(repeated_field->number(), 4); // not valid - unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ); - unknown_fields->AddVarint(repeated_field->number(), 6); // not valid - empty_message.SerializeToString(&data); - } - - { - TestAllTypes message; - ASSERT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum()); - ASSERT_EQ(2, message.repeated_nested_enum_size()); - EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0)); - EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1)); - - const UnknownFieldSet& unknown_fields = message.unknown_fields(); - ASSERT_EQ(3, unknown_fields.field_count()); - - EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type()); - EXPECT_EQ(5, unknown_fields.field(0).varint()); - - EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type()); - EXPECT_EQ(4, unknown_fields.field(1).varint()); - - EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type()); - EXPECT_EQ(6, unknown_fields.field(2).varint()); - } - - { - using unittest::optional_nested_enum_extension; - using unittest::repeated_nested_enum_extension; - - TestAllExtensions message; - ASSERT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(TestAllTypes::BAR, - message.GetExtension(optional_nested_enum_extension)); - ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension)); - EXPECT_EQ(TestAllTypes::FOO, - message.GetExtension(repeated_nested_enum_extension, 0)); - EXPECT_EQ(TestAllTypes::BAZ, - message.GetExtension(repeated_nested_enum_extension, 1)); - - const UnknownFieldSet& unknown_fields = message.unknown_fields(); - ASSERT_EQ(3, unknown_fields.field_count()); - - EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type()); - EXPECT_EQ(5, unknown_fields.field(0).varint()); - - EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type()); - EXPECT_EQ(4, unknown_fields.field(1).varint()); - - EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number()); - ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type()); - EXPECT_EQ(6, unknown_fields.field(2).varint()); - } -} - -TEST_F(UnknownFieldSetTest, SpaceUsed) { - unittest::TestEmptyMessage empty_message; - - // Make sure an unknown field set has zero space used until a field is - // actually added. - int base_size = empty_message.SpaceUsed(); - UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); - EXPECT_EQ(base_size, empty_message.SpaceUsed()); - - // Make sure each thing we add to the set increases the SpaceUsed(). - unknown_fields->AddVarint(1, 0); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); - - string* str = unknown_fields->AddLengthDelimited(1); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); - - str->assign(sizeof(string) + 1, 'x'); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); - - UnknownFieldSet* group = unknown_fields->AddGroup(1); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); - - group->AddVarint(1, 0); - EXPECT_LT(base_size, empty_message.SpaceUsed()); -} - -TEST_F(UnknownFieldSetTest, Empty) { - UnknownFieldSet unknown_fields; - EXPECT_TRUE(unknown_fields.empty()); - unknown_fields.AddVarint(6, 123); - EXPECT_FALSE(unknown_fields.empty()); - unknown_fields.Clear(); - EXPECT_TRUE(unknown_fields.empty()); -} - -} // namespace -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/wire_format.cc b/Resources/NetHook/google/protobuf/wire_format.cc deleted file mode 100644 index 831a5794..00000000 --- a/Resources/NetHook/google/protobuf/wire_format.cc +++ /dev/null @@ -1,1069 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace google { -namespace protobuf { -namespace internal { - -using internal::WireFormatLite; - -namespace { - -// This function turns out to be convenient when using some macros later. -inline int GetEnumNumber(const EnumValueDescriptor* descriptor) { - return descriptor->number(); -} - -} // anonymous namespace - -// =================================================================== - -bool UnknownFieldSetFieldSkipper::SkipField( - io::CodedInputStream* input, uint32 tag) { - return WireFormat::SkipField(input, tag, unknown_fields_); -} - -bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { - return WireFormat::SkipMessage(input, unknown_fields_); -} - -void UnknownFieldSetFieldSkipper::SkipUnknownEnum( - int field_number, int value) { - unknown_fields_->AddVarint(field_number, value); -} - -bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, - UnknownFieldSet* unknown_fields) { - int number = WireFormatLite::GetTagFieldNumber(tag); - - switch (WireFormatLite::GetTagWireType(tag)) { - case WireFormatLite::WIRETYPE_VARINT: { - uint64 value; - if (!input->ReadVarint64(&value)) return false; - if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); - return true; - } - case WireFormatLite::WIRETYPE_FIXED64: { - uint64 value; - if (!input->ReadLittleEndian64(&value)) return false; - if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); - return true; - } - case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (unknown_fields == NULL) { - if (!input->Skip(length)) return false; - } else { - if (!input->ReadString(unknown_fields->AddLengthDelimited(number), - length)) { - return false; - } - } - return true; - } - case WireFormatLite::WIRETYPE_START_GROUP: { - if (!input->IncrementRecursionDepth()) return false; - if (!SkipMessage(input, (unknown_fields == NULL) ? - NULL : unknown_fields->AddGroup(number))) { - return false; - } - input->DecrementRecursionDepth(); - // Check that the ending tag matched the starting tag. - if (!input->LastTagWas(WireFormatLite::MakeTag( - WireFormatLite::GetTagFieldNumber(tag), - WireFormatLite::WIRETYPE_END_GROUP))) { - return false; - } - return true; - } - case WireFormatLite::WIRETYPE_END_GROUP: { - return false; - } - case WireFormatLite::WIRETYPE_FIXED32: { - uint32 value; - if (!input->ReadLittleEndian32(&value)) return false; - if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); - return true; - } - default: { - return false; - } - } -} - -bool WireFormat::SkipMessage(io::CodedInputStream* input, - UnknownFieldSet* unknown_fields) { - while(true) { - uint32 tag = input->ReadTag(); - if (tag == 0) { - // End of input. This is a valid place to end, so return true. - return true; - } - - WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); - - if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { - // Must be the end of the message. - return true; - } - - if (!SkipField(input, tag, unknown_fields)) return false; - } -} - -void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - switch (field.type()) { - case UnknownField::TYPE_VARINT: - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_VARINT)); - output->WriteVarint64(field.varint()); - break; - case UnknownField::TYPE_FIXED32: - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_FIXED32)); - output->WriteLittleEndian32(field.fixed32()); - break; - case UnknownField::TYPE_FIXED64: - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_FIXED64)); - output->WriteLittleEndian64(field.fixed64()); - break; - case UnknownField::TYPE_LENGTH_DELIMITED: - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); - output->WriteVarint32(field.length_delimited().size()); - output->WriteString(field.length_delimited()); - break; - case UnknownField::TYPE_GROUP: - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_START_GROUP)); - SerializeUnknownFields(field.group(), output); - output->WriteVarint32(WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_END_GROUP)); - break; - } - } -} - -uint8* WireFormat::SerializeUnknownFieldsToArray( - const UnknownFieldSet& unknown_fields, - uint8* target) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - switch (field.type()) { - case UnknownField::TYPE_VARINT: - target = WireFormatLite::WriteInt64ToArray( - field.number(), field.varint(), target); - break; - case UnknownField::TYPE_FIXED32: - target = WireFormatLite::WriteFixed32ToArray( - field.number(), field.fixed32(), target); - break; - case UnknownField::TYPE_FIXED64: - target = WireFormatLite::WriteFixed64ToArray( - field.number(), field.fixed64(), target); - break; - case UnknownField::TYPE_LENGTH_DELIMITED: - target = WireFormatLite::WriteBytesToArray( - field.number(), field.length_delimited(), target); - break; - case UnknownField::TYPE_GROUP: - target = WireFormatLite::WriteTagToArray( - field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); - target = SerializeUnknownFieldsToArray(field.group(), target); - target = WireFormatLite::WriteTagToArray( - field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); - break; - } - } - return target; -} - -void WireFormat::SerializeUnknownMessageSetItems( - const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - // The only unknown fields that are allowed to exist in a MessageSet are - // messages, which are length-delimited. - if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { - const string& data = field.length_delimited(); - - // Start group. - output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); - - // Write type ID. - output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); - output->WriteVarint32(field.number()); - - // Write message. - output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); - output->WriteVarint32(data.size()); - output->WriteString(data); - - // End group. - output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); - } - } -} - -uint8* WireFormat::SerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, - uint8* target) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - // The only unknown fields that are allowed to exist in a MessageSet are - // messages, which are length-delimited. - if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { - const string& data = field.length_delimited(); - - // Start group. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetItemStartTag, target); - - // Write type ID. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetTypeIdTag, target); - target = io::CodedOutputStream::WriteVarint32ToArray( - field.number(), target); - - // Write message. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetMessageTag, target); - target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); - target = io::CodedOutputStream::WriteStringToArray(data, target); - - // End group. - target = io::CodedOutputStream::WriteTagToArray( - WireFormatLite::kMessageSetItemEndTag, target); - } - } - - return target; -} - -int WireFormat::ComputeUnknownFieldsSize( - const UnknownFieldSet& unknown_fields) { - int size = 0; - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - switch (field.type()) { - case UnknownField::TYPE_VARINT: - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_VARINT)); - size += io::CodedOutputStream::VarintSize64(field.varint()); - break; - case UnknownField::TYPE_FIXED32: - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_FIXED32)); - size += sizeof(int32); - break; - case UnknownField::TYPE_FIXED64: - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_FIXED64)); - size += sizeof(int64); - break; - case UnknownField::TYPE_LENGTH_DELIMITED: - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); - size += io::CodedOutputStream::VarintSize32( - field.length_delimited().size()); - size += field.length_delimited().size(); - break; - case UnknownField::TYPE_GROUP: - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_START_GROUP)); - size += ComputeUnknownFieldsSize(field.group()); - size += io::CodedOutputStream::VarintSize32( - WireFormatLite::MakeTag(field.number(), - WireFormatLite::WIRETYPE_END_GROUP)); - break; - } - } - - return size; -} - -int WireFormat::ComputeUnknownMessageSetItemsSize( - const UnknownFieldSet& unknown_fields) { - int size = 0; - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - // The only unknown fields that are allowed to exist in a MessageSet are - // messages, which are length-delimited. - if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { - size += WireFormatLite::kMessageSetItemTagsSize; - size += io::CodedOutputStream::VarintSize32(field.number()); - size += io::CodedOutputStream::VarintSize32( - field.length_delimited().size()); - size += field.length_delimited().size(); - } - } - - return size; -} - -// =================================================================== - -bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, - Message* message) { - const Descriptor* descriptor = message->GetDescriptor(); - const Reflection* message_reflection = message->GetReflection(); - - while(true) { - uint32 tag = input->ReadTag(); - if (tag == 0) { - // End of input. This is a valid place to end, so return true. - return true; - } - - if (WireFormatLite::GetTagWireType(tag) == - WireFormatLite::WIRETYPE_END_GROUP) { - // Must be the end of the message. - return true; - } - - const FieldDescriptor* field = NULL; - - if (descriptor != NULL) { - int field_number = WireFormatLite::GetTagFieldNumber(tag); - field = descriptor->FindFieldByNumber(field_number); - - // If that failed, check if the field is an extension. - if (field == NULL && descriptor->IsExtensionNumber(field_number)) { - if (input->GetExtensionPool() == NULL) { - field = message_reflection->FindKnownExtensionByNumber(field_number); - } else { - field = input->GetExtensionPool() - ->FindExtensionByNumber(descriptor, field_number); - } - } - - // If that failed, but we're a MessageSet, and this is the tag for a - // MessageSet item, then parse that. - if (field == NULL && - descriptor->options().message_set_wire_format() && - tag == WireFormatLite::kMessageSetItemStartTag) { - if (!ParseAndMergeMessageSetItem(input, message)) { - return false; - } - continue; // Skip ParseAndMergeField(); already taken care of. - } - } - - if (!ParseAndMergeField(tag, field, message, input)) { - return false; - } - } -} - -bool WireFormat::ParseAndMergeField( - uint32 tag, - const FieldDescriptor* field, // May be NULL for unknown - Message* message, - io::CodedInputStream* input) { - const Reflection* message_reflection = message->GetReflection(); - - enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; - - if (field == NULL) { - value_format = UNKNOWN; - } else if (WireFormatLite::GetTagWireType(tag) == - WireTypeForFieldType(field->type())) { - value_format = NORMAL_FORMAT; - } else if (field->is_packable() && - WireFormatLite::GetTagWireType(tag) == - WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - value_format = PACKED_FORMAT; - } else { - // We don't recognize this field. Either the field number is unknown - // or the wire type doesn't match. Put it in our unknown field set. - value_format = UNKNOWN; - } - - if (value_format == UNKNOWN) { - return SkipField(input, tag, - message_reflection->MutableUnknownFields(message)); - } else if (value_format == PACKED_FORMAT) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - - switch (field->type()) { -#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - while (input->BytesUntilLimit() > 0) { \ - CPPTYPE value; \ - if (!WireFormatLite::ReadPrimitive< \ - CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ - return false; \ - message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ - } \ - break; \ - } - - HANDLE_PACKED_TYPE( INT32, int32, Int32) - HANDLE_PACKED_TYPE( INT64, int64, Int64) - HANDLE_PACKED_TYPE(SINT32, int32, Int32) - HANDLE_PACKED_TYPE(SINT64, int64, Int64) - HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) - HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) - - HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32) - HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64) - HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) - HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) - - HANDLE_PACKED_TYPE(FLOAT , float , Float ) - HANDLE_PACKED_TYPE(DOUBLE, double, Double) - - HANDLE_PACKED_TYPE(BOOL, bool, Bool) -#undef HANDLE_PACKED_TYPE - - case FieldDescriptor::TYPE_ENUM: { - while (input->BytesUntilLimit() > 0) { - int value; - if (!WireFormatLite::ReadPrimitive( - input, &value)) return false; - const EnumValueDescriptor* enum_value = - field->enum_type()->FindValueByNumber(value); - if (enum_value != NULL) { - message_reflection->AddEnum(message, field, enum_value); - } - } - - break; - } - - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - case FieldDescriptor::TYPE_BYTES: - // Can't have packed fields of these types: these should be caught by - // the protocol compiler. - return false; - break; - } - - input->PopLimit(limit); - } else { - // Non-packed value (value_format == NORMAL_FORMAT) - switch (field->type()) { -#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - CPPTYPE value; \ - if (!WireFormatLite::ReadPrimitive< \ - CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ - return false; \ - if (field->is_repeated()) { \ - message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ - } else { \ - message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ - } \ - break; \ - } - - HANDLE_TYPE( INT32, int32, Int32) - HANDLE_TYPE( INT64, int64, Int64) - HANDLE_TYPE(SINT32, int32, Int32) - HANDLE_TYPE(SINT64, int64, Int64) - HANDLE_TYPE(UINT32, uint32, UInt32) - HANDLE_TYPE(UINT64, uint64, UInt64) - - HANDLE_TYPE( FIXED32, uint32, UInt32) - HANDLE_TYPE( FIXED64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, int32, Int32) - HANDLE_TYPE(SFIXED64, int64, Int64) - - HANDLE_TYPE(FLOAT , float , Float ) - HANDLE_TYPE(DOUBLE, double, Double) - - HANDLE_TYPE(BOOL, bool, Bool) -#undef HANDLE_TYPE - - case FieldDescriptor::TYPE_ENUM: { - int value; - if (!WireFormatLite::ReadPrimitive( - input, &value)) return false; - const EnumValueDescriptor* enum_value = - field->enum_type()->FindValueByNumber(value); - if (enum_value != NULL) { - if (field->is_repeated()) { - message_reflection->AddEnum(message, field, enum_value); - } else { - message_reflection->SetEnum(message, field, enum_value); - } - } else { - // The enum value is not one of the known values. Add it to the - // UnknownFieldSet. - int64 sign_extended_value = static_cast(value); - message_reflection->MutableUnknownFields(message) - ->AddVarint(WireFormatLite::GetTagFieldNumber(tag), - sign_extended_value); - } - break; - } - - // Handle strings separately so that we can optimize the ctype=CORD case. - case FieldDescriptor::TYPE_STRING: { - string value; - if (!WireFormatLite::ReadString(input, &value)) return false; - VerifyUTF8String(value.data(), value.length(), PARSE); - if (field->is_repeated()) { - message_reflection->AddString(message, field, value); - } else { - message_reflection->SetString(message, field, value); - } - break; - } - - case FieldDescriptor::TYPE_BYTES: { - string value; - if (!WireFormatLite::ReadBytes(input, &value)) return false; - if (field->is_repeated()) { - message_reflection->AddString(message, field, value); - } else { - message_reflection->SetString(message, field, value); - } - break; - } - - case FieldDescriptor::TYPE_GROUP: { - Message* sub_message; - if (field->is_repeated()) { - sub_message = message_reflection->AddMessage( - message, field, input->GetExtensionFactory()); - } else { - sub_message = message_reflection->MutableMessage( - message, field, input->GetExtensionFactory()); - } - - if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), - input, sub_message)) - return false; - break; - } - - case FieldDescriptor::TYPE_MESSAGE: { - Message* sub_message; - if (field->is_repeated()) { - sub_message = message_reflection->AddMessage( - message, field, input->GetExtensionFactory()); - } else { - sub_message = message_reflection->MutableMessage( - message, field, input->GetExtensionFactory()); - } - - if (!WireFormatLite::ReadMessage(input, sub_message)) return false; - break; - } - } - } - - return true; -} - -bool WireFormat::ParseAndMergeMessageSetItem( - io::CodedInputStream* input, - Message* message) { - const Reflection* message_reflection = message->GetReflection(); - - // This method parses a group which should contain two fields: - // required int32 type_id = 2; - // required data message = 3; - - // Once we see a type_id, we'll construct a fake tag for this extension - // which is the tag it would have had under the proto2 extensions wire - // format. - uint32 fake_tag = 0; - - // Once we see a type_id, we'll look up the FieldDescriptor for the - // extension. - const FieldDescriptor* field = NULL; - - // If we see message data before the type_id, we'll append it to this so - // we can parse it later. This will probably never happen in practice, - // as no MessageSet encoder I know of writes the message before the type ID. - // But, it's technically valid so we should allow it. - // TODO(kenton): Use a Cord instead? Do I care? - string message_data; - - while (true) { - uint32 tag = input->ReadTag(); - if (tag == 0) return false; - - switch (tag) { - case WireFormatLite::kMessageSetTypeIdTag: { - uint32 type_id; - if (!input->ReadVarint32(&type_id)) return false; - fake_tag = WireFormatLite::MakeTag( - type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - field = message_reflection->FindKnownExtensionByNumber(type_id); - - if (!message_data.empty()) { - // We saw some message data before the type_id. Have to parse it - // now. - io::ArrayInputStream raw_input(message_data.data(), - message_data.size()); - io::CodedInputStream sub_input(&raw_input); - if (!ParseAndMergeField(fake_tag, field, message, - &sub_input)) { - return false; - } - message_data.clear(); - } - - break; - } - - case WireFormatLite::kMessageSetMessageTag: { - if (fake_tag == 0) { - // We haven't seen a type_id yet. Append this data to message_data. - string temp; - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(&temp, length)) return false; - message_data.append(temp); - } else { - // Already saw type_id, so we can parse this directly. - if (!ParseAndMergeField(fake_tag, field, message, input)) { - return false; - } - } - - break; - } - - case WireFormatLite::kMessageSetItemEndTag: { - return true; - } - - default: { - if (!SkipField(input, tag, NULL)) return false; - } - } - } -} - -// =================================================================== - -void WireFormat::SerializeWithCachedSizes( - const Message& message, - int size, io::CodedOutputStream* output) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* message_reflection = message.GetReflection(); - int expected_endpoint = output->ByteCount() + size; - - vector fields; - message_reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - SerializeFieldWithCachedSizes(fields[i], message, output); - } - - if (descriptor->options().message_set_wire_format()) { - SerializeUnknownMessageSetItems( - message_reflection->GetUnknownFields(message), output); - } else { - SerializeUnknownFields( - message_reflection->GetUnknownFields(message), output); - } - - GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint) - << ": Protocol message serialized to a size different from what was " - "originally expected. Perhaps it was modified by another thread " - "during serialization?"; -} - -void WireFormat::SerializeFieldWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output) { - const Reflection* message_reflection = message.GetReflection(); - - if (field->is_extension() && - field->containing_type()->options().message_set_wire_format() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_repeated()) { - SerializeMessageSetItemWithCachedSizes(field, message, output); - return; - } - - int count = 0; - - if (field->is_repeated()) { - count = message_reflection->FieldSize(message, field); - } else if (message_reflection->HasField(message, field)) { - count = 1; - } - - const bool is_packed = field->options().packed(); - if (is_packed && count > 0) { - WireFormatLite::WriteTag(field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); - const int data_size = FieldDataOnlyByteSize(field, message); - output->WriteVarint32(data_size); - } - - for (int j = 0; j < count; j++) { - switch (field->type()) { -#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - const CPPTYPE value = field->is_repeated() ? \ - message_reflection->GetRepeated##CPPTYPE_METHOD( \ - message, field, j) : \ - message_reflection->Get##CPPTYPE_METHOD( \ - message, field); \ - if (is_packed) { \ - WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \ - } else { \ - WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \ - } \ - break; \ - } - - HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32) - HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64) - HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32) - HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64) - HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32) - HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64) - - HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32) - HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64) - HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32) - HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64) - - HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float ) - HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) - - HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) -#undef HANDLE_PRIMITIVE_TYPE - -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - WireFormatLite::Write##TYPE_METHOD( \ - field->number(), \ - field->is_repeated() ? \ - message_reflection->GetRepeated##CPPTYPE_METHOD( \ - message, field, j) : \ - message_reflection->Get##CPPTYPE_METHOD(message, field), \ - output); \ - break; - - HANDLE_TYPE(GROUP , Group , Message) - HANDLE_TYPE(MESSAGE, Message, Message) -#undef HANDLE_TYPE - - case FieldDescriptor::TYPE_ENUM: { - const EnumValueDescriptor* value = field->is_repeated() ? - message_reflection->GetRepeatedEnum(message, field, j) : - message_reflection->GetEnum(message, field); - if (is_packed) { - WireFormatLite::WriteEnumNoTag(value->number(), output); - } else { - WireFormatLite::WriteEnum(field->number(), value->number(), output); - } - break; - } - - // Handle strings separately so that we can get string references - // instead of copying. - case FieldDescriptor::TYPE_STRING: { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - VerifyUTF8String(value.data(), value.length(), SERIALIZE); - WireFormatLite::WriteString(field->number(), value, output); - break; - } - - case FieldDescriptor::TYPE_BYTES: { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - WireFormatLite::WriteBytes(field->number(), value, output); - break; - } - } - } -} - -void WireFormat::SerializeMessageSetItemWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output) { - const Reflection* message_reflection = message.GetReflection(); - - // Start group. - output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); - - // Write type ID. - output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); - output->WriteVarint32(field->number()); - - // Write message. - output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); - - const Message& sub_message = message_reflection->GetMessage(message, field); - output->WriteVarint32(sub_message.GetCachedSize()); - sub_message.SerializeWithCachedSizes(output); - - // End group. - output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); -} - -// =================================================================== - -int WireFormat::ByteSize(const Message& message) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* message_reflection = message.GetReflection(); - - int our_size = 0; - - vector fields; - message_reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - our_size += FieldByteSize(fields[i], message); - } - - if (descriptor->options().message_set_wire_format()) { - our_size += ComputeUnknownMessageSetItemsSize( - message_reflection->GetUnknownFields(message)); - } else { - our_size += ComputeUnknownFieldsSize( - message_reflection->GetUnknownFields(message)); - } - - return our_size; -} - -int WireFormat::FieldByteSize( - const FieldDescriptor* field, - const Message& message) { - const Reflection* message_reflection = message.GetReflection(); - - if (field->is_extension() && - field->containing_type()->options().message_set_wire_format() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_repeated()) { - return MessageSetItemByteSize(field, message); - } - - int count = 0; - if (field->is_repeated()) { - count = message_reflection->FieldSize(message, field); - } else if (message_reflection->HasField(message, field)) { - count = 1; - } - - const int data_size = FieldDataOnlyByteSize(field, message); - int our_size = data_size; - if (field->options().packed()) { - if (data_size > 0) { - // Packed fields get serialized like a string, not their native type. - // Technically this doesn't really matter; the size only changes if it's - // a GROUP - our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING); - our_size += io::CodedOutputStream::VarintSize32(data_size); - } - } else { - our_size += count * TagSize(field->number(), field->type()); - } - return our_size; -} - -int WireFormat::FieldDataOnlyByteSize( - const FieldDescriptor* field, - const Message& message) { - const Reflection* message_reflection = message.GetReflection(); - - int count = 0; - if (field->is_repeated()) { - count = message_reflection->FieldSize(message, field); - } else if (message_reflection->HasField(message, field)) { - count = 1; - } - - int data_size = 0; - switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - if (field->is_repeated()) { \ - for (int j = 0; j < count; j++) { \ - data_size += WireFormatLite::TYPE_METHOD##Size( \ - message_reflection->GetRepeated##CPPTYPE_METHOD( \ - message, field, j)); \ - } \ - } else { \ - data_size += WireFormatLite::TYPE_METHOD##Size( \ - message_reflection->Get##CPPTYPE_METHOD(message, field)); \ - } \ - break; - -#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ - break; - - HANDLE_TYPE( INT32, Int32, Int32) - HANDLE_TYPE( INT64, Int64, Int64) - HANDLE_TYPE(SINT32, SInt32, Int32) - HANDLE_TYPE(SINT64, SInt64, Int64) - HANDLE_TYPE(UINT32, UInt32, UInt32) - HANDLE_TYPE(UINT64, UInt64, UInt64) - - HANDLE_FIXED_TYPE( FIXED32, Fixed32) - HANDLE_FIXED_TYPE( FIXED64, Fixed64) - HANDLE_FIXED_TYPE(SFIXED32, SFixed32) - HANDLE_FIXED_TYPE(SFIXED64, SFixed64) - - HANDLE_FIXED_TYPE(FLOAT , Float ) - HANDLE_FIXED_TYPE(DOUBLE, Double) - - HANDLE_FIXED_TYPE(BOOL, Bool) - - HANDLE_TYPE(GROUP , Group , Message) - HANDLE_TYPE(MESSAGE, Message, Message) -#undef HANDLE_TYPE -#undef HANDLE_FIXED_TYPE - - case FieldDescriptor::TYPE_ENUM: { - if (field->is_repeated()) { - for (int j = 0; j < count; j++) { - data_size += WireFormatLite::EnumSize( - message_reflection->GetRepeatedEnum(message, field, j)->number()); - } - } else { - data_size += WireFormatLite::EnumSize( - message_reflection->GetEnum(message, field)->number()); - } - break; - } - - // Handle strings separately so that we can get string references - // instead of copying. - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: { - for (int j = 0; j < count; j++) { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - data_size += WireFormatLite::StringSize(value); - } - break; - } - } - return data_size; -} - -int WireFormat::MessageSetItemByteSize( - const FieldDescriptor* field, - const Message& message) { - const Reflection* message_reflection = message.GetReflection(); - - int our_size = WireFormatLite::kMessageSetItemTagsSize; - - // type_id - our_size += io::CodedOutputStream::VarintSize32(field->number()); - - // message - const Message& sub_message = message_reflection->GetMessage(message, field); - int message_size = sub_message.ByteSize(); - - our_size += io::CodedOutputStream::VarintSize32(message_size); - our_size += message_size; - - return our_size; -} - -void WireFormat::VerifyUTF8StringFallback(const char* data, - int size, - Operation op) { - if (!IsStructurallyValidUTF8(data, size)) { - const char* operation_str = NULL; - switch (op) { - case PARSE: - operation_str = "parsing"; - break; - case SERIALIZE: - operation_str = "serializing"; - break; - // no default case: have the compiler warn if a case is not covered. - } - GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while " - << operation_str - << " protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes."; - } -} - - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/wire_format.h b/Resources/NetHook/google/protobuf/wire_format.h deleted file mode 100644 index c7539250..00000000 --- a/Resources/NetHook/google/protobuf/wire_format.h +++ /dev/null @@ -1,304 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// atenasio@google.com (Chris Atenasio) (ZigZag transform) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ - -#include -#include -#include -#include -#include - -// Do UTF-8 validation on string type in Debug build only -#ifndef NDEBUG -#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -#endif - -namespace google { -namespace protobuf { - namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h - } - class UnknownFieldSet; // unknown_field_set.h -} - -namespace protobuf { -namespace internal { - -// This class is for internal use by the protocol buffer library and by -// protocol-complier-generated message classes. It must not be called -// directly by clients. -// -// This class contains code for implementing the binary protocol buffer -// wire format via reflection. The WireFormatLite class implements the -// non-reflection based routines. -// -// This class is really a namespace that contains only static methods -class LIBPROTOBUF_EXPORT WireFormat { - public: - - // Given a field return its WireType - static inline WireFormatLite::WireType WireTypeForField( - const FieldDescriptor* field); - - // Given a FieldSescriptor::Type return its WireType - static inline WireFormatLite::WireType WireTypeForFieldType( - FieldDescriptor::Type type); - - // Compute the byte size of a tag. For groups, this includes both the start - // and end tags. - static inline int TagSize(int field_number, FieldDescriptor::Type type); - - // These procedures can be used to implement the methods of Message which - // handle parsing and serialization of the protocol buffer wire format - // using only the Reflection interface. When you ask the protocol - // compiler to optimize for code size rather than speed, it will implement - // those methods in terms of these procedures. Of course, these are much - // slower than the specialized implementations which the protocol compiler - // generates when told to optimize for speed. - - // Read a message in protocol buffer wire format. - // - // This procedure reads either to the end of the input stream or through - // a WIRETYPE_END_GROUP tag ending the message, whichever comes first. - // It returns false if the input is invalid. - // - // Required fields are NOT checked by this method. You must call - // IsInitialized() on the resulting message yourself. - static bool ParseAndMergePartial(io::CodedInputStream* input, - Message* message); - - // Serialize a message in protocol buffer wire format. - // - // Any embedded messages within the message must have their correct sizes - // cached. However, the top-level message need not; its size is passed as - // a parameter to this procedure. - // - // These return false iff the underlying stream returns a write error. - static void SerializeWithCachedSizes( - const Message& message, - int size, io::CodedOutputStream* output); - - // Implements Message::ByteSize() via reflection. WARNING: The result - // of this method is *not* cached anywhere. However, all embedded messages - // will have their ByteSize() methods called, so their sizes will be cached. - // Therefore, calling this method is sufficient to allow you to call - // WireFormat::SerializeWithCachedSizes() on the same object. - static int ByteSize(const Message& message); - - // ----------------------------------------------------------------- - // Helpers for dealing with unknown fields - - // Skips a field value of the given WireType. The input should start - // positioned immediately after the tag. If unknown_fields is non-NULL, - // the contents of the field will be added to it. - static bool SkipField(io::CodedInputStream* input, uint32 tag, - UnknownFieldSet* unknown_fields); - - // Reads and ignores a message from the input. If unknown_fields is non-NULL, - // the contents will be added to it. - static bool SkipMessage(io::CodedInputStream* input, - UnknownFieldSet* unknown_fields); - - // Write the contents of an UnknownFieldSet to the output. - static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output); - // Same as above, except writing directly to the provided buffer. - // Requires that the buffer have sufficient capacity for - // ComputeUnknownFieldsSize(unknown_fields). - // - // Returns a pointer past the last written byte. - static uint8* SerializeUnknownFieldsToArray( - const UnknownFieldSet& unknown_fields, - uint8* target); - - // Same thing except for messages that have the message_set_wire_format - // option. - static void SerializeUnknownMessageSetItems( - const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output); - // Same as above, except writing directly to the provided buffer. - // Requires that the buffer have sufficient capacity for - // ComputeUnknownMessageSetItemsSize(unknown_fields). - // - // Returns a pointer past the last written byte. - static uint8* SerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, - uint8* target); - - // Compute the size of the UnknownFieldSet on the wire. - static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields); - - // Same thing except for messages that have the message_set_wire_format - // option. - static int ComputeUnknownMessageSetItemsSize( - const UnknownFieldSet& unknown_fields); - - - // Helper functions for encoding and decoding tags. (Inlined below and in - // _inl.h) - // - // This is different from MakeTag(field->number(), field->type()) in the case - // of packed repeated fields. - static uint32 MakeTag(const FieldDescriptor* field); - - // Parse a single field. The input should start out positioned immidately - // after the tag. - static bool ParseAndMergeField( - uint32 tag, - const FieldDescriptor* field, // May be NULL for unknown - Message* message, - io::CodedInputStream* input); - - // Serialize a single field. - static void SerializeFieldWithCachedSizes( - const FieldDescriptor* field, // Cannot be NULL - const Message& message, - io::CodedOutputStream* output); - - // Compute size of a single field. If the field is a message type, this - // will call ByteSize() for the embedded message, insuring that it caches - // its size. - static int FieldByteSize( - const FieldDescriptor* field, // Cannot be NULL - const Message& message); - - // Parse/serialize a MessageSet::Item group. Used with messages that use - // opion message_set_wire_format = true. - static bool ParseAndMergeMessageSetItem( - io::CodedInputStream* input, - Message* message); - static void SerializeMessageSetItemWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output); - static int MessageSetItemByteSize( - const FieldDescriptor* field, - const Message& message); - - // Computes the byte size of a field, excluding tags. For packed fields, it - // only includes the size of the raw data, and not the size of the total - // length, but for other length-delimited types, the size of the length is - // included. - static int FieldDataOnlyByteSize( - const FieldDescriptor* field, // Cannot be NULL - const Message& message); - - enum Operation { - PARSE, - SERIALIZE, - }; - - // Verifies that a string field is valid UTF8, logging an error if not. - static void VerifyUTF8String(const char* data, int size, Operation op); - - private: - // Verifies that a string field is valid UTF8, logging an error if not. - static void VerifyUTF8StringFallback( - const char* data, - int size, - Operation op); - - - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); -}; - -// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet. -class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { - public: - UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) - : unknown_fields_(unknown_fields) {} - virtual ~UnknownFieldSetFieldSkipper() {} - - // implements FieldSkipper ----------------------------------------- - virtual bool SkipField(io::CodedInputStream* input, uint32 tag); - virtual bool SkipMessage(io::CodedInputStream* input); - virtual void SkipUnknownEnum(int field_number, int value); - - private: - UnknownFieldSet* unknown_fields_; -}; - -// inline methods ==================================================== - -inline WireFormatLite::WireType WireFormat::WireTypeForField( - const FieldDescriptor* field) { - if (field->options().packed()) { - return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - } else { - return WireTypeForFieldType(field->type()); - } -} - -inline WireFormatLite::WireType WireFormat::WireTypeForFieldType( - FieldDescriptor::Type type) { - // Some compilers don't like enum -> enum casts, so we implicit_cast to - // int first. - return WireFormatLite::WireTypeForFieldType( - static_cast( - implicit_cast(type))); -} - -inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { - return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); -} - -inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { - // Some compilers don't like enum -> enum casts, so we implicit_cast to - // int first. - return WireFormatLite::TagSize(field_number, - static_cast( - implicit_cast(type))); -} - -inline void WireFormat::VerifyUTF8String(const char* data, int size, - WireFormat::Operation op) { -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - WireFormat::VerifyUTF8StringFallback(data, size, op); -#endif -} - - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__ diff --git a/Resources/NetHook/google/protobuf/wire_format_lite.cc b/Resources/NetHook/google/protobuf/wire_format_lite.cc deleted file mode 100644 index d347d116..00000000 --- a/Resources/NetHook/google/protobuf/wire_format_lite.cc +++ /dev/null @@ -1,359 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { - -#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC - // requires them. -const int WireFormatLite::kMessageSetItemStartTag; -const int WireFormatLite::kMessageSetItemEndTag; -const int WireFormatLite::kMessageSetTypeIdTag; -const int WireFormatLite::kMessageSetMessageTag; - -#endif - -const int WireFormatLite::kMessageSetItemTagsSize = - io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) + - io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) + - io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) + - io::CodedOutputStream::VarintSize32(kMessageSetMessageTag); - -const WireFormatLite::CppType -WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { - static_cast(0), // 0 is reserved for errors - - CPPTYPE_DOUBLE, // TYPE_DOUBLE - CPPTYPE_FLOAT, // TYPE_FLOAT - CPPTYPE_INT64, // TYPE_INT64 - CPPTYPE_UINT64, // TYPE_UINT64 - CPPTYPE_INT32, // TYPE_INT32 - CPPTYPE_UINT64, // TYPE_FIXED64 - CPPTYPE_UINT32, // TYPE_FIXED32 - CPPTYPE_BOOL, // TYPE_BOOL - CPPTYPE_STRING, // TYPE_STRING - CPPTYPE_MESSAGE, // TYPE_GROUP - CPPTYPE_MESSAGE, // TYPE_MESSAGE - CPPTYPE_STRING, // TYPE_BYTES - CPPTYPE_UINT32, // TYPE_UINT32 - CPPTYPE_ENUM, // TYPE_ENUM - CPPTYPE_INT32, // TYPE_SFIXED32 - CPPTYPE_INT64, // TYPE_SFIXED64 - CPPTYPE_INT32, // TYPE_SINT32 - CPPTYPE_INT64, // TYPE_SINT64 -}; - -const WireFormatLite::WireType -WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { - static_cast(-1), // invalid - WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE - WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT - WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 - WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 - WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 - WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 - WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 - WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING - WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES - WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 - WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM - WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 - WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 - WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 - WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 -}; - -bool WireFormatLite::SkipField( - io::CodedInputStream* input, uint32 tag) { - switch (WireFormatLite::GetTagWireType(tag)) { - case WireFormatLite::WIRETYPE_VARINT: { - uint64 value; - if (!input->ReadVarint64(&value)) return false; - return true; - } - case WireFormatLite::WIRETYPE_FIXED64: { - uint64 value; - if (!input->ReadLittleEndian64(&value)) return false; - return true; - } - case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->Skip(length)) return false; - return true; - } - case WireFormatLite::WIRETYPE_START_GROUP: { - if (!input->IncrementRecursionDepth()) return false; - if (!SkipMessage(input)) return false; - input->DecrementRecursionDepth(); - // Check that the ending tag matched the starting tag. - if (!input->LastTagWas(WireFormatLite::MakeTag( - WireFormatLite::GetTagFieldNumber(tag), - WireFormatLite::WIRETYPE_END_GROUP))) { - return false; - } - return true; - } - case WireFormatLite::WIRETYPE_END_GROUP: { - return false; - } - case WireFormatLite::WIRETYPE_FIXED32: { - uint32 value; - if (!input->ReadLittleEndian32(&value)) return false; - return true; - } - default: { - return false; - } - } -} - -bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { - while(true) { - uint32 tag = input->ReadTag(); - if (tag == 0) { - // End of input. This is a valid place to end, so return true. - return true; - } - - WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); - - if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { - // Must be the end of the message. - return true; - } - - if (!SkipField(input, tag)) return false; - } -} - -bool FieldSkipper::SkipField( - io::CodedInputStream* input, uint32 tag) { - return WireFormatLite::SkipField(input, tag); -} - -bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { - return WireFormatLite::SkipMessage(input); -} - -void FieldSkipper::SkipUnknownEnum( - int field_number, int value) { - // Nothing. -} - -bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input, - bool (*is_valid)(int), - RepeatedField* values) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - while (input->BytesUntilLimit() > 0) { - int value; - if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, WireFormatLite::TYPE_ENUM>(input, &value)) { - return false; - } - if (is_valid(value)) { - values->Add(value); - } - } - input->PopLimit(limit); - return true; -} - -void WireFormatLite::WriteInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt32NoTag(value, output); -} -void WireFormatLite::WriteInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt64NoTag(value, output); -} -void WireFormatLite::WriteUInt32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt32NoTag(value, output); -} -void WireFormatLite::WriteUInt64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt64NoTag(value, output); -} -void WireFormatLite::WriteSInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt32NoTag(value, output); -} -void WireFormatLite::WriteSInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt64NoTag(value, output); -} -void WireFormatLite::WriteFixed32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFixed32NoTag(value, output); -} -void WireFormatLite::WriteFixed64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteFixed64NoTag(value, output); -} -void WireFormatLite::WriteSFixed32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteSFixed32NoTag(value, output); -} -void WireFormatLite::WriteSFixed64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteSFixed64NoTag(value, output); -} -void WireFormatLite::WriteFloat(int field_number, float value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFloatNoTag(value, output); -} -void WireFormatLite::WriteDouble(int field_number, double value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteDoubleNoTag(value, output); -} -void WireFormatLite::WriteBool(int field_number, bool value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteBoolNoTag(value, output); -} -void WireFormatLite::WriteEnum(int field_number, int value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteEnumNoTag(value, output); -} - -void WireFormatLite::WriteString(int field_number, const string& value, - io::CodedOutputStream* output) { - // String is for UTF-8 text only - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} -void WireFormatLite::WriteBytes(int field_number, const string& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} - - -void WireFormatLite::WriteGroup(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.SerializeWithCachedSizes(output); - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} - -void WireFormatLite::WriteMessage(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - const int size = value.GetCachedSize(); - output->WriteVarint32(size); - value.SerializeWithCachedSizes(output); -} - -void WireFormatLite::WriteGroupMaybeToArray(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - const int size = value.GetCachedSize(); - uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); - if (target != NULL) { - uint8* end = value.SerializeWithCachedSizesToArray(target); - GOOGLE_DCHECK_EQ(end - target, size); - } else { - value.SerializeWithCachedSizes(output); - } - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} - -void WireFormatLite::WriteMessageMaybeToArray(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - const int size = value.GetCachedSize(); - output->WriteVarint32(size); - uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); - if (target != NULL) { - uint8* end = value.SerializeWithCachedSizesToArray(target); - GOOGLE_DCHECK_EQ(end - target, size); - } else { - value.SerializeWithCachedSizes(output); - } -} - -bool WireFormatLite::ReadString(io::CodedInputStream* input, - string* value) { - // String is for UTF-8 text only - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->InternalReadStringInline(value, length)) return false; - return true; -} -bool WireFormatLite::ReadBytes(io::CodedInputStream* input, - string* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - return input->InternalReadStringInline(value, length); -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/google/protobuf/wire_format_lite.h b/Resources/NetHook/google/protobuf/wire_format_lite.h deleted file mode 100644 index e3d5b2d8..00000000 --- a/Resources/NetHook/google/protobuf/wire_format_lite.h +++ /dev/null @@ -1,620 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// atenasio@google.com (Chris Atenasio) (ZigZag transform) -// wink@google.com (Wink Saville) (refactored from wire_format.h) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ - -#include -#include - -namespace google { - -namespace protobuf { - template class RepeatedField; // repeated_field.h - namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h - } -} - -namespace protobuf { -namespace internal { - -class StringPieceField; - -// This class is for internal use by the protocol buffer library and by -// protocol-complier-generated message classes. It must not be called -// directly by clients. -// -// This class contains helpers for implementing the binary protocol buffer -// wire format without the need for reflection. Use WireFormat when using -// reflection. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT WireFormatLite { - public: - - // ----------------------------------------------------------------- - // Helper constants and functions related to the format. These are - // mostly meant for internal and generated code to use. - - // The wire format is composed of a sequence of tag/value pairs, each - // of which contains the value of one field (or one element of a repeated - // field). Each tag is encoded as a varint. The lower bits of the tag - // identify its wire type, which specifies the format of the data to follow. - // The rest of the bits contain the field number. Each type of field (as - // declared by FieldDescriptor::Type, in descriptor.h) maps to one of - // these wire types. Immediately following each tag is the field's value, - // encoded in the format specified by the wire type. Because the tag - // identifies the encoding of this data, it is possible to skip - // unrecognized fields for forwards compatibility. - - enum WireType { - WIRETYPE_VARINT = 0, - WIRETYPE_FIXED64 = 1, - WIRETYPE_LENGTH_DELIMITED = 2, - WIRETYPE_START_GROUP = 3, - WIRETYPE_END_GROUP = 4, - WIRETYPE_FIXED32 = 5, - }; - - // Lite alternative to FieldDescriptor::Type. Must be kept in sync. - enum FieldType { - TYPE_DOUBLE = 1, - TYPE_FLOAT = 2, - TYPE_INT64 = 3, - TYPE_UINT64 = 4, - TYPE_INT32 = 5, - TYPE_FIXED64 = 6, - TYPE_FIXED32 = 7, - TYPE_BOOL = 8, - TYPE_STRING = 9, - TYPE_GROUP = 10, - TYPE_MESSAGE = 11, - TYPE_BYTES = 12, - TYPE_UINT32 = 13, - TYPE_ENUM = 14, - TYPE_SFIXED32 = 15, - TYPE_SFIXED64 = 16, - TYPE_SINT32 = 17, - TYPE_SINT64 = 18, - MAX_FIELD_TYPE = 18, - }; - - // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. - enum CppType { - CPPTYPE_INT32 = 1, - CPPTYPE_INT64 = 2, - CPPTYPE_UINT32 = 3, - CPPTYPE_UINT64 = 4, - CPPTYPE_DOUBLE = 5, - CPPTYPE_FLOAT = 6, - CPPTYPE_BOOL = 7, - CPPTYPE_ENUM = 8, - CPPTYPE_STRING = 9, - CPPTYPE_MESSAGE = 10, - MAX_CPPTYPE = 10, - }; - - // Helper method to get the CppType for a particular Type. - static CppType FieldTypeToCppType(FieldType type); - - // Given a FieldSescriptor::Type return its WireType - static inline WireFormatLite::WireType WireTypeForFieldType( - WireFormatLite::FieldType type) { - return kWireTypeForFieldType[type]; - } - - // Number of bits in a tag which identify the wire type. - static const int kTagTypeBits = 3; - // Mask for those bits. - static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; - - // Helper functions for encoding and decoding tags. (Inlined below and in - // _inl.h) - // - // This is different from MakeTag(field->number(), field->type()) in the case - // of packed repeated fields. - static uint32 MakeTag(int field_number, WireType type); - static WireType GetTagWireType(uint32 tag); - static int GetTagFieldNumber(uint32 tag); - - // Compute the byte size of a tag. For groups, this includes both the start - // and end tags. - static inline int TagSize(int field_number, WireFormatLite::FieldType type); - - // Skips a field value with the given tag. The input should start - // positioned immediately after the tag. Skipped values are simply discarded, - // not recorded anywhere. See WireFormat::SkipField() for a version that - // records to an UnknownFieldSet. - static bool SkipField(io::CodedInputStream* input, uint32 tag); - - // Reads and ignores a message from the input. Skipped values are simply - // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a - // version that records to an UnknownFieldSet. - static bool SkipMessage(io::CodedInputStream* input); - -// This macro does the same thing as WireFormatLite::MakeTag(), but the -// result is usable as a compile-time constant, which makes it usable -// as a switch case or a template input. WireFormatLite::MakeTag() is more -// type-safe, though, so prefer it if possible. -#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ - static_cast( \ - ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \ - | (TYPE)) - - // These are the tags for the old MessageSet format, which was defined as: - // message MessageSet { - // repeated group Item = 1 { - // required int32 type_id = 2; - // required string message = 3; - // } - // } - static const int kMessageSetItemNumber = 1; - static const int kMessageSetTypeIdNumber = 2; - static const int kMessageSetMessageNumber = 3; - static const int kMessageSetItemStartTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, - WireFormatLite::WIRETYPE_START_GROUP); - static const int kMessageSetItemEndTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, - WireFormatLite::WIRETYPE_END_GROUP); - static const int kMessageSetTypeIdTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, - WireFormatLite::WIRETYPE_VARINT); - static const int kMessageSetMessageTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - - // Byte size of all tags of a MessageSet::Item combined. - static const int kMessageSetItemTagsSize; - - // Helper functions for converting between floats/doubles and IEEE-754 - // uint32s/uint64s so that they can be written. (Assumes your platform - // uses IEEE-754 floats.) - static uint32 EncodeFloat(float value); - static float DecodeFloat(uint32 value); - static uint64 EncodeDouble(double value); - static double DecodeDouble(uint64 value); - - // Helper functions for mapping signed integers to unsigned integers in - // such a way that numbers with small magnitudes will encode to smaller - // varints. If you simply static_cast a negative number to an unsigned - // number and varint-encode it, it will always take 10 bytes, defeating - // the purpose of varint. So, for the "sint32" and "sint64" field types, - // we ZigZag-encode the values. - static uint32 ZigZagEncode32(int32 n); - static int32 ZigZagDecode32(uint32 n); - static uint64 ZigZagEncode64(int64 n); - static int64 ZigZagDecode64(uint64 n); - - // ================================================================= - // Methods for reading/writing individual field. The implementations - // of these methods are defined in wire_format_lite_inl.h; you must #include - // that file to use these. - -// Avoid ugly line wrapping -#define input io::CodedInputStream* input -#define output io::CodedOutputStream* output -#define field_number int field_number -#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE - - // Read fields, not including tags. The assumption is that you already - // read the tag to determine what field to read. - - // For primitive fields, we just use a templatized routine parameterized by - // the represented type and the FieldType. These are specialized with the - // appropriate definition for each declared type. - template - static inline bool ReadPrimitive(input, CType* value) INL; - - // Reads repeated primitive values, with optimizations for repeats. - // tag_size and tag should both be compile-time constants provided by the - // protocol compiler. - template - static inline bool ReadRepeatedPrimitive(int tag_size, - uint32 tag, - input, - RepeatedField* value) INL; - - // Identical to ReadRepeatedPrimitive, except will not inline the - // implementation. - template - static bool ReadRepeatedPrimitiveNoInline(int tag_size, - uint32 tag, - input, - RepeatedField* value); - - // Reads a primitive value directly from the provided buffer. It returns a - // pointer past the segment of data that was read. - // - // This is only implemented for the types with fixed wire size, e.g. - // float, double, and the (s)fixed* types. - template - static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer, - CType* value) INL; - - // Reads a primitive packed field. - // - // This is only implemented for packable types. - template - static inline bool ReadPackedPrimitive(input, - RepeatedField* value) INL; - - // Identical to ReadPackedPrimitive, except will not inline the - // implementation. - template - static bool ReadPackedPrimitiveNoInline(input, RepeatedField* value); - - // Read a packed enum field. Values for which is_valid() returns false are - // dropped. - static bool ReadPackedEnumNoInline(input, - bool (*is_valid)(int), - RepeatedField* value); - - static bool ReadString(input, string* value); - static bool ReadBytes (input, string* value); - - static inline bool ReadGroup (field_number, input, MessageLite* value); - static inline bool ReadMessage(input, MessageLite* value); - - // Like above, but de-virtualize the call to MergePartialFromCodedStream(). - // The pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override MergePartialFromCodedStream()). - template - static inline bool ReadGroupNoVirtual(field_number, input, - MessageType* value); - template - static inline bool ReadMessageNoVirtual(input, MessageType* value); - - // Write a tag. The Write*() functions typically include the tag, so - // normally there's no need to call this unless using the Write*NoTag() - // variants. - static inline void WriteTag(field_number, WireType type, output) INL; - - // Write fields, without tags. - static inline void WriteInt32NoTag (int32 value, output) INL; - static inline void WriteInt64NoTag (int64 value, output) INL; - static inline void WriteUInt32NoTag (uint32 value, output) INL; - static inline void WriteUInt64NoTag (uint64 value, output) INL; - static inline void WriteSInt32NoTag (int32 value, output) INL; - static inline void WriteSInt64NoTag (int64 value, output) INL; - static inline void WriteFixed32NoTag (uint32 value, output) INL; - static inline void WriteFixed64NoTag (uint64 value, output) INL; - static inline void WriteSFixed32NoTag(int32 value, output) INL; - static inline void WriteSFixed64NoTag(int64 value, output) INL; - static inline void WriteFloatNoTag (float value, output) INL; - static inline void WriteDoubleNoTag (double value, output) INL; - static inline void WriteBoolNoTag (bool value, output) INL; - static inline void WriteEnumNoTag (int value, output) INL; - - // Write fields, including tags. - static void WriteInt32 (field_number, int32 value, output); - static void WriteInt64 (field_number, int64 value, output); - static void WriteUInt32 (field_number, uint32 value, output); - static void WriteUInt64 (field_number, uint64 value, output); - static void WriteSInt32 (field_number, int32 value, output); - static void WriteSInt64 (field_number, int64 value, output); - static void WriteFixed32 (field_number, uint32 value, output); - static void WriteFixed64 (field_number, uint64 value, output); - static void WriteSFixed32(field_number, int32 value, output); - static void WriteSFixed64(field_number, int64 value, output); - static void WriteFloat (field_number, float value, output); - static void WriteDouble (field_number, double value, output); - static void WriteBool (field_number, bool value, output); - static void WriteEnum (field_number, int value, output); - - static void WriteString(field_number, const string& value, output); - static void WriteBytes (field_number, const string& value, output); - - static void WriteGroup( - field_number, const MessageLite& value, output); - static void WriteMessage( - field_number, const MessageLite& value, output); - // Like above, but these will check if the output stream has enough - // space to write directly to a flat array. - static void WriteGroupMaybeToArray( - field_number, const MessageLite& value, output); - static void WriteMessageMaybeToArray( - field_number, const MessageLite& value, output); - - // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override SerializeWithCachedSizes()). - template - static inline void WriteGroupNoVirtual( - field_number, const MessageType& value, output); - template - static inline void WriteMessageNoVirtual( - field_number, const MessageType& value, output); - -#undef output -#define output uint8* target - - // Like above, but use only *ToArray methods of CodedOutputStream. - static inline uint8* WriteTagToArray(field_number, WireType type, output) INL; - - // Write fields, without tags. - static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL; - static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL; - static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL; - static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL; - static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL; - static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL; - static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL; - static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL; - static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL; - static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL; - static inline uint8* WriteFloatNoTagToArray (float value, output) INL; - static inline uint8* WriteDoubleNoTagToArray (double value, output) INL; - static inline uint8* WriteBoolNoTagToArray (bool value, output) INL; - static inline uint8* WriteEnumNoTagToArray (int value, output) INL; - - // Write fields, including tags. - static inline uint8* WriteInt32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteInt64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteUInt32ToArray( - field_number, uint32 value, output) INL; - static inline uint8* WriteUInt64ToArray( - field_number, uint64 value, output) INL; - static inline uint8* WriteSInt32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteSInt64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteFixed32ToArray( - field_number, uint32 value, output) INL; - static inline uint8* WriteFixed64ToArray( - field_number, uint64 value, output) INL; - static inline uint8* WriteSFixed32ToArray( - field_number, int32 value, output) INL; - static inline uint8* WriteSFixed64ToArray( - field_number, int64 value, output) INL; - static inline uint8* WriteFloatToArray( - field_number, float value, output) INL; - static inline uint8* WriteDoubleToArray( - field_number, double value, output) INL; - static inline uint8* WriteBoolToArray( - field_number, bool value, output) INL; - static inline uint8* WriteEnumToArray( - field_number, int value, output) INL; - - static inline uint8* WriteStringToArray( - field_number, const string& value, output) INL; - static inline uint8* WriteBytesToArray( - field_number, const string& value, output) INL; - - static inline uint8* WriteGroupToArray( - field_number, const MessageLite& value, output) INL; - static inline uint8* WriteMessageToArray( - field_number, const MessageLite& value, output) INL; - - // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override SerializeWithCachedSizes()). - template - static inline uint8* WriteGroupNoVirtualToArray( - field_number, const MessageType& value, output) INL; - template - static inline uint8* WriteMessageNoVirtualToArray( - field_number, const MessageType& value, output) INL; - -#undef output -#undef input -#undef INL - -#undef field_number - - // Compute the byte size of a field. The XxSize() functions do NOT include - // the tag, so you must also call TagSize(). (This is because, for repeated - // fields, you should only call TagSize() once and multiply it by the element - // count, but you may have to call XxSize() for each individual element.) - static inline int Int32Size ( int32 value); - static inline int Int64Size ( int64 value); - static inline int UInt32Size (uint32 value); - static inline int UInt64Size (uint64 value); - static inline int SInt32Size ( int32 value); - static inline int SInt64Size ( int64 value); - static inline int EnumSize ( int value); - - // These types always have the same size. - static const int kFixed32Size = 4; - static const int kFixed64Size = 8; - static const int kSFixed32Size = 4; - static const int kSFixed64Size = 8; - static const int kFloatSize = 4; - static const int kDoubleSize = 8; - static const int kBoolSize = 1; - - static inline int StringSize(const string& value); - static inline int BytesSize (const string& value); - - static inline int GroupSize (const MessageLite& value); - static inline int MessageSize(const MessageLite& value); - - // Like above, but de-virtualize the call to ByteSize(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override ByteSize()). - template - static inline int GroupSizeNoVirtual (const MessageType& value); - template - static inline int MessageSizeNoVirtual(const MessageType& value); - - private: - // A helper method for the repeated primitive reader. This method has - // optimizations for primitive types that have fixed size on the wire, and - // can be read using potentially faster paths. - template - static inline bool ReadRepeatedFixedSizePrimitive( - int tag_size, - uint32 tag, - google::protobuf::io::CodedInputStream* input, - RepeatedField* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - static const CppType kFieldTypeToCppTypeMap[]; - static const WireFormatLite::WireType kWireTypeForFieldType[]; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); -}; - -// A class which deals with unknown values. The default implementation just -// discards them. WireFormat defines a subclass which writes to an -// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since -// ExtensionSet is part of the lite library but UnknownFieldSet is not. -class LIBPROTOBUF_EXPORT FieldSkipper { - public: - FieldSkipper() {} - virtual ~FieldSkipper() {} - - // Skip a field whose tag has already been consumed. - virtual bool SkipField(io::CodedInputStream* input, uint32 tag); - - // Skip an entire message or group, up to an end-group tag (which is consumed) - // or end-of-stream. - virtual bool SkipMessage(io::CodedInputStream* input); - - // Deal with an already-parsed unrecognized enum value. The default - // implementation does nothing, but the UnknownFieldSet-based implementation - // saves it as an unknown varint. - virtual void SkipUnknownEnum(int field_number, int value); -}; - -// inline methods ==================================================== - -inline WireFormatLite::CppType -WireFormatLite::FieldTypeToCppType(FieldType type) { - return kFieldTypeToCppTypeMap[type]; -} - -inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) { - return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); -} - -inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { - return static_cast(tag & kTagTypeMask); -} - -inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { - return static_cast(tag >> kTagTypeBits); -} - -inline int WireFormatLite::TagSize(int field_number, - WireFormatLite::FieldType type) { - int result = io::CodedOutputStream::VarintSize32( - field_number << kTagTypeBits); - if (type == TYPE_GROUP) { - // Groups have both a start and an end tag. - return result * 2; - } else { - return result; - } -} - -inline uint32 WireFormatLite::EncodeFloat(float value) { - union {float f; uint32 i;}; - f = value; - return i; -} - -inline float WireFormatLite::DecodeFloat(uint32 value) { - union {float f; uint32 i;}; - i = value; - return f; -} - -inline uint64 WireFormatLite::EncodeDouble(double value) { - union {double f; uint64 i;}; - f = value; - return i; -} - -inline double WireFormatLite::DecodeDouble(uint64 value) { - union {double f; uint64 i;}; - i = value; - return f; -} - -// ZigZag Transform: Encodes signed integers so that they can be -// effectively used with varint encoding. -// -// varint operates on unsigned integers, encoding smaller numbers into -// fewer bytes. If you try to use it on a signed integer, it will treat -// this number as a very large unsigned integer, which means that even -// small signed numbers like -1 will take the maximum number of bytes -// (10) to encode. ZigZagEncode() maps signed integers to unsigned -// in such a way that those with a small absolute value will have smaller -// encoded values, making them appropriate for encoding using varint. -// -// int32 -> uint32 -// ------------------------- -// 0 -> 0 -// -1 -> 1 -// 1 -> 2 -// -2 -> 3 -// ... -> ... -// 2147483647 -> 4294967294 -// -2147483648 -> 4294967295 -// -// >> encode >> -// << decode << - -inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 31); -} - -inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { - return (n >> 1) ^ -static_cast(n & 1); -} - -inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 63); -} - -inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { - return (n >> 1) ^ -static_cast(n & 1); -} - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ diff --git a/Resources/NetHook/google/protobuf/wire_format_lite_inl.h b/Resources/NetHook/google/protobuf/wire_format_lite_inl.h deleted file mode 100644 index d7b2c302..00000000 --- a/Resources/NetHook/google/protobuf/wire_format_lite_inl.h +++ /dev/null @@ -1,747 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// wink@google.com (Wink Saville) (refactored from wire_format.h) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ - -#include -#include -#include -#include -#include -#include -#include - - -namespace google { -namespace protobuf { -namespace internal { - -// Implementation details of ReadPrimitive. - -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = static_cast(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - uint32* value) { - return input->ReadVarint32(value); -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - uint64* value) { - return input->ReadVarint64(value); -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = ZigZagDecode32(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = ZigZagDecode64(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - uint32* value) { - return input->ReadLittleEndian32(value); -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - uint64* value) { - return input->ReadLittleEndian64(value); -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int32* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = static_cast(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int64* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = static_cast(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - float* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = DecodeFloat(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - double* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = DecodeDouble(temp); - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - bool* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = temp != 0; - return true; -} -template <> -inline bool WireFormatLite::ReadPrimitive( - io::CodedInputStream* input, - int* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast(temp); - return true; -} - -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - uint32, WireFormatLite::TYPE_FIXED32>( - const uint8* buffer, - uint32* value) { - return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); -} -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - uint64, WireFormatLite::TYPE_FIXED64>( - const uint8* buffer, - uint64* value) { - return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); -} -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - int32, WireFormatLite::TYPE_SFIXED32>( - const uint8* buffer, - int32* value) { - uint32 temp; - buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); - *value = static_cast(temp); - return buffer; -} -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - int64, WireFormatLite::TYPE_SFIXED64>( - const uint8* buffer, - int64* value) { - uint64 temp; - buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); - *value = static_cast(temp); - return buffer; -} -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - float, WireFormatLite::TYPE_FLOAT>( - const uint8* buffer, - float* value) { - uint32 temp; - buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); - *value = DecodeFloat(temp); - return buffer; -} -template <> -inline const uint8* WireFormatLite::ReadPrimitiveFromArray< - double, WireFormatLite::TYPE_DOUBLE>( - const uint8* buffer, - double* value) { - uint64 temp; - buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); - *value = DecodeDouble(temp); - return buffer; -} - -template -inline bool WireFormatLite::ReadRepeatedPrimitive(int tag_size, - uint32 tag, - io::CodedInputStream* input, - RepeatedField* values) { - CType value; - if (!ReadPrimitive(input, &value)) return false; - values->Add(value); - int elements_already_reserved = values->Capacity() - values->size(); - while (elements_already_reserved > 0 && input->ExpectTag(tag)) { - if (!ReadPrimitive(input, &value)) return false; - values->AddAlreadyReserved(value); - elements_already_reserved--; - } - return true; -} - -template -inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( - int tag_size, - uint32 tag, - io::CodedInputStream* input, - RepeatedField* values) { - GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); - CType value; - if (!ReadPrimitive(input, &value)) - return false; - values->Add(value); - - // For fixed size values, repeated values can be read more quickly by - // reading directly from a raw array. - // - // We can get a tight loop by only reading as many elements as can be - // added to the RepeatedField without having to do any resizing. Additionally, - // we only try to read as many elements as are available from the current - // buffer space. Doing so avoids having to perform boundary checks when - // reading the value: the maximum number of elements that can be read is - // known outside of the loop. - const void* void_pointer; - int size; - input->GetDirectBufferPointerInline(&void_pointer, &size); - if (size > 0) { - const uint8* buffer = reinterpret_cast(void_pointer); - // The number of bytes each type occupies on the wire. - const int per_value_size = tag_size + sizeof(value); - - int elements_available = min(values->Capacity() - values->size(), - size / per_value_size); - int num_read = 0; - while (num_read < elements_available && - (buffer = io::CodedInputStream::ExpectTagFromArray( - buffer, tag)) != NULL) { - buffer = ReadPrimitiveFromArray(buffer, &value); - values->AddAlreadyReserved(value); - ++num_read; - } - const int read_bytes = num_read * per_value_size; - if (read_bytes > 0) { - input->Skip(read_bytes); - } - } - return true; -} - -// Specializations of ReadRepeatedPrimitive for the fixed size types, which use -// the optimized code path. -#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ -template <> \ -inline bool WireFormatLite::ReadRepeatedPrimitive< \ - CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ - int tag_size, \ - uint32 tag, \ - io::CodedInputStream* input, \ - RepeatedField* values) { \ - return ReadRepeatedFixedSizePrimitive< \ - CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ - tag_size, tag, input, values); \ -} - -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32); -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64); -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32); -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64); -READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT); -READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE); - -#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE - -template -bool WireFormatLite::ReadRepeatedPrimitiveNoInline( - int tag_size, - uint32 tag, - io::CodedInputStream* input, - RepeatedField* value) { - return ReadRepeatedPrimitive( - tag_size, tag, input, value); -} - -template -inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, - RepeatedField* values) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - while (input->BytesUntilLimit() > 0) { - CType value; - if (!ReadPrimitive(input, &value)) return false; - values->Add(value); - } - input->PopLimit(limit); - return true; -} - -template -bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, - RepeatedField* values) { - return ReadPackedPrimitive(input, values); -} - - -inline bool WireFormatLite::ReadGroup(int field_number, - io::CodedInputStream* input, - MessageLite* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->MergePartialFromCodedStream(input)) return false; - input->DecrementRecursionDepth(); - // Make sure the last thing read was an end tag for this group. - if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { - return false; - } - return true; -} -inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, - MessageLite* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->IncrementRecursionDepth()) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MergePartialFromCodedStream(input)) return false; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -template -inline bool WireFormatLite::ReadGroupNoVirtual(int field_number, - io::CodedInputStream* input, - MessageType* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; - input->DecrementRecursionDepth(); - // Make sure the last thing read was an end tag for this group. - if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { - return false; - } - return true; -} -template -inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input, - MessageType* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->IncrementRecursionDepth()) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -// =================================================================== - -inline void WireFormatLite::WriteTag(int field_number, WireType type, - io::CodedOutputStream* output) { - output->WriteTag(MakeTag(field_number, type)); -} - -inline void WireFormatLite::WriteInt32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteVarint32SignExtended(value); -} -inline void WireFormatLite::WriteInt64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(static_cast(value)); -} -inline void WireFormatLite::WriteUInt32NoTag(uint32 value, - io::CodedOutputStream* output) { - output->WriteVarint32(value); -} -inline void WireFormatLite::WriteUInt64NoTag(uint64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(value); -} -inline void WireFormatLite::WriteSInt32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteVarint32(ZigZagEncode32(value)); -} -inline void WireFormatLite::WriteSInt64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteVarint64(ZigZagEncode64(value)); -} -inline void WireFormatLite::WriteFixed32NoTag(uint32 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(value); -} -inline void WireFormatLite::WriteFixed64NoTag(uint64 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(value); -} -inline void WireFormatLite::WriteSFixed32NoTag(int32 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(static_cast(value)); -} -inline void WireFormatLite::WriteSFixed64NoTag(int64 value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(static_cast(value)); -} -inline void WireFormatLite::WriteFloatNoTag(float value, - io::CodedOutputStream* output) { - output->WriteLittleEndian32(EncodeFloat(value)); -} -inline void WireFormatLite::WriteDoubleNoTag(double value, - io::CodedOutputStream* output) { - output->WriteLittleEndian64(EncodeDouble(value)); -} -inline void WireFormatLite::WriteBoolNoTag(bool value, - io::CodedOutputStream* output) { - output->WriteVarint32(value ? 1 : 0); -} -inline void WireFormatLite::WriteEnumNoTag(int value, - io::CodedOutputStream* output) { - output->WriteVarint32SignExtended(value); -} - -template -inline void WireFormatLite::WriteGroupNoVirtual(int field_number, - const MessageType& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.MessageType::SerializeWithCachedSizes(output); - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -template -inline void WireFormatLite::WriteMessageNoVirtual(int field_number, - const MessageType& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.MessageType::GetCachedSize()); - value.MessageType::SerializeWithCachedSizes(output); -} - -// =================================================================== - -inline uint8* WireFormatLite::WriteTagToArray(int field_number, - WireType type, - uint8* target) { - return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), - target); -} - -inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); -} -inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray( - static_cast(value), target); -} -inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(value, target); -} -inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray(value, target); -} -inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), - target); -} -inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), - target); -} -inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); -} -inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); -} -inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray( - static_cast(value), target); -} -inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray( - static_cast(value), target); -} -inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), - target); -} -inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, - uint8* target) { - return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), - target); -} -inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); -} -inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, - uint8* target) { - return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); -} - -inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteInt32NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteInt64NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, - uint32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteUInt32NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, - uint64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteUInt64NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteSInt32NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteSInt64NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, - uint32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteFixed32NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, - uint64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteFixed64NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, - int32 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteSFixed32NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, - int64 value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteSFixed64NoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteFloatToArray(int field_number, - float value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); - return WriteFloatNoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, - double value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); - return WriteDoubleNoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteBoolToArray(int field_number, - bool value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteBoolNoTagToArray(value, target); -} -inline uint8* WireFormatLite::WriteEnumToArray(int field_number, - int value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); - return WriteEnumNoTagToArray(value, target); -} - -inline uint8* WireFormatLite::WriteStringToArray(int field_number, - const string& value, - uint8* target) { - // String is for UTF-8 text only - // WARNING: In wire_format.cc, both strings and bytes are handled by - // WriteString() to avoid code duplication. If the implementations become - // different, you will need to update that usage. - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); - return io::CodedOutputStream::WriteStringToArray(value, target); -} -inline uint8* WireFormatLite::WriteBytesToArray(int field_number, - const string& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); - return io::CodedOutputStream::WriteStringToArray(value, target); -} - - -inline uint8* WireFormatLite::WriteGroupToArray(int field_number, - const MessageLite& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.SerializeWithCachedSizesToArray(target); - return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); -} -inline uint8* WireFormatLite::WriteMessageToArray(int field_number, - const MessageLite& value, - uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray( - value.GetCachedSize(), target); - return value.SerializeWithCachedSizesToArray(target); -} - -template -inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.MessageType::SerializeWithCachedSizesToArray(target); - return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); -} -template -inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { - target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); - target = io::CodedOutputStream::WriteVarint32ToArray( - value.MessageType::GetCachedSize(), target); - return value.MessageType::SerializeWithCachedSizesToArray(target); -} - -// =================================================================== - -inline int WireFormatLite::Int32Size(int32 value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} -inline int WireFormatLite::Int64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(static_cast(value)); -} -inline int WireFormatLite::UInt32Size(uint32 value) { - return io::CodedOutputStream::VarintSize32(value); -} -inline int WireFormatLite::UInt64Size(uint64 value) { - return io::CodedOutputStream::VarintSize64(value); -} -inline int WireFormatLite::SInt32Size(int32 value) { - return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); -} -inline int WireFormatLite::SInt64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); -} -inline int WireFormatLite::EnumSize(int value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} - -inline int WireFormatLite::StringSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} -inline int WireFormatLite::BytesSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} - - -inline int WireFormatLite::GroupSize(const MessageLite& value) { - return value.ByteSize(); -} -inline int WireFormatLite::MessageSize(const MessageLite& value) { - int size = value.ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -template -inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) { - return value.MessageType::ByteSize(); -} -template -inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) { - int size = value.MessageType::ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ diff --git a/Resources/NetHook/google/protobuf/wire_format_unittest.cc b/Resources/NetHook/google/protobuf/wire_format_unittest.cc deleted file mode 100644 index 867970c4..00000000 --- a/Resources/NetHook/google/protobuf/wire_format_unittest.cc +++ /dev/null @@ -1,905 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -TEST(WireFormatTest, EnumsInSync) { - // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match - // FieldDescriptor::Type and FieldDescriptor::CppType. - - EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_TYPE), - implicit_cast(WireFormatLite::MAX_FIELD_TYPE)); - EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_CPPTYPE), - implicit_cast(WireFormatLite::MAX_CPPTYPE)); - - for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) { - EXPECT_EQ( - implicit_cast(FieldDescriptor::TypeToCppType( - static_cast(i))), - implicit_cast(WireFormatLite::FieldTypeToCppType( - static_cast(i)))); - } -} - -TEST(WireFormatTest, MaxFieldNumber) { - // Make sure the max field number constant is accurate. - EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1, - FieldDescriptor::kMaxNumber); -} - -TEST(WireFormatTest, Parse) { - unittest::TestAllTypes source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetAllFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllFieldsSet(dest); -} - -TEST(WireFormatTest, ParseExtensions) { - unittest::TestAllExtensions source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetAllExtensions(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllExtensionsSet(dest); -} - -TEST(WireFormatTest, ParsePacked) { - unittest::TestPackedTypes source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetPackedFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParsePackedFromUnpacked) { - // Serialize using the generated code. - unittest::TestUnpackedTypes source; - TestUtil::SetUnpackedFields(&source); - string data = source.SerializeAsString(); - - // Parse using WireFormat. - unittest::TestPackedTypes dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParseUnpackedFromPacked) { - // Serialize using the generated code. - unittest::TestPackedTypes source; - TestUtil::SetPackedFields(&source); - string data = source.SerializeAsString(); - - // Parse using WireFormat. - unittest::TestUnpackedTypes dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectUnpackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParsePackedExtensions) { - unittest::TestPackedExtensions source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetPackedExtensions(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedExtensionsSet(dest); -} - -TEST(WireFormatTest, ByteSize) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizeExtensions) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - EXPECT_EQ(message.ByteSize(), - WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizePacked) { - unittest::TestPackedTypes message; - TestUtil::SetPackedFields(&message); - - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizePackedExtensions) { - unittest::TestPackedExtensions message; - TestUtil::SetPackedExtensions(&message); - - EXPECT_EQ(message.ByteSize(), - WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, Serialize) { - unittest::TestAllTypes message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllFields(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); -} - -TEST(WireFormatTest, SerializeExtensions) { - unittest::TestAllExtensions message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllExtensions(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); -} - -TEST(WireFormatTest, SerializeFieldsAndExtensions) { - unittest::TestFieldOrderings message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllFieldsAndExtensions(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); - - // Should output in canonical order. - TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data); - TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data); -} - -TEST(WireFormatTest, ParseMultipleExtensionRanges) { - // Make sure we can parse a message that contains multiple extensions ranges. - unittest::TestFieldOrderings source; - string data; - - TestUtil::SetAllFieldsAndExtensions(&source); - source.SerializeToString(&data); - - { - unittest::TestFieldOrderings dest; - EXPECT_TRUE(dest.ParseFromString(data)); - EXPECT_EQ(source.DebugString(), dest.DebugString()); - } - - // Also test using reflection-based parsing. - { - unittest::TestFieldOrderings dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream coded_input(&raw_input); - EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest)); - EXPECT_EQ(source.DebugString(), dest.DebugString()); - } -} - -const int kUnknownTypeId = 1550055; - -TEST(WireFormatTest, SerializeMessageSet) { - // Set up a TestMessageSet with two known messages and an unknown one. - unittest::TestMessageSet message_set; - message_set.MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension)->set_i(123); - message_set.MutableExtension( - unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo"); - message_set.mutable_unknown_fields()->AddLengthDelimited( - kUnknownTypeId, "bar"); - - string data; - ASSERT_TRUE(message_set.SerializeToString(&data)); - - // Parse back using RawMessageSet and check the contents. - unittest::RawMessageSet raw; - ASSERT_TRUE(raw.ParseFromString(data)); - - EXPECT_EQ(0, raw.unknown_fields().field_count()); - - ASSERT_EQ(3, raw.item_size()); - EXPECT_EQ( - unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(), - raw.item(0).type_id()); - EXPECT_EQ( - unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(), - raw.item(1).type_id()); - EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id()); - - unittest::TestMessageSetExtension1 message1; - EXPECT_TRUE(message1.ParseFromString(raw.item(0).message())); - EXPECT_EQ(123, message1.i()); - - unittest::TestMessageSetExtension2 message2; - EXPECT_TRUE(message2.ParseFromString(raw.item(1).message())); - EXPECT_EQ("foo", message2.str()); - - EXPECT_EQ("bar", raw.item(2).message()); -} - -TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { - // Serialize a MessageSet to a stream and to a flat array using generated - // code, and also using WireFormat, and check that the results are equal. - // Set up a TestMessageSet with two known messages and an unknown one, as - // above. - - unittest::TestMessageSet message_set; - message_set.MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension)->set_i(123); - message_set.MutableExtension( - unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo"); - message_set.mutable_unknown_fields()->AddLengthDelimited( - kUnknownTypeId, "bar"); - - int size = message_set.ByteSize(); - EXPECT_EQ(size, message_set.GetCachedSize()); - ASSERT_EQ(size, WireFormat::ByteSize(message_set)); - - string flat_data; - string stream_data; - string dynamic_data; - flat_data.resize(size); - stream_data.resize(size); - - // Serialize to flat array - { - uint8* target = reinterpret_cast(string_as_array(&flat_data)); - uint8* end = message_set.SerializeWithCachedSizesToArray(target); - EXPECT_EQ(size, end - target); - } - - // Serialize to buffer - { - io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message_set.SerializeWithCachedSizes(&output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - - // Serialize to buffer with WireFormat. - { - io::StringOutputStream string_stream(&dynamic_data); - io::CodedOutputStream output_stream(&string_stream); - WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - - EXPECT_TRUE(flat_data == stream_data); - EXPECT_TRUE(flat_data == dynamic_data); -} - -TEST(WireFormatTest, ParseMessageSet) { - // Set up a RawMessageSet with two known messages and an unknown one. - unittest::RawMessageSet raw; - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id( - unittest::TestMessageSetExtension1::descriptor()->extension(0)->number()); - unittest::TestMessageSetExtension1 message; - message.set_i(123); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id( - unittest::TestMessageSetExtension2::descriptor()->extension(0)->number()); - unittest::TestMessageSetExtension2 message; - message.set_str("foo"); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id(kUnknownTypeId); - item->set_message("bar"); - } - - string data; - ASSERT_TRUE(raw.SerializeToString(&data)); - - // Parse as a TestMessageSet and check the contents. - unittest::TestMessageSet message_set; - ASSERT_TRUE(message_set.ParseFromString(data)); - - EXPECT_EQ(123, message_set.GetExtension( - unittest::TestMessageSetExtension1::message_set_extension).i()); - EXPECT_EQ("foo", message_set.GetExtension( - unittest::TestMessageSetExtension2::message_set_extension).str()); - - ASSERT_EQ(1, message_set.unknown_fields().field_count()); - ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, - message_set.unknown_fields().field(0).type()); - EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited()); - - // Also parse using WireFormat. - unittest::TestMessageSet dynamic_message_set; - io::CodedInputStream input(reinterpret_cast(data.data()), - data.size()); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set)); - EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString()); -} - -TEST(WireFormatTest, RecursionLimit) { - unittest::TestRecursiveMessage message; - message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1); - string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestRecursiveMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestRecursiveMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, UnknownFieldRecursionLimit) { - unittest::TestEmptyMessage message; - message.mutable_unknown_fields() - ->AddGroup(1234) - ->AddGroup(1234) - ->AddGroup(1234) - ->AddGroup(1234) - ->AddVarint(1234, 123); - string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestEmptyMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestEmptyMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, ZigZag) { -// avoid line-wrapping -#define LL(x) GOOGLE_LONGLONG(x) -#define ULL(x) GOOGLE_ULONGLONG(x) -#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x) -#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x) -#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x) -#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x) - - EXPECT_EQ(0u, ZigZagEncode32( 0)); - EXPECT_EQ(1u, ZigZagEncode32(-1)); - EXPECT_EQ(2u, ZigZagEncode32( 1)); - EXPECT_EQ(3u, ZigZagEncode32(-2)); - EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF)); - EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000)); - EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF)); - EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000)); - - EXPECT_EQ( 0, ZigZagDecode32(0u)); - EXPECT_EQ(-1, ZigZagDecode32(1u)); - EXPECT_EQ( 1, ZigZagDecode32(2u)); - EXPECT_EQ(-2, ZigZagDecode32(3u)); - EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu)); - EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu)); - EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu)); - EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu)); - - EXPECT_EQ(0u, ZigZagEncode64( 0)); - EXPECT_EQ(1u, ZigZagEncode64(-1)); - EXPECT_EQ(2u, ZigZagEncode64( 1)); - EXPECT_EQ(3u, ZigZagEncode64(-2)); - EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF))); - EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000))); - EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF))); - EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000))); - - EXPECT_EQ( 0, ZigZagDecode64(0u)); - EXPECT_EQ(-1, ZigZagDecode64(1u)); - EXPECT_EQ( 1, ZigZagDecode64(2u)); - EXPECT_EQ(-2, ZigZagDecode64(3u)); - EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF))); - EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF))); - EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE))); - EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF))); - - // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) - // were chosen semi-randomly via keyboard bashing. - EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0))); - EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1))); - EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1))); - EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927))); - EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612))); - - EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0))); - EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1))); - EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1))); - EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927))); - EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612))); - - EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64( - LL(856912304801416)))); - EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64( - LL(-75123905439571256)))); -} - -TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) { - // At one point checks would trigger when parsing repeated fixed scalar - // fields. - protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2; - for (int i = 0; i < 100; ++i) { - msg1.add_repeated_fixed32(i); - msg1.add_repeated_int32(i); - msg1.add_repeated_fixed64(i); - msg1.add_repeated_int64(i); - msg1.add_repeated_float(i); - msg1.add_repeated_uint64(i); - } - - // Make sure that we have a variety of tag sizes. - const google::protobuf::Descriptor* desc = msg1.GetDescriptor(); - const google::protobuf::FieldDescriptor* field; - field = desc->FindFieldByName("repeated_fixed32"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_int32"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_fixed64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_int64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_float"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_uint64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); - - EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString())); - EXPECT_EQ(msg1.DebugString(), msg2.DebugString()); -} - -class WireFormatInvalidInputTest : public testing::Test { - protected: - // Make a serialized TestAllTypes in which the field optional_nested_message - // contains exactly the given bytes, which may be invalid. - string MakeInvalidEmbeddedMessage(const char* bytes, int size) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName( - "optional_nested_message"); - GOOGLE_CHECK(field != NULL); - - string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output); - } - - return result; - } - - // Make a serialized TestAllTypes in which the field optionalgroup - // contains exactly the given bytes -- which may be invalid -- and - // possibly no end tag. - string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName( - "optionalgroup"); - GOOGLE_CHECK(field != NULL); - - string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - output.WriteVarint32(WireFormat::MakeTag(field)); - output.WriteString(string(bytes, size)); - if (include_end_tag) { - output.WriteVarint32(WireFormatLite::MakeTag( - field->number(), WireFormatLite::WIRETYPE_END_GROUP)); - } - } - - return result; - } -}; - -TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1))); - - // The byte is an endgroup tag, but we aren't parsing a group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidGroup) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) { - // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not - // be a known tag number. - unittest::TestEmptyMessage message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) { - // Test a bug fix: SkipMessage should fail if the message contains a string - // whose length would extend beyond the message end. - - unittest::TestAllTypes message; - message.set_optional_string("foo foo foo foo"); - string data; - message.SerializeToString(&data); - - // Chop some bytes off the end. - data.resize(data.size() - 4); - - // Try to skip it. Note that the bug was only present when parsing to an - // UnknownFieldSet. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream coded_input(&raw_input); - UnknownFieldSet unknown_fields; - EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields)); -} - -// Test differences between string and bytes. -// Value of a string type must be valid UTF-8 string. When UTF-8 -// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED): -// WriteInvalidUTF8String: see error message. -// ReadInvalidUTF8String: see error message. -// WriteValidUTF8String: fine. -// ReadValidUTF8String: fine. -// WriteAnyBytes: fine. -// ReadAnyBytes: fine. -const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0"; -// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to -// interpret \u differently from GCC. -const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214"; - -template -bool WriteMessage(const char *value, T *message, string *wire_buffer) { - message->set_data(value); - wire_buffer->clear(); - message->AppendToString(wire_buffer); - return (wire_buffer->size() > 0); -} - -template -bool ReadMessage(const string &wire_buffer, T *message) { - return message->ParseFromArray(wire_buffer.data(), wire_buffer.size()); -} - -TEST(Utf8ValidationTest, WriteInvalidUTF8String) { - string wire_buffer; - protobuf_unittest::OneString input; - vector errors; - { - ScopedMemoryLog log; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Encountered string containing invalid UTF-8 data while " - "serializing protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes.", - errors[0]); - -#else - ASSERT_EQ(0, errors.size()); -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -} - -TEST(Utf8ValidationTest, ReadInvalidUTF8String) { - string wire_buffer; - protobuf_unittest::OneString input; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneString output; - vector errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Encountered string containing invalid UTF-8 data while " - "parsing protocol buffer. Strings must contain only UTF-8; " - "use the 'bytes' type for raw bytes.", - errors[0]); - -#else - ASSERT_EQ(0, errors.size()); -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -} - -TEST(Utf8ValidationTest, WriteValidUTF8String) { - string wire_buffer; - protobuf_unittest::OneString input; - vector errors; - { - ScopedMemoryLog log; - WriteMessage(kValidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); -} - -TEST(Utf8ValidationTest, ReadValidUTF8String) { - string wire_buffer; - protobuf_unittest::OneString input; - WriteMessage(kValidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneString output; - vector errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); - EXPECT_EQ(input.data(), output.data()); -} - -// Bytes: anything can pass as bytes, use invalid UTF-8 string to test -TEST(Utf8ValidationTest, WriteArbitraryBytes) { - string wire_buffer; - protobuf_unittest::OneBytes input; - vector errors; - { - ScopedMemoryLog log; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); -} - -TEST(Utf8ValidationTest, ReadArbitraryBytes) { - string wire_buffer; - protobuf_unittest::OneBytes input; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneBytes output; - vector errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); - EXPECT_EQ(input.data(), output.data()); -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/Resources/NetHook/libprotobuf.lib b/Resources/NetHook/libprotobuf.lib deleted file mode 100644 index 6c0974648212f068b2d7478465f94161e2394ef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17150514 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ⅆs5m{oxwxKQ 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

kkpef83+DjrYi{N*4qZ-SIqayP!$ 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%0ApK~L^8O1r<>k;_al2g{fIwi$aOO{!6Z`CV3M( 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%0A=pd6!pX)Vz{pB~;TU)gKL3F( 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

+?4Z;?#g+no>%ur$H0jmjriE3<=+53%fE5H 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 #c?uVZ}C6rT!ne=4r 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

DSPKcTbryEHVnFm5+h&fi!p&=lZ4fS*XU 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

W`? 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/=I%s)nofdY= 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

mt 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

h8pp=DC*Y=PD}KZVx$cK6acDY|0P27O2!2)c<% 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�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 s9s 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�_4No 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

SFgLb+yMg3%>f`)}C+o9Z-hF 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

KVLU!$g=@mW4ER3C2U2A`GlilFgcd_OAV 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

n(t39 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 x3@6VG;4MXBQ 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

QsUg%}xlCCtDAw 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�Y;1n&mO5qxmXCg7QRacQyY0rWu>qKbuZ+em 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 z zdu|XzuEoo&daNEhO9zj1K01_6O}b~6pOI?dl>_V?eo-U#fZl=E;TUE6alar(@ttJu zIT@6n)ETlKc%8evd3kfVxuFFcVm5{rH@CEemg@o6Lw|VX^tdrk;pRhs)F`P`9{Qg} zDOXJi`8zRjc9a>Fb`6FZPf7%Lgf3`}EDu9AWMH(GLuPe!w{WPGp;qzZW9&JNcD;yl zG6jcwpn4%3Zp_b>+5y*~9dO@wB%hc_KCytc6t@elMPn{!%YG%lz1xz%2zurnPn+bH z{0;e){6w{%DyXnKqiNk0+#bzUx8<%!bCreIxJDk+h|N75pNtb5_h4kg9GYyT=7)~d z5EH2(7O=hs?iJcMHI|LktnRkdTm%{YU7GfCbGA~`X9h1*i(p^*#5D5US3WTd<)Fr! z#nYQcIjpGiDu?({>0H{>pE}xsm}m!LSoI51DzsZPmW_6}zT4WN3~&2E8tw3#UeXRJ zMw^o|biT&0dt4v%!bc@7FtMcbqyc*2qq2~Bm$xB}%s)}>m3g-VA{U9@=tw*X;~*)6D~-^TZzTufUoIM>C$ra^g_88$ znQENAS}0j)ESF;|jmDZs_g7pO#_j9MMPqGtG!`+@Si}NW8HNdjR<5yZG}foOt+9Rz zja8RMW4&;&X{=P9s-&Wk2VIrweZ8)wQe~`n3L@!S4~%9yxC$Z*ZRGNmrqM>z=uwT+ zMsD|MF52iZM;j3nZA2_!?S)nl8r=m#%iRBPbGNn8F?id3X|&PrdQux@G|tB0=R?)m znjed*uNPCEG+AFSrY!WF%XObd&wZ%YtLNgq`MGGiZH}fRCYp{|z`6t)N7FQxjoo!? zw>2HNFMKJDrhDzcYP!5T-IGd@#~e!(k-TRkuU6Ut$nQZ_Y)Lbdy-oL@R%}^lMpvXs z8qGMI@hEW?V0`dNE}HRKM>7%=%}5OUsz5^t?PiTB&4|DgEE>CPA7&fR+78#Y#mU7% zzLsT>h)I1A3s}X78WUPjW2!#5B!azpe%I=PuBp~d!K!snMcy5`g;O%; z$xL0D{#}M=7sb_3BPb?uA}Eu)h7j^KsWKhFq;`JF|?+}(-NIpT4-{Gy@fKTE+iUIk3M*^~Tf3Iryc8$rz zYtm#VTw+C7v{9}z($@KgpIg-Ive%YLg`ToyLT&k~flvOu^H=*uKGA=pJuhgVyUAYZ z>l(HR%Uwhxd%C`+*lfaBtkk@D#{l~R9~QvaQ?iaPCc6x>FZ3&JsTdqNe%({yAve_( zRMZzl26b-e*SWDDSm?E}8+HshVMFH&`_^w*bA&z7j_ld-fIZW1b3u)pf|=cSoIQO{ zS50v!I=$Eqf*}`1gO?*l4f=vha*z^=k?;$T4n;>V)Ylw^%$|<53Q83ha-QZo947r6 z2y4^SC?nYh;WxRJT=k|tXU>1%RG#Bmma%2Mfx~_OQk*v%=&+`?d(Qt7=iM9Vw4#=d z_QcCDPt3y}98(#?4B-^?JT4u*Z0;U)h(^7n%Y8FA%Ln;sZ~?# zC<%+jDTy-@saDTG;b^sLR`^{`8N0Y?jhWuQci+B!Cs%_eJDEGnDs`A=0kXWg{_2r{ zVNG9*2rKH@C4e6STnfmQR9XP50Gk2l0xkoL>fg5j^87P^%K=}~zyG3t{|)eJ&{?lM z&kuS{N%F%Qll5#!lh{pSMQV*ip~(^*hb5Wvcd$uv10?x~G?M(6{778dL3X=NrW^d}rH3 zv3*R}6yN;l^u6_6(~Hn$%CayCdox`UYL4q~D^ zght&VH1W6=+x2C$=h>s@+pE!=Z{DEnj4h|It3RPy42>uDjeM{F7P~%Z58H%&Bf2me z@JO_#xbj8V7*C@AKi_8$soWHvW!L#DpKA+X1Yqvo33bKS!}Qqk5{SI^EznN{y%Kb^ z`RIwm24SPWFq)>#58>9hYm!;`)V8E2Yw6h+zt?kq!%4BeIyL*9p7Vi|V}11!ocp}z z{9>FpZ4O)d{wUFJd8Czj;=SL+(L4@+R7&4hj|EUA4rwQuzCu@V5|PZ8@b;;l4ZJEq z%siqUs%6g~* zr1ek_NbBJ${d+MWt%XiNS_wA+(n>Jn3FJ%C@6hzG0rEND&~);iu`2f9Wnxtj6U{(O z=C%m!o5-us4r>OH?_4#*u_)1>rO^z7&O#Nb)P2p6#;2J?JMijxhqs$Zw%tbR5sUQN z;>|>D@jggiZ4sIt*VRxn)ecr|@xG%ih>5l!7O)-$M{AnKw3ld?U5MG@^X>7l2I^tSdn#=#sU^y zB|b%K*I2;13mESxvc9GvV5)rB(n_!n+UTJ6J{e8usXmdLR+UX zrRy?WC1Wq7Bj#Hy$D2$V4um;mZkWg!hAVdA_fR;PzLREN-!0ynjbA0>>eiKJq2j)< zMuzGYNmS4wy_jn9T{-%|hoNE0eqju=Tyt!dShFsMqEJ^QT^ECWEC{EQC`(gtKxCZQ zmuCw^;-3dR8T1zbDd~f7qb%P{Ok!V%AxaasYnsNgk@SKOcURKqLRbCO(?2lUfjR$N zJ|#U9Bcq#!2{gZE?@ajlfMg`Lu1CfSq-XP$xtO>X!Z2bITY}e!iK4`bN!&UZG9KAo zNjb`q6k;MN!~)js;8>x3MPu1WN@2Gpz8|HTh=cQaIJjGMl+445Kc@m8jZ#)p+ z(UTJ28=sZAjJp=QFpa(<#mTs$#L2jOt&7~+{0}%%PE4enSiqVCX%ialWT9m)<-u-C zIbznWC28g`eI?&g9+S*IwlsH^RzhDdhi+<_K3goAYbn^+|p$*koHa(N0yRD_Z3oUg)8ZC9_!KI~Aga@SAaU?gkPxZd; z*)Khlm(-R`&%7`G+j~VDrK*-*DvHcCkZVy3qk&=@02mFVC~+Fdy{1KO8t6lg1|lXJ zh*-ed2~8lh-5SeA10COO4djQuyCaPTx~JzfP)0*$hxVElN(JO&Rx5Q?wyz&Z&6Xz6D)ovzY2vLiGPx3^Bk$RWw?^`z>GGb% zOstXvUQ#*RZ3iI72Uo#mt_fWWR~Stg+akqiLPd$wgzj}Ka?ylmI+~D}XhLEEYc({I z&_1Ryr3o2C)VX$8u&vmx^*cM5kKM4Pc327gxY637H`e+QGBgA~;zNcegJKfn-k9)Y zmE3_Lq+yP@O6I(G|8j1J`xj405TD8GIXmq~UUkXB!{)*69aWaMHpVSNZIcs6TcIBL$vTZR<1#W7fT4l1-p7nG*7b zNiLAn&Uts3B-c8a=Q;0K)F}051pRbu2SpN4Bd}Y{yVYViKK3ETGo$5LzABPH12|yE+JE6tqiscKLQz*83uG z!}+5@kP)66owm~l?kct_=N3l->V*1f*I@=vw9Z#K*B@4w;ySzD*EM;kFB()=7`~c} zoS1Z(Mwm|~^3@T5yq0h#4kmNntFG1~-$OmoFMKBNCC^=o@0652I^OL@OA_*))=8h_ z`rcaOA~bb*dsACDbX8>0N1MV4oNT05^c$DC7=rTAoNVGM$5d0@F%H>TKS+^el?%>< z4WdLNI6{-;HNx_W=c(LGVm)|gzV1bME>-3GfJX!F17r*=^k)Z~rb0lf%zl6r`Tl?m z;2r?TP-~v2EcgIxG@bQKI(eiD-*beTe@jeMEU|#K9h@SxH#DYN-9w1iS0UelG`#)} zzEe_8yq?_0c_5fP`J17g^(qiqbN7QN5f69Y3eD-^ZbjM;ceB~=ZQicI*9dPD6W%5k zV05A-v{y7{c-x*^jMvY7qdum*@><3f ze*w>*>ES`%!)s2&Q8pHTR7%f-v9X)fZqg(ym#rQ?=vO2N)#%lTOtHm7vjkXw6su-r zvlKz10w#|#j@2aA3-vE;44AMgJ+Jle3xMoMyaeom-VMwVM;ivr;&RlPKR543p%_6ivTY(|u}vj|`Rl*{G@gn&QeH$+s=OQ1LPK zJu%Vu!~zzr3ZaeGnBn6?WgPD~XDW8Sf@a}3K^8Km|yr_c#G zG$JlZF^x#!^aS%>kj`~H2jBM*7x z(CCYSA7 zN;Yo1n}6%-=gn8h*k9IRedNY_NwnWxHhDXd&PRRGnw?|cjz;!YZVnH$w<@Z=v#Vxj zUDwRjTWYwt{k~{qr_eXs(|0#U>Abcs4K3sb2|hKfyb{?dwCKot5gvjH25>2Z zDqvq!7?lcL%gGlqxdvy0IOt$tnluUl&~W#1(3%d1(P;2K=PV|KwOg8&E^S!e*wWNi zK5=4sb&Il!nzYxyYMw@Bt_U}`E^n_gedH=p_El9?a~iH{X=<;E^_A*cTU!#ZtFNx9 ztM)!^%-AXr#{pDbW_`(>smStG&C44XN0u*YX$tpl#>z*la(fD8_X$rx1RffZHq1ofBS^Z8iOs=cb zSirI&R!WjCeZ-zq?(dpZY+tlsYpenc;`)Axz znO;?>4o{vGMclLE)WqlA8QQ;^hx|_3&|Utf&X_uBZoM0qeJT{0)jmML`UEk%9YoN0D{2#sU_5YjSS^RDs+} zds?oeJxwfE_3%kNBNz3+{EK?{l)^Gq4^{b854WgSr&15c!5k>Ha97G@rb9ke z!_DAUQ4Qo43Arve z%i(i)S1zi7`4`o2o5FfUHQb?Iok}%S=Rq}$M-_ZAJJp~TK+dCnhm%zoMGRV)OGKd8%b}_!9 zXfJ9EYoviAc?Y7kH5RZ2Ln+9;M{5l0ssNMgI0=DRuGYj|ct$QNgI^*l<8FoZipsc8 zy*ic32<1U#WH~M|yQytu^P;9aDGblk+!C4XxP<3XIVua!)7%-$a9pCHXH-Re#`2&j zJ{6}Z#6eXB@ii%zj>mt4dqq`{k404wlW~b}DH@dqF&UTO9WpLKOvWYT-Xf?4xtHS- zavjGd%q@@c2G9QOiufnxs3+nd=FXN@6YN)aq_HTj>KQc=m#;i%iSK!|gz{ro865$b zi<XRBQ5e(&=AqHEUK6bRb@=#snEV*9&y0??ukl4!_&PWGJ2&_%e;wJ5 z$+8^&{3njdI81_vK_w2dGP&nC494%{6czKzH1y6n`ya^ji5`CK3)AKPyRHVHWl0O8=ZinS7=HD#?WU%Q~Ba z!|giwCf508J!1E~4)VhH06(aIvu+>4Z@LaPfDmj0xI}GOIj;8I0#62Ra_FMEi_xn!qTdaGMo#8KG*N#Qb}wY(Hbklx>(*9sI86 z09nt!#EnwV#H5~y1*|e?0ikhVQE1dmHN{XzN7>VZ_Fznzt@mL{tUc8qo#KxvqjD!J zmPO`b;>(!a%4ipUzlDc?(W7j551Ev{p?AE><^uRVLn|9vBu*?=AF;rf7?xN^sZ>zP z@E0|jpLiETUt;fxVLkZ91N}a|WdZ6SS%P=dXt`G|R_Y3M;!LQmKa(6vCdW=WGNJa# zvq75OwkQSDvd+Csd#qMgLjlPPa0V)-{k39Rj+PUXU>;%tYaCRP(8g;_DJN_ly{yzI z9I)>h(!NIhT~qwv-}S!=A8pUYobWNxGwn8C^ctT%%O9=xt3ZHatEaq>loj zxVS|IX1dZz)X~)2?(?&ij8S7rNWpn{$Gskr;xqXS!n(QmqmqsXQd^)nBBk2G1IW?6 zD8g!~j7gC-SkOan2Xo*)UW=EhWY&jNAu$>e@moxt?cHabB)tHn2>^pKnl%h zS{;T*84n?o#MeGr_xP0{cyg$1n9z@Ahz z3OBKUwH}z<8`T)LvvO!(b7(!#UeWn^rboEk?bW4T;o5(DiLF7`aqu;)}?bc!!IOPV2oR4mD*IEHyxlJ}4$sp1>5XUUB8 zNa__bVjPgmgIp|?%VRQTnNT9j+=CkQD6}cn=~#y4o{nW$ABJUKby$X&unaNT*->ae zMcoRm2b#xU;^E6YjN@(|o3dw|Sj~4wmu1<1%jYXx%+^!ikT8A#UNFhkLtB){hPPmX zv4;(R3B%6SLrc(I*)*+xb{LVEFe0&l<%h-+TCv7lx+{O<3IRO)dubT4ITuDu?Bz4E zCvlWuKZ_UhCfMMqHd>A`O$<8#Z%)d#2jIOKE7c{5-2CXc1aAI9Z5%h}VkiF9VP;~& z%)}%XT4?k+3JqGd^9}!OdqMF$u58%#paq@SRkNqgemr{pp6G(TYOKIsi3tjR%uP7T zo>Gi;4~yFdR9+JN*Z>SR>?n*zio0rxZ7Wo{dEw;||JV(jk>I!Ns!~BthKxU6?jAo_ zXQUo*5e^Pj@L;07$%fvCgZ;OuINawy0Hb7p?tB*E9MnME`K35tpr6L)RC&(-l17al zt>BQ}!#Ear##EUn-n#%t38LU7Wf7WRi}?pNtHVvp+cEJ$sXg;~e3Y?c&>4l=^Mu-S z#GDsDc@owsp=g!W&7-1%P?T>9u%*`sQ7j~#AF!@oi7_@tJ%E+rUnBnWlvS*#N4v<2#nwKmMTdpAw)Q*$*%_AVyw0X-l6$2C< z{CyH2X(#Kd-mR*7H7LYnNP`#xm{7q&W2FmC?5=tCE(}A~)yLPh{dinu`_;6FZ>6kk zBT7aXSlJwfWEqf0sVSJuc~-XB-klX)fJ}KSo6qDkPQ&qFpQ!8zz9e)(Yh=0j*eIMU z6lrOy%4ZpPD}SM`{3`*6<9vgz{CAzoCnl9oEMPUFbcME5V@A%G?OSGvmyA=*n4x)b zb!-?8Cm`mMSf@2-*bXq3-jM7V;R07Ce1Q21Rvunq3zX}DtG!Q?alMMRu^_G=gFhYn{nm69N63G_EYiWX@CC3iU5u$F3TaIqzL1_#vG0 z)+FD_dnw6}9-x{u+9Ih2HD1UwP#0;ukj%HYCND(I@!O{Y@_R1QHQE16*5vJ=5R(;r zi3P0jkQN27?a0%m|qE6g>t3@tp-G`S!;B;`&GGL z0tzvaAYvjxLZbu;4b2v;T0h#Y^)H7nwP%!ez8h@w*@Zj$*_$h0XuHt$)1DXXzpe7= zm19Xe)-JTC7uSz`VfH+|p!dSdl{q`T*xsB-hS6Nyx$oaAir zHD5nt{l4(!DwyDO-0r&KWmW*;j9G?b`7u>AS8v>Dqznl>?UAufayxDt-#)a;Se*=)`4Qu z+Zw@5Dp8xeb;z5Z^WTM1F*=0zyzV)_2j~0g_I)YNebRG&_DLj&fxHXYzi@bU4D-Z1 z5I!~-e^knodDoDf*Cj`MQKGYJ{MjDw*Z2v_sCTs|30jEWXg)Kpt)DQMKbeZ51C*i1 z7KbgSN&IH&De8#(HSsf$59+DU1C9gy0^l^juL9QT-;4Bbmig_Ve-`k+0KcMte;4o$ z{Qf>5?|Vqo8F9kjn*ez|W7)n8_0O=rG&AHVTP$mkL3D~L(Yf>^-% zFtp?#MH{2BfHe_ViK1Pgv4GVHOz!=Z#sVr5UubtZG{}60ttRh`aeO0kY0_|wutb@> z9DnGwn#noZNOZni&AU=80U*^h%xGGro)C+jt3p0aV&1(K^%g3E-}4W^qXBmV(ka8= z{6_v}MV+WBiq;e{v8IRxEZR^)vrth&i&<0l44-|By>aBGjeGjduY6?X8C~c8SLM6m z%Rt%)QrEEcxZRpvKVL$RIv*|W|NBsMp^xT@&uSlIKQ?k}z1b>dtqHnv!?w~idN@!ftSU+gNqJvtBDr>I-c!eg-k0nCe8z^pQ*xbZC=SHFJi>6(kkxqBYXrrlCXKjRuMjl;=0TgB$((nOZ?TwJWK8C~ zx5s@K&RyYQExwcQXu$DMH(4unTasucxVXz$wV%Ulo!xfWm~`MUiTT@r<47D~983pl zubmN!y>7=FiHXfYOyY%w#&}_&!2$BFy~;P?obaigYtc2s&R?&Y{ufl!mfAffcv7@> z_l>o$bzbOuEwu2FV?dC=Z&n#?ibfnJ86h*jhr@Q{bv*D^3pt5P!7?^QJWHXpET=XV z1<}W+#X3*BKr6ySUhuF3-^nM8!SUfy_#;XAx%tu z{B)yuO$Oonw4!r5OI7BJ0a+Fsa16k~juF!yXdaf&yMXi&>;+^oy$?7Va35eX;2EeK zF;|HR>kyNvJ3_k!Hyz$#3Ec~_R| zA{TMbs#yP{oHyviv0O@>uz~bHj1FO?Qyu= zY7XE|9K3iVNTG|H)-WuO3Th9QXF7EvXw}Qx-A&zi*Yj9p+aPf)b0age`$@bg=5%)) z1^PTdmM?-^6oZUW3_|;fnAlIm0#*lVNN8MYLTCq_{q&nS23&{FFsZlgr!!G#FM1f< zZ9m8|1pr`G(GJN(c9@ci-Z{b6fwX?AwUEFQ#$9jDBL1{mptJs_N zBQY@oh#`I-H7T^OX-o}fXph4|(npr9MA@j(GCi1d{L9FXcZnLej(;<`AS9X)-QHj{ zAZCTC{lY&9NH6_OfR_XEx(0n+F<_m;R>Xv@h+&^0Fq6i?M63dDH=Kg@? znpg>a#ot)RLFv2m0a=!p;bNILPfP*<=-X&R!ery1)AgjlbJptPl=J?!Lm+2p1r!efV}}; zO5VTQjw&LDnc;s*`O)}IDL(?o%bxRhjzT1v_L=Y=?z!r||F1ZIq<$J%|1r<`3nBUg zln#(7B|pY_@6Nr<6Z7y#z|~Y0Dv6dzmo_;Hf;6_ghyAI~;RG348mH%k0CP1i&k zT0(6N%a=$Hj8PgaIVuTB45{QSsLN2OE^iJm=ok!rq`f&*Tigg|%Xy&5ocK~uYg}=7}-U;{|;9Y?4 z0p1PB(Les?aQD4{8vwr!xE1glfaJ4p0zRqFlP^gp50TDq3_&YOd?YdH+Y$>{S0Kki zyHaBTi>>G&yC6Ey9u%GG+fqx3uqq3~$Ib8hGEsZH(N;ctOXc~IzlZEXhqCYy)_{1d zVREGLUBhD*m*~5un&<0~cMEk8mx5*VO{>gUkZ)(XK64R$*G8Oo0Xqo~dDCON@tu4J z&E#wNN0Q?6mge?wWj&|?4Vt|scYOOv}tygFB;jc8op>vaphJtvj`9? zVC!}_ZnaD73;e>EHw7yOM~+|jRCvfubp;jm1(89W8~Sx_?1ye;Nda$#h4nC;R9Fu>=SnU7_D;hb_#C# zsfq0r13RRhB1``h$2uG)9f?9?D`G0p+d5G~+~*&HVsp1n@8Vwf`2uvNOzSid=ic$0 zUx@R?T47RnTJij&J=4XRC$>&U08S@|sFb92y1HS7i2-nTqLZ{TX;)TBa=mJm+|Nvi z0Z_83R;_Yh*8OFKlD9G}T9Xo6nIR|~Pb;$=ceq=booG_VRDwcLII^@NNB@_0He?;ASQGY`cg_i$W}51<{TOjVogct&g-QTTlSEd4$5< zqD-tpc}R-2D0yW_?|4C8A1={R(n#g?!9AYq4BEZ2Dn}-rNG^z}ld@^`mMi9`I1!Up zkC-f`EHo~rEHu^eJlyI@r|sZw^%@}HM|cF>-RkXdI3}l7FWw{PEWn&-N9Mh`Oa5jU zrzv_tO;>e(#yLD20J10YpcR3F}xLdk*CG2eJh)GLFEMWN{;zILltk3kF zz70WG?GXfbOZU}kr}nzt(xu?V92<)iPtBoiOYy{>%V!3y*~d}-?p_>CM@KgS&!#n7 ztr(oG88KwieoGjj29dy;>WXE+9-}uJlKSRc?z6HS=viWR!B$EEbI5j~=doi4^`iy+}^kC#3_uDvQWF*|TrE1zQqqk#&e>9Ix`YI51yNpg__liUNq_N9& zi^k3Qk6?bE8GG1;b6nQ#YL9&InS2II@&S~eB;8QVX=~Ce>W1dHx<@fHD^d9;4kD=K zvy$|RQmpAF9E#nK+a)+V+eQ6Tb9gthoqBc66uEabN^K48GPuX;F)4pat-=`aJo9=gCvoBdg-NASSL0Vgcp+5E`XVXs{sb=~@WZ&FZSz zD?@ECryk+w@QN6ZGcP7FpRq!cFn|8$u?xptNqE@YLr2YL@nlJddHD4GtX#KW9uCcE zZd{`jySqwE0mp{tTs%zn^y+oi4|&r)HaGPM;mwNxS#K8ulE-d9{mF7L#ANyav4Hg| zo*=Z>G}dPfmyr;fJs!pEHe61f?38&j!zHHJy0h?Q+R>~uBUL^5*5rmyPrfmeW+VTl z%kRvmdtxLvKPv{XW<|!i427FIq*=vg!BuJkP;Ii zB^I!Df|G@|TVpyd7OQS!drXA%tSys~gHyIlsAa6h-x+K11Y#}b1u>L1VcI5NSLvq6 z2POm}gArg64Ui59`i>w*AEJ|dJN!6#ggp@FFf2Era)vK_9Cy5{KtN=*uO3&Zfw|5{ zefwspLBR1`MAVP3H=z#gz*4VfaibPCj=(W-RPIPXc9|KHcRda!bKbq2C~4QJv$6AB z++={hdKb>kMQ^vnW4rR5e8)N*7jo!ErJUS5X}f_*hVSz3OOE z;S6S6?c{2VtJN`_3B#g=yp1CjRYY`Rxo!g|4glmx7}N0x9^lBu34jd2{s7U_ z$VdEsrfi*JoFnF4EQ-%GPO+bkSC7S?Bo2ja*9{VLoW8A0*ezl3HM5&^@Lz`hCmY}A z;!YOh*eMDACq;7nPvp&|rdR-3UOnx6x=-=;YP^Y0G)K2k2yA5?Iv~DV*vmsr- z^Rz;4Mf8R9oUcw$L?N{StJ;D%)Qml%8^Wz^dVMK%1`99A&m3n?B~@WLK9f2v#gvCb z|Fg1I*mbC7mq<`y*MQ`5$x=!b$q@;$C9_r7-&0IYg-uKpHnD((>9d-K39||dSlwjm zA3!RuNW;``ou3<1XQGw7OqPhJ zKt19J6fqGfVlamw1wz}Sv2L3~m?v#bN+VErczojS(JSd)^|U}8Oi>zXyP5x41(CJj z%!_%>Irhtr>BS&<1V@o_6r8P&;1CnRAr`P+0k;e7RgHC9aGt{h)}|4h)$l>;l!ulm zqYh#7^6>eGWW-6{#Hz0sQ`SOvCb-bkS`7!uBXo+CqtN}<5jtWbbi}Yn5DYY-4bxb+ zh3;(#-B;5H-KqtELOB{->JiFQLGlQtBIPKQPdP$KOoWmc z_Gg1A3hi8t>BT~dxov#Mb*EYL=3@bnuzL&4uIa^Q^$@$LW6fz6)&;rFzvEb}2GX$_ zzkK$)I|5uJYqh`fkw{y|$4|5Dc3-4_bQPwp?M1xGgiCyp0nydI9YqsPjQFDGV-c{m ze$t0VPTt^S4uoaR;JW80*pxYk5Sc@1Ag}KeAd~b%eb+TJ7KQQFGyLTu8!Y zQOwvWiux-r@JD?1&K<|A9ITKWM9;_iBGD;+d$u1@GtAFa--JtgPK+4xtuJ)Cz+lj31D3rxe z#)okJ_sn}?<(^2BU5jEF0UzRxmyDRVxpsu!K)u$F+gVY((AWs<=CDny0d|aD-jupNA)^LfR2lZx|B)2JCezFE~m+@kDviv3w+o+y1w` z(#PDdzX)q$>=-R)kH*FE@8xr1ueF@FqA+d@jp$rm7Q`-I*imOnalOh7>#JtZma4K6 zl);uN<><6qa%gmVYUZ24mCIkAkDLP&tTSg?U)0wmzvFMCU0N z)(9x<`@jY$j8n%8PUP9o0V`D4cOBXz4y_1{hFn(;Os+c@m_$Wg=3sQh()qs*he_At zEd3?Oj!JaUa^nzQ%lN1dd(OW+g4gpb;+}Av>N!9BG~O#u<6N>+Jm))czQ1+{@4|UT zCscR_@R%p&f$)nJKvYWa;8m?*j(#@jrpG2X=J>c2?M?1a^}3K*e$*0fXgC zuzcE#v186mpo~*%m^Gr5T?(5I`N2g{*s@;PG3d>3Lz+rl6{?}*s)D0e=CA$(Ggz zz-qvafENI60%WiKQNSsHzXZG(a4X9Jm%l80%fd2w4 z1biQGARq$cI!XZh0iFOj0Pr-xfq+v11AsFDivec=9tp@j=}G`E2OJF81ULlnqku;P za?z$^0j~iZ3fKWy26!Xj$$(ve<$zxVJQeT`z!8A=0-gr=-+-qBehY9U;P(MX0n+U` z29Qe@jsxU=D`x|8J)Cm@sTU>yZUd|Yd zMtO$-v7oYbB_KuS`7^0AAJ&*G>p)rn{y2oO04uWI(^$ab0uL`LTCv8kS0FInQN#_K z6c(^r9NG$phTtGHHCXlRyeXe8AJ{hDj+Az;EmNDn6+6r3jeU7bt!k;F3y00SabfXx zWXwYIw3JZxxwNk@tx^qDFnS?Pk+CmVZi)n>*DAB50xfBDwSPz1_yxt`BctPSzOr9r zNVH`iE*?J?06_%nXtX?QrM{;%*wvDoP~zRFtKGV^H5 ztngJ9!j?G(w#+<#v>!|vJd#h3Jz2fN9%HZdBb0cpe|(5fLq4zdMX`P78eipnU!(|j z8y@ibW6a~VAo)r1lf+7log<;=`?Y?4i+@MI z=rPer{?s4P=C{vh37?}S?s`%^W!|{xm{_2HXHaH`t_L1^S#@Za+2}69Pzg6DAp?GaSZ^9_KL}#*IGPYdCP989rn*j!<=DV@uQGFxK{yMVpoBpsWdH zIq+J}D_3Of7VMZ4lcds|t>kG=un91UbxU)CYotG_>7hai0lyNE{IUoTI@D?cJP&XQ z;1s}RfO7#`02cx-2W$Xr1*Cbf0&qEC8z9YrFkl2Q0{Ah&m4IsjR|9qcUJKX>cpab( z_%Xmw19kx31$YA>wa0qE2LV3`_z>WYfIkL|0{$G(2HXO8Ga$`{PXj&$cnje3fS(0? z5%6<>gYnH@02~T->GC{>|o`znAIXY|ih*Z#L(50j>nR2k=_J zdjZ!1ejV^rfd381=KY(1p9Q=R@C$(V1Ktk!9Y8kA4*GpT5Jepic3IG#h;H7DST|3%oLg#D9}k^d z-N!@osruaSgnzC#c%}jTXXLBY8VT%w@y=2U1CX96DeFKn=?aZdS29s|vMa^kJm%nF zGUur~i}bGnpwCigW9O+mVNNLOk@!2+bDp}hpR3EY4rN;D(Vff_^FXut>xXq`>mn5& z%H=-ebf@b4>_>HSO=wqtsuZe@b)!_>tk%}B(sgDbjyjw%iFH8T#`bfvCSC+tVVz$L z$fryLWY>5GAgbM}2dn~|4amBi3rN`_M~Z9_6WJmbusB2@G@80Xqd7U38`^Uv`{?M( zx58!fX(K%!E}gB+x#OcJc5dR5?Um0*-nu+`4R$wQut|miyq3Xuyq(FkC**EMYm=J^ zPshPz&U3<*;bk@nALLIYbKbq1G=-60&t%U3-zl+QyMSV4f2^|}KmC$<;=4I%=vFof zDv4!~=Rh}zbRHkm3UG>m|L zDKtK%&lMp|`-2zUHv>kAS{FCe(6$6BTFeqf<`A@^s;M2cII3`%MBdqegHlNTVft@$ zxcdX%2S|S8z{N)Ze*(yBIDo;o{?(B}Vj_ja#7`@q}C|mE|u@BZYrEAH}0m z_oOf*Kd2fL%z91r6vK9zMB4XguCkK>S4gvwfj=ad0Y#3NfyAkoxk$m^9Vs9tQb0_0 z3J}_rkOHCgB`Lse+}1zRNWo95v=HdoONnjK{zGo4d(CpM0+Y;_Oh0=!sop*uie0gy ztu@?wRb+8RMf&nHEmYb06&0DbQP-mC^@zKX&*Nq$ZKD)9UOw~LM(uW_lbA>+F$uyG z8iVkJ)|aI79DLRDX{7UnNe4(edm+p^smNy4lHVu7z|3jvEQAPcDIq+;bB6 zt|NiOL;{InX##Ml&=}Vzw7w*PKg3tf_e49n`)c=?Zg39mqcQ?jV|F;$J=|DPp^Bof z7D{#+z!m9kG(a@D22kXl(*XZ=GypNt0K@{;CFo`f?Fx;_;v{`#v4aU z7O*}B-5@j$Kntxe^$7k2E%D_vTB7a3p4Ae4JCHx8UVl2}+P8}>J1ydx{9v@mnQ-$a z@jfYX&uNh(9W6pkv>o*rPIIxE-l=}hLl z+XK7{bjAR^;u*K&JNb?gIKF(?!+YqhZY44nn!C8Ur6nQ2LSkD`waHw(B|5-Dt@uH<6k@Y8_gv(EsMM~5gmyIo_l2qS4&gb|!dtjPL}#Y6r%ZY2aTrEPiA1=QK731RaeDL_O4v!NP9w!#CCWEtuHbrCE^Z4ps z83W!^T_SV4=OHvFzpV`d*Vi#sj~QM*dEnB+_TrckQtViC%D5CKc+w;e*Xs z##~NVBV%f*uKmc^6V-7oTz>4hlN=c%CNf4WU_A;h6&fu%p>fouCX4>k4ZS8~8E{?h%EbCwk!sHDeifxmk^jtJTByBjfYHmM$wcKQcbtk#S-oNH#cQ>F#1t5mSvYC)yVS2 zV6FYx#M9I@dA5m1I@Ug?bP&HMrEXjliIwa>cv_zT`w+YIx1&}!O`=8(o&DdUWIYW(} zP|LpUM^6j~Yv)~0oaN{VVxlLA1*{t(X+pbMV@gld+ckUP0mT|#b(kAlKg+DF!Ueq^ zIU1ejfmrJx<^wG^-Dtov96lWM4>8dP%HKTb!~83bTRnSfm4U|d^nbp25&ozo zZ{dk3EGLx#;}SP0Zf7sD`4*NnA{~%ra48_muR_%us0x!c{z!wJ2M-moB8&S(2~Eaj zbe+Y#*iPjQ<-}!9+TR1PG4mc?a}tj0oLSweoCb%d z7$2llj6-v;Ze6M6E0YsK|qOhU0KI ziy62Dobs>%hg-n84j6x*0Z2Lduy&wNbOfB32sklpjEBpGHb-N|fXhI@3qG7mJMT}x zr$aNn=J86n1-v6i0Z%j<63rAZS7dU}{yIGA)lMdF=ytA5{~|l_>e(!1Bpogvypay& zgI9|QsK6376N;qTKO-HEquv#1(p>?W><9=k5fEasm5$JE1J4RA;})>6+X6BU()d`K z7I6K31!Vty@565MOy(YY1u`}^nTPVD(8@mst$0PZuT)`Xt)wd&!03V2ssuY&k>d1# zqOiM@Yb!a`Q3Aw72@u2fLy$(Ht=3o;tz=QRl|TS5yE}~%xamMCfy2K0hUPZ4UeA6P zf=E$RM$9ETt%n3X#k+IVU@4xezbK<7-W7ykL|X+R#5eJZ6erqFq=Gc@Z@~`eZVNxd z5pH54+{6ObG)S4yXbcN2;}$;HZQ=ekUe?e*ei<#d3H+Hn2zRWlIvh0c9}_f?y>jWR zY?7JX;fkIx%1K2}#49I7ic?Nbh(+$oX||)Bh>3C{7O;vjBqp?=#K7WW-#enGmSLtnT#dPQXbZ(NM8^vj_!43`cx@oWEHtW zJ&fW}p&s#yN0H(bj}s4)yW+XTQ9Q&%@em7G+o1u3_J+o?P&~(XTk+5Z@WnKW=Sz82 zJQt7D7-#iW*I3!S2&JQfN3{o zGz!p(*~wJ_Ugao2Vxje)Dh7ydoMQexN zSnJ1P^ge3{e#-U>xL++wFd5J!1be8&b4>1l9MX(S*qnDSOV5~(vk+ji%M-A}XY%^f zaGZQG{-`7|AD-YG5qd2BFQGd*diRs+l^ma`g>D8mc0(7bv8g@W*19GkdcYJx!5e<83J-_=N8I56lX+IBp&FWH2FM#+sDd9$ z$h(=$c`t9w#rp?&!UgzD-iuHvYpV0{I+$xpL;F%;gwT|$8&zAGf}`P zK3u|b-R21#o6%3=N@fDGyz2n@xE6%i*EqaFOn8M@!1^X?NND$KEIqHh z*<-xI&6j4T;gyQ9_-K{V^GZzYQ~O<#utv7}r+W12v&Ws)aMn3v8Y(L4S}{=3)HXZJ zz`r{9E2#sMwqto11WcRLtXc0w6st#3-7(6msB+=Gl@9L_6W${x8(|5J8(|4eIsa0$ zasTKs-n$L&pPq*Ip6yxQOEIjQIhP(#{!5YDtU2$;`{%q|`0hG~?}!QC5yR5|sBNKf zD>k8}b%6>bdumpj;bbMt`rrUG$S2JIF(nYm@1Xz>iqF_np}35x6?f`C4Z;+ z{;YZY%|sr5AEZ3?Y1TVDPE2^5SirgxoGr9QjVT^qwr?pps_}0At;1@L3K{#$x~`ht zjrWphzq@RX>MUb(%V^Ecv2RBsdn-4G2ijW|)!x}vv$L*i=ISjqd$9@pzG!5p&^O!D zcQ-~==lIglLd=Q6AWR{i_i1FO5IeuB4b*{g$G@uvuq#{ztU+Oy0IP(po_zMyH8>l@ zVMZG!!QA=~=2G$L9E>T45Oq0Q+gqVf)6%64%dz8ZTlvI^<<%`MT$inBdQ*FQ!;+?| zdF+DBToG=@3IJ7R+HjR<#;U5SISp5}G__a78iBgj)|SNU>Z@z&s^cCtW^5HG;{d8I zvp(m}PGtEi^nn*gmM>~)3ino)%15iRdIIIO)-!O$^8FBwg*bjO3x8B9NY_}fP%0{< ztSTxzMSO1Jovt#MIVh}8lh`?z6vVW$fK@U0H89pOAaVOX3*$q&q2RiWevqdR2M0&4 zzIu&{qE(GVl{`TG<@Y=Qo&ak(d-OepK>&W^(}1;r&j4Nl_$(m5`#C`7<0f$H5f(0#;8x%XU%pj=m_v4CYmjFjYD z`iMQJ+}|~+*uH4zSP`;^@doR4{^2*sFeaP6mmmVA7RIBjTk(cM>ttY!N`feg_+gzq z;B&{}wJ8(NQI44ZLM2t7RT#`Uk7~G^&xlhD)BVxuJI8K_*6gj^8XmfAU$i>7rMk2P zm(|@^VAtra=3Q!lO2Dtg^vmicN8!>J@%BQsCGOoR-Bg$3Ix-0Bnu#NDry$!#;C(2> z_uUc}C-6$Ow?!6(tE#K#O)Pg0gjP+SJF%RDTY8MGYH}5Nzg1PZ%o(8tZA_JrtK8%q zAEn*{t#JvIM0YcFCckLRnN%?S3kD39!hya^P%!@qMW7YhN5IjKdlVY^=M)^AHT&`` zT}*n@Ag7-5GW5>)A*ZnO^Tgqa3eq%u7|+rQ@(q`QTn%ld6{Hz*SMzT<0`-9{E&uPE zHM7q?`#f@zoFI6!f7w~{*Xlvu5_pvv7=AhtC1B9-jwfPM?4#i-Dw0i-9EO zU=wMjKBZ|h4CW~M9=s!0tumOS&c+lSxp#uWWFdRGj-Lb)qk+Vp+*P}4wUO+8EF3eF z`x4CLkto@p@q_|(3NSH~Ed6JZQ;uE+x_@Sp?;~dNa~gx0l+VBmutPFF1J7Hnuqt+V zevK{V7=8?XGM>B@6`b6iLE{BmCKe7LZtQ6felJ1o1;>``J*OkRZUOJ&Vd8pqZ7ppr zk(S2RmK&R!8e%hQ``Cj#SK@E|yDOkpear-&wH_jf3A((X{P%xsz65Ltd~B{sdd`_$ z*I85G!O7?61<0j)7H%`2pYO$Qzx1t zm<(7F!y@Y7n$YesSTcY6UgVM3sP>~>eUxqC*YV^Wy#=cpSlaDi1tGW*5 z{*RQcDwfX1idni@?RWd7+raXf^%HFadu91Rn#1BU=2gt*@F9P>6Pm+Ay6kAjq#H8< z^}i#~l96Y$V^ugG4C=kdk*qX4qWykvsULfOoAJs%wP7h6txdMkvVQ*&un!IOYtgRR zi3d|rFZN(vu@$2cnP7-;F?B130FE9OVXNAs}S=9?Q6ht z)joq^14eL&cjRKj0l^$~C!WYVa@D5{=BQo3sBWlqTIZ8Lqs}J;4k6o>L=8QG{f$in`f*QmKc;OSn z$AVF7eGvN)l>|z0v(tVf03)eJdEsf)TzMw=P$CzqG3PM7&NSVS6=<BG3O3p<*d8!*>H zTC;|QzNs*=A?n1?QY=#EO_u57aE;C#LBCFUa$kMdOopv9F1C4xB%$_R2VNRxc5T3v zGP7Kbev5w8TYn0mjYG^J#AF8Z!Zr;@C)CC&@{6vhzGz~QFiFSxu0)$0=*B*OA=`WO zT8~!Kj=}m*`sjef+UCE^&fTta=P-`- z<}hxrEM_Ead*uZDS5H)qRoxp4@;h?fqixqR6yN%y@m;p`(PMG3#0RH%7&Z2FoPKSt z!EYXZ=bzWvlU;lsHa$40Z6s>;;Xup7Jb8aL&i4kjncc6LHpjY$iJFjcyOeAQHuIa) z%t2F#s@P`gA-IR=DZ&nUI|tptmaC?T{YeU5!k{GUAs9Y61sz7#&8dK_AGBE7;d}~m zBa%i;B#jtWr$h}4t<_*=P%`Y+gz6W$d)%tLp7kNDJLf*D+Y+=JKUi2-H+uZ@-G3j} znXB6ZX%@<(Xjn$Nb3+Z$VS2*ji73HOifQQ)OjpasvK_!=0`)VnJ4f@7^3sIU9&-(X z3-m$je-tpjlY_HFQ{(032%Rbx9-6BUdp~#W8g8VEt;0Fch!*69qSJE>zkMinBg6kn~-OyOuSv6G$ly5P}}tvD?Gby zb?l8RpiqleHFq@Q770+snR>JY`p7E~Q;#2eaZ)bqK^y{2b=0FZr2h}BI)gZ`19FVy z4Zu>sHvumO+y^)t@GU@E{hw%Eyvty+0wigU;&{z-z~GS@%u!qg?0HSAHJGD542*Z= zs*fAYQD5_D^s*#BaRXNu?8LJaJiyIcBj+J(h*is?aQwp2n$YGaBcl;gtWWCrVb*#*9c6UziWY|cK+xjvWj@}p!&0_ss3z8kHP6rUqF}H zs6W*kaWi#sK)snK^B|mChkyDo&fgW#?^tu8otG?3LQbv0S;*W>kx%rxvXXb7e5xr^ z1G+b5n%2Fe%RJq)F_eGJfbLZ{ua{l$$U{x3>1bZ3l`$WboxH~SUG$T9SieiFBAYyW zke^gVI$BgO9`AyRk=KQQP-1lk;0b_5fM|WxI6$iAd4T1BypCo0Ih0A7M`F@E5_8n| zAyL23w1*AmsHcFvsAEvEKQ)7;r>d~m!lAlq@F+P=?oS>2?2UM~n9KAm5 z&d-b1=II_;{}dA|n;OMj0!$QhB`{IUR$!?W^LnJRqImKMDkdx0pB_}q(@_Ci0*c8z z$t=RlGEmG|W70 z7B-lpMg#k;rk!XoN38}X_qG`fb1^&`ToawD{bz(@ct-xfE; z7aRj@YE$HzQZX}XV^e0@C&f$ExUPY02PP&h1u0(fG$l^)=JFb=cnn7HNUeC}U4ImB z3htxgv6Z!o_cGK-6pxrF9x;S3AU%K7G=ASg%u(M3_9sna+e^$*4pd9-J=$On+jK)a z+oS!Tb9nRd>gxjPN5{xIyww?~-@qE1RPn*oia9vXOR2Jh^|(GMbE;PKf8ej(~LjMbkza z%+V1mxtEc8xp%F>a#h5m{hw3iI=uQ1)2Q<=^R!ous5EB=)SAx&IN_Hus=p({0>$2F>Iq3Y zW`rwvJrBCPjNgTD?!oyToL2|N9C#0}IT`1XXX2kel8koOwO!ZNenXpX6&Ex|FiE|s z>5AsIm627mn_FAfV72PRuhMOH@R&9Ym(Ep@Ck8fn8NpTfM&_F44oo+Y;3X%jtmF1V zD(U!ueNUDf`RU`QN@A7&3CMSO0g&$hTc|ggU`9+Pm=Ti+DMI6f6rq6;_3obT4?GCU zu-i83pg`BS)nk4Ao#VEb$()U{d|afSfTjF$>o;f%%6r)Cr!#{l_VRF2K zU&B4%N=iDLBMohhYnrtkus0LhB7nW4x}| zBPH7P93TfUo(DW0@TY*h<^@2$%g+GGqXU}B>kTHFN}8kgdo+c{TWEeJ55H}rW>JPr z&eu%Nr-BBUoO4i_d^cWean_l?x})pJGCLf2pfaoz-TIJwbTsr~+;^ZdMApwYwprgsno{lQvA|M@(@3umaF=m|gU{n32T;cGS0ilNKD}cuVeiabYJk-|#`7Yl8B!`bj4T}XQCLAUv zO|{Ty%Y|lCxOzhVZ5zkpZnY@GhI%aL{5{gMe%Kx1vfH2RddsaIJAQl3d~MJhwB07V z|8*`an@)9Xg!ib4{t0|de5g6DHZT>t7X;G%>^>H0vjgdz!eO2DJ;3h48MNknCdGk6 zTs!+G4v`IOo0I!*VPqvoxit&Yj6p4!fDH2lwDH0`s6p2zmT8YyAVHdsvgFUVSpe;%H7@HqV`ym7E|?&tK0XW;^UBx&*E z>HdlKBYlIPpv%cP{0VT59KH*X9R4KWae$u!B!@o(NDki(NDfax4GV{f35SVE zi!U^`_(HR~JSJ-#o{VQ5JPs$b*nSRI_r_raJN?^g_npm?@Pzbi&P0#@7u+M4cLS2k zdjO9E+zUu9zXnJyzYa()PeLsVmx&3NiQ!)GR%p~{p;<0xPmibJSqG2H$>J}5F0V_+ zsnU$wodOmkFV;L$KVvW(wp~w$x*`P8Gz(+8Q^h%<$&b!EI@L3HXyk?6}2o} zCMH}aCR`R8xhyox<*`}Q9{~M}jX+RwO&iGgQDGn`dYr7&1?4~6+X^H-L5}}Cip(QGQGKYLS*iEt6 z0Z6fU5|9r0Q-E~Hp9Z8u{tO_+Vzw3w_R)xmLrx5{RUiyPJKJC}H*IX_wvEg+<31Wz zfe462K@zbjI;6znKD^(uK@f}fu1HqpB4{m=iNzkUn_{sSkYe#SKr-+(K#Ij1fE0^2 z0Vx)jdSXFL#DbWJh0rJ#LW8xy>_K$879ecbQ?;+Q=L0k)(XQ8`75mJm%{!5+a$k%t z-Cz1ywj`r&pM?L5+*|V80}zgB3-U&7#y3F9ofGQmEGXUG+3cQB`tuta+gd$;{- zc(g08bX(WO;~&|!Z}`RkI&fgdsQ0~v9LGOZw(YIqrQ6n>;XeQT|NIE6z04TDw{%Zu zX!4V<4nN|l(jA?{-5s^=Pvr4)_(8#P7ZVxt+`JD*!>=wx_Q-aodxAgXd;A%XW5z$! z8NXEe%M=+e-H&o3?~r?ZG{1XJD75LO6IItN_ww+j4M4`a!#1r4%2_RYk4;D=@2zcO)bk|#4&kKCGzHRsbvC~v zXDTHGp|(K!xO2c|lUpg$CkE2Hk#6T_Gfc+#Z(~5;SSFT%F#kLt`bg4;@&!!eR$QyZ zf^y}ptrZN6baEv-ZHoDt_K4vOmgUENf;nm8qy)+ZiUXn!3S*q{<1o0*I(z;!Odz!Z zn4`^z_wX~6g2LmT++(;5;5RQ+s)fs~Ogm-+-ie3(c!zpiqbc%_@66TNM&jpeL&q1D zT93N`&j)QC;1z)QzH$?nGvn_zzzu*AK+^ew)mon)G*~W{0TG&`-i52?X&pb!V2B`vY6IqxRhcnVrJ*JaP6>;=1xT7 zFi%4_t|)66PJ8ejg3BxZ7z)YvdKz#k;4^@ofX@Q*U4H_|veiLyWx)r^uq^mM%;63n zYO$uhWH3=g-jRz>Mde;c?FJ_Ia#d=%mvfoqI?iPxHqhl2mmrUUEU(Bnk#!)JY7FKB zIuAEu^VY5rdOSzwV?-;$uoU|1z7Nn_-HDS6pXp2J$;dzto0PNTl-XKNUO$EZa9Cw# z3wNaXO)GmY6LHvd|3D90s0VNcI||H`dElYyw1Eif%ngxdX`PUhci5tUV5Z{umie>` z0!5J8i8alX6-}=H;}gwb%fd1TTbBQV;Bns7e*+#3xD)VLz&`?VJnK(@d_624w~6n{ zbPDPCx!GEZxPNXMKovKWr` z#BIpel+qU?v)o(rK@DNe0M&Kg>M~7d8&nZCjw-x3yM!+%fZ4XD5_3%o7D>kb#zwni zA+7(dT7pNTQe>4e{8SR8oX(2E#E1gD5Q(%qH-h#sq^>}H#7q4OuyUA^0<{g;b;uyL z9GMouU<@pwcp|^4osj571$+p;v=UqI?=O`|Lk!$;b98t=e$26NPAU~+HNV2;}1UH7zi z9UU+&^!-|Vw;fL%NbA7zOY5*!V+qb>TJzEO@MOIC$lJ7jwCc)Rg^E;mDTz6G?&45) z^;jDh%Wy<8->ue@3$10!PnLDQWNl+B8D>qp#F0*ub%T66FQ%>lCB-&yWBO?7#<x#LA(j4~AH zWu7HMM3s^|uzHBOV;ry>^>vp3lhk@(@6+aV4X_P5l_v9boPKjkWk_dEpXKxXMlR8u z2BX3$ZE5gAzafn?*~txQ@b>;ZrwA3HP3XOVH31XKx}XWY9`JMNOlYtq{j{GSNwlAL z$JtMmh5TNN(;h4%O(>%dO@{aoOe4$vFd$9n{{!p-+zNOb;3I(B0UrZ=4)AfnUjuFj zJRNyG33xu>Q-FN;rvWJwU8pQEwUl`=wZt5C4^r1_8k-_wjw;5Tydzg#U@!+?yJ5{a zO}o)xSnywW+}K#c8sG?rj&YwPc2esN2k>opH6 zlB{`HW7j-Htj#QY7{BJ>eB*CapDK1mfDZ*C{_K&T4(_peIBkw?15BU;vxQ>XD zd(Sc$cK!q=*L}udNtS?oEn&%UDpay1AU}Wy4P*&OzJ}PF4{D5E|2lU4-A5KBtl$=# z@yT%`SaXtWvkwcd78Q{vnB_#vQKzDF#kqBcdVL$izJc?{OH8#e;!N}O=v}}=!eR=SG z&xTMjf>31WHHZ-K_k2JwSS>ISgOB0INCZulA|_)?#ITn!#8+sHT?MU%#7N0owBESV-bsB2n=TtI44o~ir$ zblp>vh>0c<6HO8tHA!fhYtkom|JQP(3HjS&ur=uicuMpKlF+D0LIXEz(XF9v&N>u?9#ZEHb!Fe>djISc}LO?Ma;Y$l9}XOl6+DcLL6F z$KszpvgCnuc3p!lE_8FoGTI}C+wV?t@MNDO!53hsykXw8*XqFvYLq6-YVT?@?OUQv z)W6=u)7r*5BoMdViP zbL;j`-iigr!yj^wEGvBqUm595`bHtshKZ?S@*EtoOamJCeK(o(IXrYuV6_b1lY^5k z=E~UMkzN3%!N1!*Kh=(OG`2*{(%S=c0h6qnt#`fG4<2CNDK?=Tc&^3R{DzxIQBe5N z11mf6u#VJKs7@n!$NGA5c1uaRwfoTV+kG*3T8{pm*H@eB%abg54sI<4jY7tQZY+7W z5b!v_dO-4Tv2n5fT?-%^24d1M5OdV;AOS*q*O^@FF=7)H?OsEB+>7Z#l{aYj)C7pmu$asDOh%doK=S1m0=d?Pk#CozmUS9X@eRe|-I z5-&xLT$H|#IhRd}-_6dJtEgz!Op9l)jAoy_No7UF<#y9NJy!!e-IXoAN?qZv$6!=v zs4m;D>AE(y^{B2m@Gp5?dQm3~Wn;Pd_-1iAWBH@*;+h^`TL`10U-f%uyd1Veh@uU=9aa z%yl~qmL$@cxQ8nnp$AT4qca*?7QOrKiVZUX+ zyA)HFH3JZhoX;6Yi)3iE`?35*3wo;dd)HQk&1~F|{-U(?OqQI!>U8)GvRH^Tv$k=) z9clKM4}?!)8V~yXM+5RVV;3`V`qSTq+(YK-T%?r+(pMq<2z`h2BQ6P~KaTX_ria1C zn_G0P3Am#y6U%S~&TkAE$Mz0u<|c5XoYX5d_i7vw|Lc^GKw_F5>+UJ;y9g3Fwfj^25B9`qC2l4G$CK#zuwI@5B>j0nHb>k^oZ}zdL7WoxGr+lkzW}6Uy$DFj zd_V#=0fg;c7?&T zbYdxM^!mBOP_(#oZ)DsecSET37mFkp8DLNRX>3 zbI0M`z7vQ5u}pk6$7Vi13IFsVGPkaI1qLL18>J*JI2r4l#aY4BYiMSig{*%Wvx&B7 zgth`=Ht|{%-FQ2rVgGo+eX}66l`S3E38S%NC7N0pi`8WAZ>y=EYgER3&A~d^ij(qs z0ZtxY2uXzZD}cx0_xAv&0R9k=b@wAcKJ{5GceH@S!~zm?)B~t}p*?6YM{yi8hjU3| zMvvwe`&MbYv%ONQ=dwrHmdAI&XY(?1oNW;U$DJZ>9rM7W)VM%;ej)W%KS6iV|Ah3Q zTrf|%h74LnJ-JXi_HzixMZ?0Drc4$n^T~x~wYF6?cqe=CJ-6ay^I_|BG+Hyh`|*Gr zpFJ7ySipAyvi&#(5OYJ+ser7XLO}BVKQ-^y8%&~#q+xkbuz^@Ey6}Q&`%>$chg?L0 zdn)#e05BMnkNdwek-i~0L>p3s(;j@ja84++A^gpgI-ZOCUkvEDy@xjB{;Bw7U%n-PEzjWOm)&;#B^0&y`eyNEPUk1oJ zy4*yGU)20u3<@y`(h+ks7ll^C`qnh`7qEjlx&t-c+w!oDd0wrAiqRwBGOo<{NLcvf zY^6By(E1KYwz7zptqev7*~)u(&B-|DO~5~WB%1C4233>V@&V>)7B@!g5$R}8)MNWD zF}5C!_cLs@P6@xP3G7|2NqX;c>z3Fil{vD$w&L`&{&kpb{(b|H_4uYS@;n)iV)Hm?nN_ivcoz zu!Jeac*5cTT1HbcZ0>5nV!!np)aLFFT1VDHqKHXzM+`awNfa6vz8Bh|p(F2y&R&^D zN1nGnI{LhkrjioBtCNW^WzwVtbs&>_5JDY*h-dPIewV6m68be%uunqwLV53m>b5tv&P-ygmgm!57K6juzivlCv z{{F#xXAfLIV(fn>ZDu(@{d%WXO5gNzImGLr>E|1sei9S?BnICPS|GID20K*RuMU)F zMjHLRx#I2C&s0O0sT+ZTiGHf*WueU*oPxbQ711|6tcMsKG(G%>r-#Hu4~aP(@KZv= z5TC{l6+Qe0%5zg1JzP|oO+C!0Z{EL|1(`_WAU-~;S~`g3JS3{AZ#p~?B6!erm}8)_ zcn>krVPXzHkkBKfxvIcmhl&nkr7ZR7G&)>AXK-~mezkVn1?**pP?Gg#?44;kkFl04 zQAe^~j6v4vte3Zcx}Ei6NVWA%$BQAN2TjLEcsfo@betHb%RsY*c7ee}$MK!P+>kfR zu`(1b3%U5O_^&MN&0IJNdiKY-(d<|+Qzlt^iU=e)bKx9+BJkkM1+Lgq5(xQl0xPZ2 zxj1j()C@Van#4^%_KkMy#HCy0PWS64PIlw|9SM!BTYjdM~n`JAAki*S#*x6uB zsKGcXOc+vPeRD+JKZD{um=Qr9ybtggz%79MMmGw`nM!v6o(|{&l27jk7nD9Ss{3z9aCbcaiY)N^%hDG+^R`#8yjWZ?@6{1UY>QUp zl|IrrB8nA*AL*&iGm|-%hR2_RDP+-#UEBUKyeIE2enGZc^;G87%wJR+_iav9*sa^; z=5#+crWO}ebNWDdeyzy{i(*%XkThSCdh$x$rMr3x-1#-$VlZwFKJOX71B)Evx+C6- zn^A;s5PL!&?aBLLv@#s64q?(-!pd}c3Xiw56+)}kYH#I4_s2Td(w~g#-ptp&MwO%*8}@mn5mxzwh~jV z3iL{HZF)NQA3)o$u^fo0U|g_TCU0@Fh+s>Ay(gdde!{zMD=^9B*TDWA(-jKT$*3sF zSIVT&zJv`pTd$CK)D;D!j>h;{rhWHs9`dv(l;mhIs%0aO>eBZ=l z9*|41?DAnMh|t%o#D>hmeAM3t+%DQ37(R?Jz>0Y@jS^?0C1c~zOrsK?xtvZsp~I(% zgXI+3{z*xR*90VdZid#%9Cl5tUz;_t;+MmpIB6o98{5F-7hO?3anfXUk-y1V(HL2= zs%VDytfA%x^B`N=Rvt19r)RN-nj8O&$ivK6IQ*NNqDe!B!_3A#%w%uKa10p^EJX8m zbp7b3VtI$44>C!w-RYYlZ9gRVN;SH{i&iyv$kqt#ICtS}kky8`1`J)Fo8jCxV0%tP z!*Y+=1<$7fPHsbW^9|@IV+SMo=4?A@3)ieoB=Eb*g~orfd->>48n->L2Yu(Q_)&;6 z&(J3!G)BL=1aK z7XflJpv8dP-e(CQm&aZXI03K`a0(z6$=-AkAVYVT11pf;G*KNfek_%(D4|y?LNoCA-n-{Z{R4QR#W40V! zKlTXQrOr;wwwG0_;-YW8Tr0s=|NpqVGm3Zh@`$($d%4zM5QE!LbN0Q`Udl4Ca>w0$ z2vuVrI+lY~KROu6@r+K4#Vkz|i+sxaqN{(g$izt%N!C2j1HRta#`H|?>22D6d}Kcu zAl-4RIBk2F=7aD4QT`yzVA(YhMM&i9W85FQF_}r|5}%ED%OiKr>Vw6MI%zhZhYSk z+t|(TGm70D1@AsCc5^SBf?(`s-i$!(#v=^HZV-#QFiZwPAyRrLR4$ZgA@_f4)TEKdb-9)|E&3Z3(ljFs11nWI^BiAu@Be^hk z^Mn_>kyOTRe(c3=Bo*eS&#{|dz`p&=-{r}0zMWmZSHxqJNQ~L;dyQ_WFWI1fR^Ugwt86bIsy?Z_z@pPW=4h);Tiq4;D! zLBq+#vdd;Nz74G(bZ>au9|KzN1cgTVRGF$26NO5U{m#Vvkc~_T42*OtcUWfU6WL7=?e&q0bwW?ZgpzgS#;_z@oqN*T3y+sf-P0*L=R-CpA? zZ%2tG0%^YKhyM^<`QQIN?moDVatv||GG5^`SiFc|wc5)BCf!!DwK;LpotdgO_)*8V z;iU#Q&iGxwxz9$N@$HcRG*k2rNqyDj^(@Sgsn=1Vw@q+7MjS4t9+AW$wSBuhN>5sb z)OJX1Q_jLPGb`bkdA2_Fcc{MA>TRsBHltYKUxTs2XBig^e24nsnSofLM;M9~_A^#^ zIU)cOD`YG{Vui#UH5T1&rsk?bgE{Iin1v|U?J=06Mk4Zeg}yG=V2(NwSe2%|%V3Tg z53E|#-fb{P{Q>(B&eOC%8O%|iJPLc~XxiNdbJSUg21;4R8_ZE<9&NTq%Q#k8j|Uve zu|igq#0ptG5-Yq)V~iCp(pUu8l^SELaIwaQVueGo!a<4^uG9k7d#v!QUaasvUaTbnitoK-dd#+#qV~g1+MqDV(R#rAL4!ocDb1*#JY?Sw4RYcr#GK^gwPVeV2 z8c61`&coyl{jt$cW3`H_11rJ%W23jumdGf+{MQo}W!+Q%L`54;^3(9Or~K6OGxd!c z8`|}VyJo(lD`jwFv!C}juLF+F9wz##`^*1lEbdU#n(VuJYh{xU3m#5_{Ely05sMx& zQ+mevJJ~TDGE+llN@i?uX_IXBIpbRTY-a4YylK{e^zB4xWAD+7V(;bHxh`%UfjV>^ zg0c6>R|I139$_f<-p|;310re?duMD-V(-Kpm51m$Q*%|m!5p;|JJHB>jRten4ZxP` z>uxfbqoTkXHLb^Bm}?8{8cqA0!5lRcJ;)WBR%tLty^^m~lcxQ}V0Z@h)R3~=WH3j4 z$fJGCqh%a>UyTPG%CUD=l*HayJra9w(->p#*J&&QY>mbkdvDd)Q0#pu_C83l_nWkU z^&WeF$cw$d&x^f}_G0gX^&Wed>lk~NTo`+Q*^9kPDr4`jc(Hd$?N99eoM_mpqqOY50Fo~ykX&U3{#2nQQY@Mcc8q86{(F43e({c>vsE;E$zFyNl zX)s5ffk?QNP3^?A1AKuTw z_vW+v9&dNW#XY}YJ%D#seRzTdq`z_hcTA1=#|pTP*{x~D3Ti5|IaZL#zE=}k+9H>j zg-DXFKoS?~u`8COSyed}p&!J@XLTfD5X+g#z``ItUaDzu#~D8EcR8{=&hU=00a+TG zcxTmz*Gdez8yPRHFeFGEj`1WXd(#ZwF{)+8T87MWlI`Mx;xeR7>9lFcEDxDw7~9O_ zIYVao+A{Ix(L`z6604E4<4qIM?F)=Iy_L~;(^^C`!>J3N|ZB#+z6@GTwBj#yH;eQH@1_eOzN(fPGA3L*q?D<4uD!-gKW9u-?a;{>vM0 z`mi_NbgDPrBv|j`O>!N_nYZ9c{_(4ZQA&L-&G^;4Iq<3Uk&QK_5=Tbj>)4J)^)iOVn*uF^y|bU=SXnQ|AdhEd zy}bP!*UEY^4#xP_AN?*)w#T>PYb4QMiA|~Dl>s46ygbRYmgFBR47oS0X1?~@SU+B? zGvwYd$k+!7_i8SQ!1r(Z%{y8VW7Rd}-XssqPEtc=KI8T!CQd`W*hu>|U8#fq@nZl( zW`4-bceJeKhV5%R+T$gsUyfct5o14x%zSb)pXz(BVsu*r<8Ko&V$l2k#iOSL#^26F zPQmfF_Tc!NM;ID^>*x5}rx8_`@i)fTW&DkpqprZH8&h*tjlmrCdyJgPb$>LNqy7Qx zGy1v%2E!i2*kR;uO*_V5jye_CXEp5%gE=aPQ4mdY42FGA3Y5A>)Akt5Q8$gYWx3U0 zj{2BKyUU|xJpT3tJm63se`7_-_#3N7#^1i8F^<1|QDYHcU)Iq(u63W?$rzGb5iYF^E$a$R-n#VB?yY%CA3YY-m*35iM>}9Kn-`knYy-hhecbmh z3W?I!5*{yPWz&C+bV-%XBrm{V$xA99pW($0=E-}<;Vit+(uXBRrYc+7n&x#>ceS=o zPfT3Z*tx1{#_rF%(hYh9F>tA<%=Bsbh|pL*T>B%;t)`6@47f8hmF8mC+|sj;M_rX8OOG?RN&t zNFLoXW7l38G~?uY}!27 zDB3jGK5f%#0cq3b1D*z02S}T?5Rf*FziHFH@5vA`ks)GOG!>i@8m*hqGO%fGnXzg6 z22F-Oj`EbIv1ylOMTTN#EwK%a%>uB4H+tA7i3Fus1t!(bFrp~wR zNyeosyhO&PGHrbCg%~6;cVC12`WxRj{N^qrd)HrC{gEfD#6(t!VPOSGgwXaIEJJ%| zWc6=@CabrhJZGhm)tW5JYM+|mYzgPVZHA9ZE|Aycgw}lSVEVW?3#1tyKIdM{jmC$$*S^OJd&Hv!!WD*;jjd*_5RA^q-Iv zzddb0gvK=dXrD9b&-B-x?(pQ6n8+pESWd_D*q-q3G3m2g~~{C?lP>B13&-xZ1?`e-x1K@faYT zwP!qr5fg?Hb5uTZ5L$u3jG+l{``w6ochBanT_ct)eI%r64EMsCdkAs(xfj-#a7wjs zZvwE?+?$G29`>!tJ(iNcDFNr=coL?ue_t9aYGUo z#_Mx$u26u5`6k{FLFrbsceTYr4rQR&gYQ6&l7oB?9^1h|a(D;eF@R43BIKrj^BVr< zd;b(aB*Z{WI84k@MaWTTXB*6NxF@vfh^y=6GtA@hCMLWl=BNqau+WMPW_i8scR7csHgCn7-4x)oUz<-I3{J;vcvcu3 zP0UeLVWBamFSHoD`((BGU|}}BhSV+dMM&l0XEvG4-?=z@WA@Xy=6wNX zGf(D$7^r$;Fqj?hTv_LSP#Dd3NylimPGoEWAQ{bfwv7Ih$7o{0Xkucug+`VOO&G1M z_Vpn+VUAms7aaySD{MS5x?y$U`QnB}E5h16!(dbFIw-1P`XpefnLZ1tJi-FBGfg*) zOedtY^04W_5vOO6wl2VQ=E-|8Vxr#6jOjDGT3VZ$J7Ruxs#ZEP+g-Rt9O)@gPUA@P z%Tc~W1ZQWrkCzMfqWp~idzKlWxeMMG=8qXv=I{2HPfVCk z%u!^y(54#9`f9c{zdqC-wZ|uTM(t^RQmg%Jr1G$8&4%6DdTX!!=|Q#s4HDlQPr(K$-bXGw`}63B*Jah&ieZ z{1@76gIP)Fu|2f@i2{Qt((L0oX+)s{sXY9mz)l)l0742951Sqog`XoW*db@0ytf?Z zf-H+dl9*n)=Dsg7aB@%vf-M2xE1d|O$aJuttuIA@?{8azzk4D;OhkZ~qi6zzHr-%a z1Xdqdh1*rrz5HKOtHI>QYkDePYr2mlHuhD!CvQbit#n6Z%<2Qt^8D@P1@x_JwhVJC z@+E5HR=w5~rCzEl8D(QQ=?JvyIqEoIzXX?aR3)%`&-cgMia@c)l|bm*P>y-fR-6Ix zU`~vueQP+FJS_RDt=J4|R(o4#!#Zq38vKOsn#RtS6%Cl%fx-B)+4zcqQ%f2m9gQuK z&a&A_=EcvBO%JrwcKesdq_Xnz`pNhzOlNat`C|N>5x-+>|1#G3l@*uOFu(p~QOvSU zD#msb>Pmm5cD3Dr`8n5iwXJAvjug!ps@T2?POM^!inZKsgtDCw7|fuopMmo-oOe#g zKYhrTfSx4FFlwVjeA_$Zr=Qz;LX&)8=96hnP54}o7hp08h6VJ{@c^^QN+yNl#Gq2? z?ZMVSj(qsmjw(537na0e*V1k;@L^O}LwPGS-E*yvDFCUaskt+v7j9vG+YrZWSkSQo zF{)uDjV_Sm~r9ug0y~UAq&{Qr(Y*AN8g??whTbK_OEfOhYF6EpoIS9;tIe zR{^sP^SU>V&F{!_E5l;!(J`F7b$jJlHUiPgFf1``Uj9$k%8>c-O6yRao zcba!zXU{WrYAik2{=beAel?&*%#-(@gY!-DOdm##(1nYzK}f1bvUgxxds9}lD(Od_ z15`2UYDq~$b$e5@(b>bR%)LyawCemi*cMRdpHss{ozo0U1=aTys4HawOMh&lJRp#% z)i)1fEQ1!r#2+H&XagX$C6HR7>7H@ETL(p~2(MP%+wyANs{GpdR_w(;cdYZg`M3~h=z!oc0 zldfp=S$R#toI7phgEpRZx)mqu)$-?D%%bP-^8i`b=L0h9W3-SgHdwA&VlbIJ%T$>> zODsdDIUKFRUmCwTFPYzr&>P#UlkgnB=X@z>sXgaqNM)nvH?4lpnI6awRC3RG1>ELH zN7sr-Sr$E0?Vr|`S1cZYg9_()rgomM0vCN{4>+iYLHXeaist_rFc{4s@6Nzkg|nMZ zhCW2|1DZSF2BoCLt1WGvDKqwLi2<#Fg(udt_$c2FDn zon)8g#jL zxxpOWf0XMU08Orgksq+f^)5VdARZUrM?9`mG^U%Ny!u6}RgIa>;@%RjS!6%;*xsN6 z^bC7E3L9CVTcgjP=WmUgkYU9Mzi?)H9*SF>wwJY4Cuv3b(g_%)n^RmsQV#(OwCnaGFU9C zS!P4reVBPdZIEClZFcIoHf<9RYc<)KIoAB9RXv-DIBYt#%0IhkJJQ}0@Bx`8^O%Zr zYfNj>d3(v{hNT+QTF~6Fu4RR9)we{~%$65LFs_+zj#%;uMhU}Me2-x8(m%s!G}1X< zNz1YWknd~9FVEJTUJnW}an^}Bit~zu#`z~glVPl$ke-;($EgVii_>V^)TT6?-ZmJV z4w%90@Huh7av+>O&*L;P;WRPfw9v?Dp;=BJ$~q12MctN$(@zZsr>mMHtJ<4l{l6@+ zdN1Ck45vK?!s$sKr-=!ti3z8LMotS&IK9ZdC9iaQWZr`Mp0&l3f7N}74nFO&z3|X> zepsxc%l2y^iyCoc3655bGn;!qZ>kwS7xq&el%) z3M@}>mdkR`_-y*p*Dk<6eHg!r;jWJM4GkTffg~aBX|X z8U%EG;U2aM_E-*teFxV41Ve0qS*5SA9B?#XBOvSL8bB8BB1qUs^`OCW)k6kz^hdBv zg&zT_Bc^?ZddOUO^?}uDk@32T_skhv(^EZmCvH~mys6RZsqUib4bl4P?h|@8GT%u0 z<%J$*rKt%Nd)T*O8V^bnrG&qE7USe$)9EkdnqMP8XF!XGO{W*`_`L9cM_OyZ_VAf} z27=M*e6U82B;({6i$Y0B``YG?Ml8#5aRwe?5uOWrg=G(=W4+Bq=f)O5|My9_4Y z9ch`zS$1!)*w44y{AA=v#?XabapRFDu2O+~{c#mm%YRJr_nnHEkvXWt&+DOSu zR0GTb_uD&b0r)C>zhJE7NhPt8rvUlhKL(`slxyu_`%KxESP3yl{TZ~`n)a%}9Q6<+ zmUrZ;tp;<{`LL{V?<9j^?R#Ky9l8M;+pg*gA2F;gX$m{skgwq~#3}Ov3O+yZ7{LPbd^LW^Fe+Q6kqfzEz(`nGH zp*0y5pkA`bI+S?9# z4J2`mATj3P;KnG=n%rY$s>qizEx z_ii?rqdw!&?(t~i%)2!qI9GcxkEmxo6tu=hGSe&QNKZe*>O_?K=en6joYUwh=ZmG* zPgr4nSawi9ZP?R63T9x%rBgqTFxr@l6ojtg(y5=reGb>7FrOs>{p2(G48m6z>f7-z zsebxbw~-;cB;mjmewnOslQ6*}77ENl=4ROMQXOw>=ve0qIc6pIUfjocwL!-)K)6t= zO<|d*Hg+`m^m4SUi&iyvG<%KhPMBid*iw^d)OmQC#E!0&6($g;9#L=DsPgz9=neIX z;Yf&ydIOM?4c`R37;qopY{0hwsb6)_7SS(aqF=-u^>au~y{5fnFf`M^7HQh626NPS zXpr3dZi6{$wnv-m(R$Ude;qh5Dn$br)UV$hQu=i?-f?pp{rXFK{fa3=>LmxvP89TB+2kssqj0*3~7@JkeERqN~Ilbs8jasivK2 zFh|irUZ!am8q87afXTf#8Vsw`c(jjsv`lpM)C_g?WJ0=sVxYk7h$aXF@dF3rVN2U(X^Kr=*_h>0!{bJR9SNRy^LZZJpv z6j-ySu~j7IsNn7!}m)b?E;V1t1hMK_yya&R}U#&+K;;EOruMC((BT|nu5Tv zk)2DH#?>60=cUoV!Fpg;G;@DqE5~(y0-E_au1cwygW->^hHi;o5)-{7=BQE7sOvQC zID_E>aA2*PR%9?oH35@*R~gJvH+!^A9xa=Cx%ZIL%W}NqgK6~g^-T3LF)A7V#i3QY zcg9XVn82K@4;jze8VvcGC)~RVN26NPxfyupJH<-g^eGF}fM}vOHe=XL%D_nmsUQ5M&Ft#V! zwcD)>x#61Ho{C+F_n7gSoxIYm4tWE$zHi3#(oF1i-;A>5D1PxFAB~j(y9NFB0>w$N z@!uB|fnty4Knm;+z-P`^h~~<4T1Hft;VsVff9d2KteG)!MiJ(smDw$Bu*XVlNIh{( zCbk59pv6qQ6ghI*Ss!yQn-u>Qn=MyS(X5#k&t4g2%m&Z&25-t1Uxk$+Qct=asxNF? z9baEX3@uU4z6&{97ufi1Ip`c&sKNPXUZ@X=405sSboMYNh;dCrlCVWU7`@AN?uYT@ zM~3+~4pkHPPbn!$!DP(RFzuY*28OMuDLbkAW%D&1haH}RB$}X%8C78Pay{&?Y#2aG zECY(f96eq0CQWNaFNK(+wnEx@N3L!!h+(M_%vg|niw%as!>Zk{urS^iZMze`XbU0v z0eo6hphg3eFWUH}&8^5ZM{(Xx|GsErL1oO4YvSZ^>GN9566juEkl!)fRrNjJ{u1); zsmiPEsoOu_eKuN=Ck++8cgCXnk&!)f^EN-(brRP-VR&D;qgm8wI9e0Jm(G}3;2y)Y zOGDB8=v+f$%OvaXGeSISHXqC}7{Pe|>o`I7j%Hw_Tb^;mg1>p@<75T+)4ANBP{i)s zjbB#<2Fh)o4M@v9kJs}^G6f`NWa6ika;<(DZ_phiKHnZO+a>{|HzCV~Go(U`q=$E6A!hR0cr51!1q*4g@QamUK6aZGr(Kye<=}&(jh6nv~i@%HXWdT88 zp3Gwf&Zp6_k|T*A#K+m}s*@ChYRoTd_6vg*ROXc^3_r$Gd=X#1%wm*aZDU6>Rwm?3 z2$qNP!TlRj2?)y_6p#sEIEP~}Z$S$NhDbJXs0M+eO*McB6K$#oM6h-f-{(xQ`gZ*|=4Ng_18K!ja0AFbHe^X=PlRZqn}v(-+tZvRdYyxn#T=g|I_<%=Uwgw)hK z3-C?&x;%N1b95;9CWNQs^rur-EuZ%Q<7C!`B%I^DeCwa|Pgk`^IdemG*P3gZJNmAs zEb;TFd6wNScNPH|8}TwrtCwXU*&`WO5u?~dJ-rf;vpcQ=Bv<*H@5kTd>L)#}5)-Zx z6GJXE8gik5tMvAyrPs}TT^QWm-*f#0VJ*J!el}XSZzpo*3JiK9r9{@AgVfXu@v}wu zvyQAi5;U@QG)_8i{`4Sgwa&se=#U3o9 z9M+KwwB5Ye*LI%>yGu4uYg=v34Y5`{sK9)WpaL%iD`|oo069;2Ip8JcH{X}P`Hatc ztR^O`CMMqw2#wzk2rV_M7yn;j^(=6>bx>Hn!sgsZRK~hH8Eke(8y|`CEDt5A&eM?J4AfRXgwm`CC^Yl5w)*-0DYUmJ*}&}e&eO7C zuMt1i_IfoS?e%qlwAcJid(GeE?3X;w5);l6bF{lHv_f!JXy9z^0`$lhxtDA{5E<$I zWGAvyH5AntvA*40s2<4g-Q39zV}5CxDVc|N5G%jymi#aANA$ZuL>2jV$g~-jW+RhoVVk&$4VfiTYE_xPt(ZXbWWBS+@^0uCEF>5Y}S~& z|9%JUy`54>JHIfHel5~%FObdu{WzBdM2cl%85(gOeFpyNBT2t5*umGI_p~*(UfM~w z?TYrsrsk#u=Z(xW$0k|m^i7n>^y>Hl48EOCd?h_30gd@}@ zzVjGBhWbwgk#l&RaM4C|gk=Dz3*%Sj*2MrX*ix%%1i zkL4oQ{2iyif;;@Z8;~5{16T(58sJR8y?}g=Hvq}Sf7e`GZ!l4O(qtV6V!7H87aCjd z@~~SomAW2t*T~bJjtM-b!p8=iubl(f|T8o#jcbBek=3N&(V3{LB>rQ+o0 za7|DbnJ4pLE&g{uIGL%JmWH7T9VtIYS-v1g-vX!Thy4SPCVRi(-~qr&{Qf5(^B5Kq zj(*SMC^6wEF-S0EMQ9AN2`w#07r*m4nyE9EO^$}ZDRMLikQ^NeNS$;5$hd?pm#SqjkGn(G^`RAL&;1uj5DxP$Hi_yY8aJug7?z<%2Wz;jEiwAd$3$o?2&+EHIGqXFU8;(KsqMJ0afD@m-L!MQUI0-DKNQ?!fNMKb;EfS{yQY20Xq(~G3QY84BBJqSL62wF#h)EDl zXte%9OKbBpY{k1ge{67D@%!+0%L82PcPsAW>f6zhp9yY}yJrE??w<`vV=x|&cK;ke z+WqqY$<-fwTqP!4C5G+Qz)PWp4Q3TRg>RN&OMbX>_3dcQi@_~&brK-CIvJ2$y%3OG zy#SD0#U|pKtIv5{B_>=YCR`O7xhk|lY0Za8YyReoCvQDtn;zE+>5fs~+HV@9bnW+* zf%IVeootkYd9wXpf%A{2;h#P-=xWK(Cr7ceX0d~vWR@-1NiGFb$^44}X|OK=WZ7pK zX8+7%HZfr~F)_?SqhS`>pfLN0LxS0#M5WXR?6{xV|I-&{GsKovR?DPM_LuFEjMerEFEz}rHq3s>V>U5iHZftg(8z3|4GObEhXk{exnh21|Fy5o#zG8T*;8!oo%hD< zTEpxGhS>`Zv#&JF{;kJsV!~`d1z=wt~_0y4nEgb+rT1>xux9;eYiQ zPD~h148jdI3yobUp^@QUI2*gIP2~&(%sybi%$r!^=_|gO&~r;&WuJmLI6dQiphLHg1Fx0xsJU5@jI>9`#~$QhTGVVV-x!n8vt4UjfUHQ^SDh+xJ^vBEi`glXxZm> zG6(zMbNg=8NN{ekpW6@hmD_!GvU_1Q%9jbZZ!_F}kKuN=;r158?R_4%i3zuf3Acqt zZVN5@+)n0UAAD{nv*dnmKinT~_s#L@mED)h%W(Q`!|CA{+8MmW zgww>tNfR1dZ=q$M)4>t0#37Bo^PLWDx)%J3KzgtRPp0L}lP!1~&i~g}zWV~;84hdo z!g;aj{*f-0FF4Y5kKz5jhWGyl*o5ou1Ed^(5wI2T^MHIW{-z%{(vt~dA``?!`-MjB z7n;a~TRSywW`f_3!yE-nB=xy+@pDXK(Qo#iQqN4d9H~LJvbc22M&s;lX2KV7O>ja# z^JE?sI0wSkzK(13#$T%TT%7h`ImzA}!0Cqg6|jr$_*Vg^0e%gz9PpcfvjD#i$oKj- zAm1_1V=FOXD>1B=i=2g)XE5`XM>suO7r)cl+Sh@NY_RnKu#0T{E+E|WG;`31vnyNQoc zUE@~EYR}l=4)YO?+g_$OI^ABD&(tTduph=IqqFkd%k#KCbiLO1$-kP`FlOV;ZdW+E zbhlew;8u<)-Ej+c%gc8|Td>+_!K;_K)niMybvfm=J=OX8o&%L*Vo!=z?6ON3Z^aVE zvezG<#LVjRqoF$vR2JY0ZszCC8+%06ZnF}4#qNSxr43_lzQesivMt>msYE&4Tl2fC zF9>ySELL6TtuE6~#2aCzByvGDDZHEiIVSIDWwBdbyhvZ}`!>H}nVB?6#T<)T&(V{l zp-Qgcru_GK@18?XzGC+%fmD{*gudV{p_#EwDn zB$so5orp&k=*^2y#)Fb?xV9MA72tlFNFHO*6FwJTFtN0IaB|l0GH)SHEI{r1@_$zQ z+6@ca%i=?YiJ$S;&eVHZ#a~v_(H?0pn>3kgD>wP`53H@6rDqgPIw((>sOyY;s}A(< zSnR)JII}^U0X5>H7z z;`u2LlvgVlUo%I06RZR=1ce%V8;ov#Ka6f+%oz5?=oa{m?id)|d>UQ(Qrt7Td4pwi zCwO%oGrH6IY;6Rl&M!*u@yPvk$7g)Ep zcoUxMv&B06)|)Z@7K|&6@wWkKjK2d&WBdRhjq&#YX^bBPq%r;hAdT^vkU}xW)B`cb z#2j5aXKUIQa2+v69gREB(X?X?=BRssF_&C*zrkeTUCECN?@E67w%lCDWe0i3pcvzK zBjaosW4@*sW4^i=<6?~^F~$YSJm6^6PIn@fYr^L;ShJ~OXK67$o;mR9QSl$&RONMV zz{fY0{P^a`o^O2#b=_093(F+D9IfK|PU0}G3%M09yGPMlxa_K`(kJ*Gd>*Fz?sb2O z>AuD8;*jw)H^0$!np?43f1?w*BwDe1^MO&fZ=icC-}}6>2DtCb9W;aZa(;0r(JRI0 zxA41<$D02B%b!SgAsxbLUPXx|y%aS04u}#dOLp7@OomQw^RS12$+tmId)PlbESZHI z4XG-`6=9q_ehRmAyw5G|K>7oI+vT&6v2{19+anci*dAv^OWVrX&1*Z$Vqfyi>}qLk zYVJt1W##1+Gs^2^-H!O}Mc}MrSJfFs{;fpIW@AYyu4`(xVl102>p~cqN zcH{Pv4LG}pbjiJ)SbqV2GzY9I`Gp>c8U|RwKB+#ESk(j$$Ox9ycaUG&>n${y5hQxO z&q36WM+(>EnSuwKuXOBgA)IlbKdvHSH?AFVGE8rKd#heW<98r@8O!9fwy(G@<`!@9 zJ&^B3x0r!FT3a4J4XaIj*PjCx1O7K4BH!vIz$(Ds0)Eoa?+5%net!e-4}jk`^v3~z zhu_Zu{t@s+z&`=*0_63qNB*V-p8~BD3r_tL3r@_DVH-_*1J_N}G&;w;BUim>Fh{)` z_E_$nY%uK23{0-O%U})`TKL^7$SAhZ(61AmWh(0#2tEWC8k&wr4rHMr7G4$_x>#d6 zX2>tk@iils5ZLF%k&fSVV}a@#4V&iTd$qd#dMP12RWhs=U>mA^-3LbAP;#K?Vf`W% z``yLiSI={+_PbZ+zj`LFcdrV+`Ysprxq0rD;a88x`Ta7ibH{#3G6b>16E59##WvmcEx8wO^_+I=gcYnl zV=YqIEb!#P(RZo|uSNV>$22uPUjQEshouL z;D?AT6R#lbzxhj8T|geHpS+3RkmkXfc}Hwp2ZilXCQXJ#^A;ThVWNNI2VODp!r&EC zgM?`T!ldFLVPda_mTOq-gI)dK30O31g~7@cn>!pnu4u-wF5{==T7=4tPIc2c@;Z)X@%NE{xqw^^gZWPeH>{gm#a1y%u(+JMxD%6cNol3Y%ZkCY%ZkCN&Me%GXK~8rP~==J$)xC z0Ml}IBSzX&u^XQZ--X|r=-#q>^>l0sC_gR_tsWb#+ATkDb$+yK7vjNKDQ$=@V%(zXNRV zEapd(`6#|6D^S~k<2g~_D8Tz$Y z^)!C=5aX{|aB08pFKED}J=6+ocEOVLIi#%Zu`x%@yee_`yU$c)9+ko#HMj1Tc z)wclPD$wo0^3s5^(OY7OPryL&9kv6qceVqt9`GqZ8o(a|eh=_zK=#U>0elSbS->9y zJ`c$E|0y61+dOEA_@2}k@jZz->W@gBuW57{i8)y0Tke1XG?=4u;a$qTqYNh7Vln4j zy~r}L_((w}v063{5}`%=uj-LUj$Q<+f9qVb{NjEt(pZ8Cylofl_=B^ajWy96}P)s0Ws`W=VR~PpB#u*ydMi&P8)M;)#?eFdp%VzY_Hfk z3b#d+qf_{Pd(Yu*l^x?bs|88a& zeRw(l-_2a35AW1;W*vQauEv>v^x>)c8a^cYaK6U*r0Bz2^)-B4^x?G{=QE=Z7vjHp zqhhz}c6{$#gQ{T-nSnS-Oi@E_xO8sl=F3-KtP9;!_2Bl3r=`|+Y+3rCzSRY<=7xIe z9-JS`7eXqHSNAPXb8BQInlc3ACsn&AKO@;-3A#Lp4?2=scqp0@AXx@$H@eHsgecc~`NzMnn>$n4y zT!$4tjhZBDhS(i^8Fx|Dc`%>zePNbQA^je|b@zo?bOgnlw=$nQCui6WEk>IYiv#Fz zbVDE`G)(bpbdykC7r1H)s0gWi!C%5a`*X;Y5&`hTqnr~DlXB8w+k^A>ID<>JQm)Z) zRignL``DBxkr>^UQ%~%XZxNM$n~c6PwsbuDnH-7DgWWnFR|H~GHu}GKoQ?k5_5Pke z4HQ}2l_ciA52U#6lMePQ_nwPp2=B(`|47gl8v24f=^rfw)tU2m2RR{?q&Ov z#;tyP2CXUIPcS;*f}IUaoQX*ub`h|4lrcw7rxLfqvp~6WIvv5UYTU&eLZAHb&F1Alt+uqp{X<64? z*n(~5S2lNap06N$dLTLoIWUbXOnHD^x_d(Y$XE!um!rETC_Ftq*47aFll`60Va*=4}poeBx_V3M=Cp?VVpc}MWgB; zyEq-S{(gUx^hJw(n$_J$&{(nrPo2)V4msz8`D8a(v=+Y!cJlv94tW zMoB=U!MVt@`O=wVFwFlzz7vf( z>S0B|ZbdP2^tuLORT-4%EWDv5vZ}CsZKP#Q%Z=EQy1k?D;=(H~U0BgDzpi@WrBxNy zST;3Z+tSutXlgi#@ym2J4r@pvK$|p{#K0}N7sX9x;1GfD%A5SF=+gUF7g)0ut+*#i z$L@G{{#^FYuuksM{Re*P(!kZ4S&Ho3x%*5=E53^tms9CKx-MGvEIKdxQLB&WsruTM zrC-$+k39kv#UMk~{W{U)j3EAtN#IFh?_{F28%6f#8gp`27(F+Y65IPB_ZJv@PSJtK@vj}lPrP-j4mk4H5U7+ zpSHHu`uJ>XTdRHWwbt^m1go`LAD>p+&-Sw|6l&4>K+E6!f4@0%@7}$;8b+JVRDS2_7rd0tG@!157o{w_X zjle{F-Vf|ijCRu14}g7Nk9#%(>(uXV1@@4pJrC?bjr|4K0~$L8`AsZ(&%|98Lk4~f zZ+S#7Pf)zoE$m#Px3so)4w_(duwDCiY-z1)$FgyWh+v0=CF97@rKd$?4svEUv5RhH zRCToyQAy!g3}mXyajp?|?C}Z%nE!Mq$s>OcT(WQ~&q10ns{UH{AB*~I_jC_z1MD8M z0l&15-9t=e7Zt@Xf8ArSrP;yNW5gK|ta0@iG}$(*)F+u9<1eQ{=DOQTfO4?83C~IQ zaT&y>klL^mJ^pAaDh$_v&g-}3QU%R5*Dx4pu=5&f5C#_k6!rY0Nu z)7h#6?4uxeI!XYa2fQBe*MRgRLHgeeon`%7T(etR4K9{$iSj|ZC1O7H8{7?R8rNQk z$+v4R5U3f=2Kq=Ch^^2Fd0wCa|%kXJeOs#OqJu%hB~x7hc?oo z6*#oX4sEJKv&S2j|NhV${jygvhoQRrKZYpP1|2%i9_+eNHUI3MUqhw5bRuF zw;{jjdKFfB$4OKDlP=0zSc6WowkU65eO+U1-pS|YRm`3?ttc;kvxzqhK&d4RD0!`U zu=r&dz{-)n@pg@&Z^Xhf*5b_yO;?$2@ReKAjefr6avsCL+&!huBh!Grho9Y=fGV_d z9e9s{E4LiI@|rD=Z!_5UU&noW<(4g+zwdasopCabQ}BE6X#CMZP6u-v>P(=Kj+}Vx zGS|`6m?K*G08WG|D(YhdT1ePQBD6DxiQ6^e6Zion*$4xU{Mm2a2U1{0{gsRCg;PE9 z*CNlv#XOTo&`2G#(kJ@M%IOBcJkU1+vaNmv)hFj~5R<(h#BjbLYF%htY!Vu(d7f_8 zN8r`yip&Sa4lHm6J3p*QCWhCnB#w`Qo{Hi-e1>pKsw=9wrLMK6y}9+=m?Fp5OxTAa zr*`fxaHiQ?;7^(Y-vY>d|I!rrH*|r|1%+6qUYQ{#+a-lY@hmhHcxWfjP-+<3Ri?F; zZFo~*91Ek6Q^RFxVTHpW!zF3@FBTQj9_hEHbcj`*wr1k-))v})Z0_{$fx5Q~S{`5R zramT$B8XL8{$0G*u|9JwFj?c|q|gu0gwo+_M5*h+%;~T=Mkkf63FGyQuIuDKs$Mfp1g(fSGPW)d0n5xxuk9Z#C)&L{M7F|M!CI-LXK8ndBD>U)5%3Q zV=g-^M7bHgLN`ipkH#|IfFH{_A3p}F4!ox7Kow(?>CwJ})+8zfF=>;;aLh4kPiR{W zhIRaY@YItA>-AHumy6$TKLHaAACK5=eKtJAx@=$?tk6T7GC~_NieC=yfQ4dd+U1+= zcD0I$FdVy8u{~meV-gC8Vn~K z9`k50e1zX-_jC}p%LR>fHF5+M(&q%p5-)B2$J;bw)Jx`b1Agwdu@PH|K~kFlnSWH8 zmRFDHwy_=*Vq*A4%%^7=g~rW%LW?uQmhvO8{~KTT9)bOBB)P9gVBdmVY;w=jxTcPH zq;p_aYh4{ro({}vt82Hn14J)k+kJV7oZMc*ldbg$*L!&^&Ypt3y>V7aenF`@lsf8Y z>aFfPc;=cuMfq@62sikM_tZpi2Di=jd7o(I$00iS&2Z)C8##x4spb=ZkY1 zbTW^}3@np-sX&iCSAIGYs{0}?q}oAbEU)4nn{1&r-2IZcDRFB{^YJE4!QIm5xB;@` zf+ych#(kcAL&5eVEqx{cBiGAR6EPnwc(D^s)6xv)Q@eoijZF2f!F*~yJ|pke8Voxl zfXQ=r8VtQ!az`+yeU5^LBQTlIVK?(QKG~O@5zK~|ru|%F5TaGK@^%6?HdJ9y*jb%5 zqe>Jx>p0t9DL1Y{#}Ok^sg6XU=jv&b#M<2?JjdSI4jk!mqJ}ii5YWWHeV@l=x<`5$ zDCd_vy(r^k9OvUVY9#*XAiU|;tok_jB2zscb+3nq4npQ! zP5m9@bFRrP0n1?ne&m;F_%RH|o=uj`aezkw9uLT+v(EvZ0eAu+dF4bvnkSqD$a2gB zBtL9I0})M)m}qLmWSUiIoMsi8-G~nC2;edBSjT|q!$PQ?f~-dX!E=E~h#3I{rq#E# z2NpCp;cq<_S~vw{M7zGTq^40W`&jY&t1;!p^bk6WpZ;vc87Y1GGZnWLeEPG+x=Lb1 zSqVOLiL;nd19^4>e&pMH{1_6AD7zdvMNH%rF*x*q92MFSgZb3KA*a5NS(oLWSxdK^ zdj34gGye8UP9>uodRt&J@1S=3AZC*JLa$TRODVBm)8x%e(gJzErYcDueHd*pRXqBP z!=uE6M~V6L!m7}6!R$giIC%8`ke)|+&?W9E*&C1cs718Y)VJytLwh_ZaAa)N&#!4} zZd$guIoOuR-REsB*sgV2QIYI&kKgI1DsncJ9vS{n$znq3aj0al2T^pWWHCv(b}jfe zRdVflN3IbQxke19<3i&Q+EjxbEV{>cAlH`mAlJG}KOwmmy?xXcgMAff31a=EBw2#b z$7R3drF4Q=B~$xbb|v`u{>)O`xMg&dB58F1GL@u!dKLVaD*5!XBcF(gd?M!Ksk2IG zIR-muCp<2l>3*f1u@a8O@qw7hHSLEc@1^6MgT1%j84}i_88gkj9C=cYx(^qGTPIVu<_I zPe%40Tm_M&ysd^jNtL{P!;!bdMBWnfsn;RZg!YEP4i4evm@t;iJT{fjY`m_g*Mk<2aB99M0(T_iRV44r|e%jAAMGcJq@xKSy6 z!yrKKm#TF-0kba?*R=X%phYdLm9-TupP!E(gMFV{pv8l%(70QZ!M;Be`>pz$tG7Wv z9@d>Ncr0!gfzEF*9cMV!lwxt)2m{K4+C;Lb2xgsabuk8Nb^*ZnwL`X2e+WBp)5vVU zYF)@}V9uht);bhYI?>|z_Ou5EqA%u^>iZkwy-Wv1!OZg9gsU`M*`BIdlcX> zzyiP$z|nvg0Gr&K7CC+k zywZSujXKU}Sor@!4&5G?u@yiafrgo`Xgc>&2C><|p2y}bxcCRQLEEU`3`}_I=MMH1 zu;?Ai`JmY0Ss>h#z*=PBp>}7w+*;lT+P&_5Fs{8kaJmQIO?4&b=ZiHu_vo-I_xPiX z*~&9D&L*9Gd$q(qC8VmY3$ivahA0-aqTD@}(h>EqL*D6S?z80(a zX_YZprv2v-5VecPnlo&O&sY+Xn&*YT6ep%0K_$ zsVeM7@?>F*-Ye|dYiGN6V7m@XY7REFB*jL=~O~3(w_X8dQxE}CbJoh9Zb|7ns_O6y_Ofh*|_TLcmDek)A-AsLQ zEHR(@K4|jXV+Ql7r+~eupZm4JeCl_=-q*B07|f@5%G3v%_78*Mkih=PiKeYH7!C;p zCf|M0U_Q0Yp`l##UF_#c>|&Z5FJ$-5F~B~?2h#N!1>%jR1T=T>x>~XCA(h;Nq=VZb znN2gdG$4%~1T&bfyCa2K6u*=GG&UJ`yY*e}{;_7$V+8dWXfzqYamCLC$66(6&RJ59 z!wB&mL9Y=I-NwI!bu_dWYyyJE;^JSmU(vDbbY(psEVD{8I+mWUf+xZqSU-(r?-TrUe36@3 z{;W4+J_zi8G?oVJJ^YwQJ3Ik|be0N(TTMbgp&r4{ec!wB=*uY5BG0Bk#z{4Z4f%HN zT+*TEO@VrmDJ7dnxXm*qidF*K&ORm*vC6i?h_=P@wL=8AwXIr|phw&K;e`-mW%aFX z@W=(pMrp4}(`rD8xJH<7M+(R~;buR&{-8?|h6UKn#P5OM^cf%v0mtI{O29I}X25BH zR{>T6HUd5hxEPRi%lm9M>EImM3`I-^3dDSR`=8Ku(M)PQ*Z=EFH);4tiof^$==AXb&6AoVm`! zqADR)XGlw=C?~UJgG(YFd-6fCgKnR=aEnuzljy^U_07?AKQ}MCWoQz^ZFD(wy%7{3ptt>=7K^@d}k4ZHwm;* zp;7A-8dM>iv=N^dPU$r-(5J~IJ@CS>&O`Ea=p8R4H5}7=M`ZJIGVknd+egnFn#>ox zO*NT!bgE=jm~=~Y?P9W9;vbW0iARlcwZwN&N4;%_gPnFrOxhtajBC*PgqC5jo@Mem zy>5q>BmQ@LXoq)|NGpst?oW2&+HE{5t4Ap`olQaHBF4P!PBX`$mBoGJkZV!*F6Eo* z$MMsXk=2#ph!n}{&pJFpOn8JC&WlFN725p<>zPL`>NSr{MEtMxz$3d$KOr7D09zCG zKUW-pOzk5dxb|JxJw;VgeDGH4_~0am4~PjL5QE2kv`(Q>dl6bsI!mC}d;m{vYOZH* zx?6w0ZgSuGpl|lJz1_B zQGb;0@F6kbLt@a`Fw_uQhQWI7kJ@_8hu;Ptmh`}fK`svKkZA0%_pNe$YjS-t^z2Pz zOZ2@1&U=Xxw!gS8(f4}AZ!Y_4yWiWG6u-TmI(|Fd;WuK!Z^V3DeNsZ(Ww4(4?WSJy z+g}jB*C&g+->c+&amx5DnepykZ0{1af@E6Ve*An&xp6G1|O5x-yx0m%(SHjF$@?UM42IOw6ZvXpPXO8BF)Pp`BSg zpE|>;gcSe`2Y68RyH-Yc_U;DNIs09l9X7*yRit^(9(}k3RuR=^*r((w zWI;WEx&Fu!lQXKs9nQ3HdC9%RMEi*}{0Qle*L{D_sUYaPV&+tWuKWehR1V|hyIg&$ zLKY?Ti*2MA=tYhT7FIO3SJEh`$=Ea=J`-W@XCjE?*f%q;IJ3lwG#kD0WH$;{ARB}U zm=+mq4!z-_3JaPW8{yuc=Uxp0nJ+yI@>O-q9D9QQ!!?|G2J7?_yJ39uvl%=mSL_Sk z!5ic3$N|}Y#^HPXO=6jf)0#pP zYn&`=Q?)sLrL%>nuCID3_@PyvGh$06>?}2Ff$KacCt1(B&Q79J-p}KknVP?t?&!mJ zCWB&!X+W4Grk25N8^Z-?u1~q|(>BH~_P2pOg5Q-MgF?p1cc=dDN#P-=bBYLsA zscWB!u|ou>A&GrD=9xJVkJIWFwkwKNTzC&bV$BxVaR4&CTM-xJoU^F75;e%^uLER0 zI`E%mbgomQ#H2=v!I51*xtpnS4W=zqA)Ze3Q= z=jWe4bu!GGxyWaqbuc-O1@z>S(dH0>i%ZWh#pwuc(}t4dVt`q6K?zRN99;k#?8&f; zzRR5`?-2$EFk!F)X1P6%pI5-LtSR81#Lu5SVazQ+!b?Jd@kB~> zhhdz2mu7{NQr)1L7&}C8x5g0L!{}z6xQAhSy*__ z3^D0pgvK65Xt6y^ylpy#8^Zowkq#zYma`^3?B9d##qLomqk9xeJXxG#P1{yWpqf9&hG9~BDme9yy59m zV)gep-01F7n09ZMf_Buw{G0|z^L)%aX!~x^I&L=f2LXrU`cZSAc|QZ!lx&x1u4R|P zb}U^AG3in+*EDu1#H35%8`7l^lP*QxWtSrFvP+TY*rmvGd+$hSx#XVXVY2eujbfP|jADbMM?@8F#h^CAJ$OU5_?kexb13mQ1ftrd`2 z4g!+j+W?ubC4el`MQ8v66}2y7vcHs=Pm5iljYY#28X5}sbEcIH*uZ~0v@hs`CKB$a zH#9q&96D!b%;>y@v4;JTtM$()gK7OKVAL2z#$^U{uATm7|ldS-*Qv zUbaB@%osZa{@=y%%bwz`?L!*6!=*W0rMcO7vT{v7%#4|H=gQx$4Ijn#FSf@M+>4y9 zjs;1^6BhuxS5Hh)>U+lymw`rU?p6;@LI02rn(p4Af6eUY+65jp9fd8`O>F_J4e$s~ zXXgYjdN<>QHPI3?bJgoO#&FiE5YtyWvWrXSmU0FxWr@RdSRZH9#uSub>~pcZP-CXk z4i_wUcJ1R-r7l=Ac3TC0JHfNE$+mt9e&zVx$svmlGInzcT(%24%_XI~huuuki*+4Y zH0)y}#$VZ~B3Q}#cA$8Wkb^ZsPGZtc0w*TyW%pZAXo1p3@Vlc}9i0nOWo;cc8&mmW ze0mf*vvq;89Vrx;XbD&cb0Jd(0Opf`@R@$9gY_~5kadGuJ*`4>j)Y>og_vBV)={8j~^Q9;|4Z&3090=V|E49LoB^ z_|iFNxi$ZMQ0$Ng1lfy{>%8WVa{UebZu0c&d7$zBQ2d@?Md)Do1Ik=`YxA-|YfaOY zbzUZkRsIv0o=G~5iKCEBfTE%bcXPIvZLnxuES zbM2aq?{TCXO*C%X%fo$d+nb|gn1^|i4(9t}K*k(K9Sqc4u!)Jm2Qi<@LyHqyzQMFs z?^*A<7jby{bXb5m9s1x%ch25CD_(C7Usvpfzl^WC`}0YlMGyD$`7INW58a>JBRY=w z-2M3tNb}?Fl^j=pt~V>T1{bu$4UZ!LQ_`8!w@x3r%`qkU`BkO5Q@=z-9S82|I6oCR zKo2E6_*cLiJv_+zqcovDdOby-4#I;@ousH!Dk^fyOS2&P#}1SO66^z|?aqLE_m?7N zo*}n%1aPOrZh#!5=Uki}%G9^r{Q&dn<;ADKd(8W<0Ga=%4KLoJd69)dUXXr(m`{BK z+O3-QvB7-mO|)>nk*T&B3PY+#}o70+UW!pU$TxjSqLO77K=A_VhIcOB)@;OWXa-Rv<`=*g@d@J+KboE^S=CvJx4RjZ5i5Gu`|>)w75Jg zc(>IRxct(2n=#m!xA`=@DsD6`0tOdFNF&<_#}ljYv%`%BvD*^m4<6RfvQ=REOb7e^ z_t=T*y9!<*v}I7#{oVS$NHb1XHtV}0d;){?PUXqbcmWF(S<5g*p}` z5C|-6Ze0vDZjc&(GzW+be?pyTPaNb`@~0hGemSTD*1|MHeC|k@9eW;-D&lVe8v%KJ zE#M1)*8#o=c)hu1`SY47{VLk_K}gIpK?$*1W9Z z&Fy7|Gsbaxy|Zkq?RHOJR=io&Ieq9hd{tS;h3AZe52w(UlJJxXofTU{T_wd&2cL>G zbu{>s@t};DF|q0yJG(A7K@K4EB9@TjxN2qP`os?{4dSr^IvL z+t!aoS={Go>r4~B&H5W1x2^Xguje}dW& z+IoW}sTXph$E*~seyaV*p5}JGg)g~vK`u!Acub-(0C|<|i2TOj)dkrXp6Q;3aOr~Q z=Q|_f=((NQu~l4hzN-zC#Q12GiI{zVZ+79>v(8R9jkE9Z!JetIbl+d2>N$H1(!yDr zLU(a_l+VLOCZeT8YwLEAnfaJ%@WeknvWo4K`rf(t{mm<@?3u+>4mIOQucXJRao%;c z`goGBH#00|`0Acv(Go9uhUIr03EML)vY1hTGPDEB)vH^(=U7rg&KQE)0z$DQ%^!-@QqBh)nGpLEvQ!V?spA_&A;dZ<+%)lrDl%hVSKwUx;677 zy7hN81|345p$+r2Io3F9PFmFr#{jeRJf$( zvTd4nRQa+N!(1u8d?-Ic)j_=LQXQb0T#KI_rWl0x7$}-K*ylBWG@N3v?{i_czqz6~ zAFJ<1?$aZ+y^PE09s2q_*E9XeZ}J<2XP4lQ4x$D}{L1M)2`TU*6L)V^sv?&iM0JZ> z8gayTU}0;sz4s(_AJ8LWyO0Q}{Yv1ZRE*L?9-X2*iBqRkVi3H0}2W^Qpf9 z`=O@2WiX%m9GF_(J;`8V-6^zj4s9=N^Ko}~cCu{q`-6&YK1NZj>49yAPBwL5+&+8Q zCbFfkH@o%|bVYkTzJ7mxwP!}#zh6!X2d1OOJTq0l2GbMUSC)3osh^QncvtMm*J+R>I zr9HA>Qa#rv?qdn(DfFeUN|0W&a$=VUVQ)IA>rkQ|7MTjteqxagXz;=!#DqnNLAgZD zZ`8D{2J@+xfNjz=_F=?)DjiH9@A?deMHz=iMw9sV!Xo>k-0e81SY#)PVo47ya*W?@ z5^` z3A+*Vsbjz>TQ%)CgJHcK*i)Kzn!#`o958v8V@i3q(V?|Cv=p-2I|miJjYbxK)&slk zEK8EzVrO0tW%n3~`@Dz%`UFZOMV;i!sANwkc?U=dc@|BgFKqiPm{8c3n6ND|pPGZ# z_!~{T)L=ff2-tI)M#d!OQ+ENAcfV#ZS@IMbmpmmtux+&ILTG13yscC`@hF&Mt;i^R zEgak#p0}s-{(QFk;uTrht8M@i4rXle@99_k&-RH8-80R;`|#!13i0fk6ZPUtLw9Gz z(3zc6h8jc0@WnZmc%}cE~sN3 ze8|!N;%+W}L-1qZAx9%H%bpIL6E7#E!G^>=NgO?=KD(*DslGk17>ka*nvBK-_GrvS zr)WxEM`hbd_GWI}PEJ9A$H;Qur`a((UobmR0pp+rHI3Nb+|u3}u>JA{+H0=FeaycH z+(jEZ|9-f5Wg#xkB1|&Hn_qaifU!NLxwT|JwcmV57?Bgzn9=hNb17RmflPSZZ2Zx| z*eST0cASkf3FeMs*Xnw=gzKHmjqSISPQZD+T}YwSwL^}LIQ#8iH>Rr5)3D>lc_wPd zjaPHrBE+0&hNU}K`5uXyphE>XM|IW0u^X)3Pio8>Y?$1yK@TiDo^f>mps-G5w#$ zX5qO%YAi+-uByHlH>1pW<9QU|b{#qu$f>TZGJXX_MSU_WN+s2<-KZ$Or9a0;FI#k` z0sA{>5hri?pxB`f2n8Oq#xV0Ft_6v4Fjda8QI5yCg_=v{ys){xX=Xe3QnbbD1buQ2 zgF##gciK27cJ_M1j*cmnTXeAZXRL8rGt^x!9)0oOylfmZR{xd*+XdAdo#4~wM#4|BWZ$WD8 z)U>$<^Qk+*QG5gAZiB&{0Wf*@C4>3YP^3bh%QG0o>E1lwyc@Hngpweh5PchIa0^je zKql+?hWQe6hj%mT!toWvdK6!sL1ouAg1KAvoA7-&qw&^O)DR--~aJ z*cd}z8=VBizBYH9nJHGl^*4bVY+2m{NRgPWBC(vBVx) znWNfEtm@p*M~;uPj&Y^S&y2dh!N{KP;pgtkIIB!G&Xx>U7t*sxWcDNvZ(9j=r_5@e zRI|9QaT3lY-;2RvO8Pai_q)}d7*GFkAQEJ(=_s-<@rZ1e?QqZs15R+{WgL;6V5sKG zj+W%CCp$#OTRB*a=GMR$jU=bYrhw(9zxpP(e+8`qnFyFR`d9cYu3tB_>+llOy9)3; zz`Fn`vTp!fY3Sv=o&?DI z`R4u?%>B{k{@I4U%+SAR=qmv6?T*cWOdpR)z8&y=z&iksMShrGmi1QvSppw`W2B2A z??@Lz4B9#F{!7z1Vju=>A2IO_X!{1kG0MQ?-4_ieN1w@a8Tb~lWV)C)lI~)<5o2Gv z80JR07%JE4YNkFTxp73sv4{R@vO#SX4Bt<_a9FTvRk^QQd;8S}?+hJ?WARVFCmOw~Q%#!7QNA z@~z3-<)#x}-{ZR0M*K32pKr(nOfQ892cI0YF@PaEn1>GlsYUGuJO%JWK+3?60LuaQ z07BrX{|Ct7JPf@$Sf<^8OzRPNShk}O6SIC|KJ|HgQD~Am8l53SYB641aAo1nb%<6IN{qmMzLWLc7OPs$oE9`8{jqg|tk? z+RGwF@-uvg-t*9Ux5|6^wk6)ADm%;NacnK1-uV9Je(f2EMV^^H#7gVrt5ZX}kIcSl zF{0|u*F0iPDXFa14`F#_JEk|3HGQ%*r=)6zP0iYV52;bl-4ge?rJ%k#rKIZBq51a9 z8QT|t`1>g(SZ4Ztgq*c~8ps{jmFO)&DtN?tCeHTex}9>nV?~x~zsS0-q|^WK9N906 zJg(9OfMGXk7|J-`(v-?-t}K~+CoMwx|#tD z4w0Y?a+3|!j&yD3O!vp>>T1v)(s!3S*!933)HHOc>H&>?1K2uqnWBN z0~0p|9L=7k@7@EfP-FK48?CX2fPFz@4+9&au}6TNsWEPsJzZn#ft{eS$AJyg*al!j zHO6+!-Y*|NJ3NWIt8ihrx;Ib{?nTpYf?sZPYuc_EtjTo?Yl4mK*hn0#D{YgxtP+ob zPVCfH=|q1Y93Sf$sXztR8^7XCl}GmW|s*n>E2g$Hrk#vH_HgMiZp4%b3< z&GQUB$=@SzpK$mvo9p8YJw1F|R1}Yg^yrh~!VWn$qH?a6(dRBb`V_oT)-b+q%K za;^KR{Am@V$9f5cUcwkJVYHV}08Q2LgoQ}Qd#=ZMuFvsYkMUfO){60wC@`ZK4>f~n zmi5)a=JvV(e6C>bKG43brA~=jOsk^xu6(l0sTEWEeb~@_N2m_2G(&&vz%W&10sath z5a1TTqX9V#&jqCR{~5qE#PM0c;{i_qEC9>{EC)OVa3)|rAnmhH1-uXNG{7GLo(}j+ zz)^tz0|@=7)L=e! zJuvDbnQFDceClRk>_IctI)nMt*MPAv%~baq%%{EwjJ;~6demS(^$TF^Uo+KagJH-I zjQwk-deLA$^+#areKXac4dzpC17q)-sopb~PxXTe$=)|p9bqsZYgYHonQE}XeClLi z?3**y=M4snF#jRwQC!fK8^wA=P<6n^LdUVe-r!**P$&Cs1S0$tj`tx?ckE?m15 zubKG=>%u)TGZCBv5@qESV4_x0cnAi~z}%%{L3wUEFi~JGcCgEVl^|2;Y5_3uxTGf4 zG@aI-cV%6B-lDqJx}v;=HT8{kwR!E$npP{CL>@L*2J7-_+VX_CRC!%nTg{bqZFvjy z>x*iZ)a6Az+jg=VrWV#Tw$-WjR-A$}X{vwHMJDp1yhSx_0rNOL;RWl4pI(%wDw?C? zP@J8b>G$uH^ph#B%# zx{5O<&A%7V#UGP)`JdxG>qG0LP{qi8*RRwA`{1b!;!Yv-WZG(+w9!?fosM*sXh{tT zv!g$j5X!Qw3hm(7Sm#a2MHKzvgWZ}k6j)lgEZ3Sc1XxD6Y{=Rvc{sD7xvz=MePw8OMi6-^h?kcFPi)DR=%x5k!+=LiRwyg54iu_3Yp%vSB^a|TsYnC

3VWj-r%T3JZh8qWITE*nuff4Ca|IU-SdEb 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

iSm;Ux?CcFA4+OSjZyQHe_T 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

3qrvI@bK3h0{`7r#ITvXp^`iQPJJ{A;HXU1A} zmP8~}RHM9{RAR{|!P$D=Q{XK&=?pL0^v~ZeoFJ!ZT@*rjptuNGl1leoNGjdGLK>}d07<1wkAX_!Q|T(*Q*chGbmu_gdOF>C z7t%;z)16NsjS%S@NGi3eAvd)&NO?G#pXIk1=pK_dol)H9 zdbKW$acN@A9yrI0CKxNOM7*G_3>*0KzuyDbr>$&%Z*pl7yUS=ubE{yNq+PAAFelZ) zt}A6;t;gB^=64j50lpp?oFt!&FC11hX_&d#fIp5JwK$7&uRGpFNTL4L!@02I+JJVG z3dUYBc4FRmY(X0$bJgMkG6CS)0lw@Ve(oWzt?W{B{%?vrstZepd*RFxub;vOL$Gtu7cN9qevM+FtoAWxa&KcgTiM?jTe?^Qvc;`dJ9T0ztcrD@si23gKKM;3D z{3T*O0sJ-M21pSu;7d9o{vL5I;vW%Tjrb?T*J=GS{rgVDzd*kVF~0Xv@(AJt#Pq%t zLc9@i3gTUek3q~iF%@wy=FzT-Q_3)rLglEq`{*5N=tAskCZPF-8EVYJDlM!6t-X} z25B0vvOM15W@g>n{o>#6-^pBX}sAla(9`qsWP^x zFn|1LxHZN@s^D}x4xcFkEX>az#9n#cz>BIDzq_>W^ zb2I7)TRqHb(U|-UJ@{vc0~xi=gD!H!fYZuByZuYsJe&@$lA3P_iRYN|qsuc;ZJ6-< zR2wEdd)0;s&uFz_!t*`uros^9=5A)S#S4*~ulfxfgcqK^8+8vgQM~c`?zqD{%GP0D zRuo-R#yRCPGF-O=rE}8LqMZ{9!qL=7IdA12Op0t|T)vLiJLQWh!$S-m&$yWAoW!Uo zvUa4-dylDPr$owVh}VAS?INsvFMjQ3f=a|SDv#qjm^yU;S8}c+gdf$rg#_WsP`Nae zob^t_?!^(BD|1nnY$TV1*P)~^2TsR8iMok)Pi&OD?v~6RH~(-Tv}g0riP2q~51iWK zaA;TRJYES#FG|EKn_W|o!N}qbV2I{o=SDpBEEbiJs{ik*dZOQsE^&0LcMMI_267eGC zK6Ek`@}fjlgDnoXon1HehJ{r3N{=Q!!}r5+H1!(#ab&5Op#UQI*yf`@(j)b^|~nV18*hH8**S!j<1 zlgWbWoQ5|J$=J3{QIpa+Kc*EN8}0UqGE_(Y(#wAosH_h6Wdffv2YP2VMBadzVxr*urS(}T8 zM{lEHqb-|%ta3gw)?rGGG5GB$|Dla`WpDneipp}<<|*eyH}BcM9=)$aqgS)`6ehNK z@nDtEPL=VjorP7RJNuMNx+wqBH&Z!4;1J$S zl~GJaE(eW2YdUs$ShGBqQt;?3iAsU`|x0 z_`@>brif0#s$-{M9x!)GO`%Zq&jg z>($g!wpFzE7dy%+YnGvyWng={-i3QuU;6W6IHux{XI4nuvjA z43b6%>i>tND5-e;rrUUTB$2KYsS>?`eP+*rL!05paRukwfn3F*iPVatjFlOuiP*QK ziDcqo6ZNs%=;)egF*~qz;;S_bPyZWK6M5(U|3?j_hWk=Bmujd^iP4`A?Bo*2J!{?j zSh1%yX5Df1(BFBc_?HFV8HV$?7TT^MTMbSr>~_N}QNg(t9J;%WSIq~~wEy2*jqSye zFuGAKwPmm#1ZOtxol^f$SR-03(mPq!y8RMWug7BCiIhEwQ$nx4e~!rIR`j}ecrG~6 zTwH7LaG$=pU$v@~)4oL361 z6(ZeI@HaXmk;`~g@^K(7&Og8>bjF=ChDmsLdjn@l*A)6=!Q6(d0m~;EB-3oa_zk94 zvj+x#=Q@H>WknI(CAn`UDVMc+5r+%0u60}Rn)ZeTxDqU1naRwlMK`<`m6vTp@o<-W zB_dtv>^e^IG<87)cQEUuJbmS;h~mKqCtV#;(O*ih6i(H+x`0->`e0cw0sFi@aOMtP z(E@NBuX?>3qS3CnAXuj_#MGrFFT!|f$=EIL(O!ZSC$`vhFcj_RUEG)P1EY3|9UP}KSl&~mr7os*Q=zAUJHu@%omPE+TE3y7 zbk-5mLSuSPvTzYC-p-^CYp&hg=3ry`_9s*?jP^-WyAhGZ_38?520dwXZR2**bjmXl zH}6ft!sJY|W-FIPOJ8-BA+=Z;1qY!HB;>o5mG}hcL#(f%&0kb>%u8RgWbn{pA&+>i~uECPyl)MwAb)l#?8p;hcf_>P%!%aS1FJvBxgA8wazf8EKs7Wd z<*{2;7{A+cpa2Brss!cbOPGk+`SpLOrHqGicSyua5{BK}@Ln&Q%yl7okICGPyRGTY z9Ow?5OX(pQ>0>kW@KBxN-Hlq*fc!JCc_RASpyXq^fP0mr0P6>y+Kp;W11&*n#wBGNn}9u3CpX zGU-lFNa`rR&906vG)G^6q*(YtmyffEz=sx`Z$+X58zu3>1EKajIs(#hBJrE+iuqGW zia8UDuP-HCI-yZV$3Rj?d80@j{X3*bIy0x-WKuO5Le7=@q6|n%cOE2FYdMfq9gH{9 zd`K$ybQ+_2M3d@nx-B88bSFakNOHBp9HsLXb#$*e+6c9%_(nleeEj;iD#r(q6yo?A zE?*Bw>S%9B>S)9qeFl;$(d&>@iT(jerExMgN>m!ml7K zI=tGWod^9Dl4|MCA*nQK?K(;=PIi8*-C9Nle>rr@&U@{T;(9g@P1g`}_#L7FT_zc5Er)7_(akiyx* z3~4aV<|OBNNDg#K&Wn(`;RVNZ=VM3%rQHreQst;p8_vHZS9Kx1hBGqVxd0MxbEi93 zLRul%Yaz96Mcv(y?w8*5C?(;04N{WW?SrI7sboBbqIBtyRBBm}_$UHyDne2pg6acl zjpznKI`W60F2hm2`iFr|!W`t#|7czf^x0|t$KiaB=E*y!{7_GJ;62nhp20ij4 zGtjJ(GXUQtmD>lJwXEz6RCXU|*1WQ7pwc^G#SWVO_<^Wm2Tgx``V~7!`s34YQ^`HB zMP*mOd6iuOm7al$eN_GNU9hs#uk2~4d1X&S%`1BvYF^pXQ1hmhJPQ01M}dF*Nm#L? zwm&}oiXFB6@#$CWsO^tWzo~LrlpP9w35nN{O>m*c_=11&bq$koc`1Weqi(>KgAVat z%9xMsO(ci69NeqKw9JcpHE)jVwpdl`HbGVEpz6G!Dh^l6pjC^Ys(Db=EU0Q4P@UH{ zs0!x(yw>81sTHbPe*h{CuX141&Ph5AyBd6W8?_0aMW~}~*t;#v&!33b<|pIhoB0z* zj?FK0=vj%6;`Tekaq_2)EiB@vZ56OC4!LiIXPM%=OA8%crM~Kh_6BX zBH~iS{7hmQ;z@`XA-);$X2ka({ySoRu5K~n9PAD8_+-TQBA$u(KE!m-v>GuT**}Q* z3BUW#}kVz|>TDM5S}V!pa_Mh)Zx@f-NP2yr9) zejG9RYoHw;MtlNdrh6JQ5iooLVXi1#4gfcUS7 zpF>=TQ-I~=?(Y`Fbr5ew{3zOQ8{)NyUqn0`?E`n-B_)Xej5rVbTyG&BhZsB5B}ItQ z2TGnp{66Asi2sWCeZ;RKhHEV6b;PX^vs~>F^Z0ngA0jS6ych9G#2+KBhoOx1e>LJy z5l0a3M|>yZgNW}%{2Ag$5Pyz%3*s*j??C(|;&%~$h4^E{-yrUZeX(y5_eT6Z;?0PE zLi{@7pAjEG{2St`*b7ZSeP55b3gWY{(-}hiBH~2Eb8-GuLwqCRWW={3u8w#K;xOXh z5T_wd!VY9@#A%4@Ag+hFF5=S>pMbb2;u8@ML|hN?t%x%aFGE}(@hZfbh#y3JI^rh~ zvtN9KxFO;Lh|faY0OtYgou}87&h9HxykDhWk)jlK*5c@N(XH1~*lCTPeYNPav=nyO z+h>SwgObVE}w6x~Hy!j}Uf-6Xn~ zv;;exsW&S-Ex``bEy_+yVP`zfQ1+Y}4)4ZLLVtmz`p|kU;iK7*7KzD_iY}_9uyY5bHKKz%Ig!G25a&E5I=F@t34H_7Kc)XELHBuu;>RuIYwL3S+vjkls-6B$dBjrO{ zBDx8X)XR^>Mw$yrvD|2++s)BcM)x?R=Y(awIl9G2yNvXjk^W+&zZvNtM*7A`KO2c} zJk>mjcka@RlnF^aebB^6Eg)^gS%+8uAgLEI8)Qt)D-@4eqbC(l97W$)WAa92$V$7A zzO%;Y!y~Y0&lo=`Z4hlk-% zYh-aj;n*qpNX*2m(H^xMt18?*e+Nr!3( ziIbmtzm!v>dcTwtr+UAX(`u449Cn;^l^ZTj#L5j9Cv4@0i_^Js!^O#7x#8kcK)K=K zLP5FV;^HC6SphySGL#!GE-a};^;FY(bOCTxVMwdf+UF=3edR3&Ukd(Kf*+#k^(!Dt4 z)njPteRvM$itlAe+E)^!mxbk1NQ&iKND5mMRi?1HkhmO47f%Y2EK2lSab%xGvvG7K zn6Q4A@HNo>2P3|~@nW;_5)*G$nTa<= zFZde&AHn}VF}`ZpSDHZ2aVhyU2ofsvRl_!E*UsMgWOs9eJ59xRM?=pqoS5j1eSd=r zwg5eUD%mbGV&<2dO}OTCT5A2AWaTrw6!9A9Ff^4M3!5^;EZ4P&Ik#@bd7wV`&huSe zlv4^jPvGcI(LJrDu#Da>imoL%DB1o*trdoN@J;(!p?qU z$45ztz-QrQto8Zs^$oSMu-)of7$>*1fRkGemC6Dmod{;(OBXp6EPOe;tC0my`)R2= zBsH=Ofuu&3(MGxw(%Z9j)YBy=~NkTwVIdVJ)6Zoht*-8xJbp)(08bd=4_IYaml3O4DqEpb|RLVSeK5* zQ&%vanm0Y8Xi~-%`9&GiClwc{1t%O7O%l%%H4NfJC3sh*RBF%TRe)g};`_T&K;4x&BKmXo& z|HcZ^{5Q?}(VUb>&LVI2|AVIfWHgZD?31SW@0|Mkp*N|ie<&n%g7PB=N1poU;wZ;r zG?IkassCCGJxl#_aJ;F%^Q7_P;j9@agm`c+^gSc_@0yQuI}Q|Xoz$d)>}Kk*$-DiT zJJJH75;KTp#D9GjoBj7^(Or^o_aZN5Ny0wNCCNy{;nP$<#x>U!lO|m;KEGW%xz7hr zPwm>-(}QnG65BuI=IkG^L^%<+_c+9V)d2S)7BKx zrgzq{n%>z0YI;8)l1#q)(ID6qMH4v5U3i>x&X+izF3W`P@hcPm-N1JChcix5zY-B~ z3BMHor#h+F0rrB6!EFiWMsM*QJYRgvmwIm2C$uaHVVsJaq-wsEv-e3#a+nN3IMvTudY}ZaT!%;OrZ2dD&vGxC5f~x-? zO#M?*^-n46yaANby`v?376nrLI<9Hz_&1=_!G!y@|Asog2Rw6*u8xB>`7ihNEAl7i z7w{_)!zSZe15a^`EgE)IRqh;3ou3v`b^a@ANcDM2s?I5eolj6&rDI1{I;nHHxa0Zb z)pH278-M(8x0GQnA-3P%4{cdYow^vt|Euu>wKr{SQ3k$nQB+Vo5+5{EqsaffX7M}; z^2ENR>Wq@AGfH8n^n8vfX$3X!M&!N$z70+Rc2wm74iES6JpU8^J6kd3Ip3hJlYn$3 z9#!{cxXG=KW*X@%BPBwL9jm!U@rT&DW~OGv)U}H_2gm-1y8hQkY*ojcn^YZBQguuT z=lvRFRmRq5<{62Dw$e2=5(IU#kbTt~cdNE_#{{KgjXR>_IH`0eLi(i*?M^kiOrv8f zC_C2PA+bw@6x$xnq4S5>_P7HFr^K{}i(%|*4>M*TsY?geqW|lWTeSn{Ce;p@oIR5q)&ocCB)Q__sG)SdoZ7Yb)okmrNp2KmnN8_71O`0|(tI{+Xg*$CUQ+Oj(=KD|r?{(UtiF^n#vmdoQA43Vh_Nn4@ zvW%J(a2rOcLSj>0A5VLs{5OT8f@No*O%=zF;*n5-i)!#r>z*F!G(r$)W23mG=%I!! zT!>!IJTkaBq>YW@dM=dU-r}p{?0?Wh=|Z4QVo|jBP&4wU|Kg!|D}jMFc3R2McsUF= zc+{6et_&GyW20CP9_os27r?|V7jH~3(8flw$AuDDUWOq%I{8rVDy8&F8^yWbD_6(d z`QkUJpf=GYqt`Q5@^MI{fpMMW|Fahx0Uw zHa3cjd#_wm*QIUtPkh2P_;OGBGAT0oeYhKiteob zfQM?UQM9p9ykI>NYPd$x#zt}8KN9LXjiQZ>%CJyhJo*$mxLX^KXcTR1RQ(E2Z)y~6 zY*YgaHR!exzP|CRM$yJbomK&g&kHlq#ztjAIiZ(W?orTI;d&%b>sz9S?W23SxRO@kDFaf%0(Ps(+ZERF~XuMXQ_{Kbp zw=U`hjiQZ>I^ROQzq&dsUDQF1qK%EhHlZ)Ab$yP*V$em&OG-FS8ynTZLQTHs3{0mk zs&z6BBGAT0WkchYYj4+{XdD;Ck7_ey50%184FuZQs2pg#a)r;qyEw2=p`Aw2 z#zu9uPrsZqX>(*r@K%csaC3n++O88ynTbLfNCuCmKZ?8+D~i5fE(x@;QN1jbT`s&; zC4n|Js<(x*N6|eRMH?H1N$!ZX@q#!Jg?Wqe~o0&Q&6B^GMwmd9q(LWR8=MH?G+sf8N+&doS+T~w`O z6q+_R>M{!z`gC@Ihq_p!Xk(*>Sf~@WP4LY`*J>1PY}8N-)i|%_7hYOBHHtPi>T(NZ z_ukr=%NS^5qlQ7_)x6za12u{^Hfp$qvU}8R8buo$l~)1kRgI#JjT&L0?0#4y6$cS$ zW1~hw_Sc(q~os3{sn8yj_%g|hp`(;7t^8-;<)mzG`gUuzU?Y*e9zvTMHUaX5%T8yi&w zjaM$a4)4$?+SsUK3uV_Ky&y8s#zswn#!Jht!_Mi%@UBoS3JX>r%I+JtX%ubjw5C}o zyXHUFDB9Sl=@!a9D?8W5K?K^^sH>sz%4P3w@C{}L+SsTW(0Hg(dpDxfxwGCujiQZ> znrWdDu1k2^Lv^Twg9x;-QL~`&(pvZYTNiq$#TrE$8->Z+hx*{1ao>2T0~$pe8#Tv5 zwV3+hUJrG_@i>S;8yi&ujhDlLX(O??aBJfxjiQZ>nror#HTHguqK%EZ#zOtvbk%+@ ztqyf@5P>!}suUV8hv|2v{p_I@X%ua2)I1AipUVd{iZ(W?%tF~|Wu1V72(+g46HT%%}Xqpq`1b`E!F6m4wOd<$idHW?@4AOdY{R0J9?hxTYQU887Yqpr75 zb`D?DDB9SlsD-lAI^!f9M4*k0S^$lgLwjVqTBB%VqslFmox`UziZ(Xt1`B29@N12t zjg7j|LfJVyw;m26(8fkBgvKkEJ@$^*DB9Sln=F()_O8|_+SsU@EtK6i_G=VvY}73l z${w*Bo{WPCw6Rf(pz+FOkJ#fiiZ(WCv4yhR>p_j8jg7k1LfPf|yGGH*M%`wi>{f1Y z3JxOB#zrlH#w(Yd!{Hi58yj`Ig|c(FLZfJ7qwcU!b`JlhQM9p9OD&Y0!_!a2K?K^^ zsAbT2<+5`)Qln^Nqn2AJJBRmZ6m4wOofgW@;U^kJ8yj_(g|c&4KLZC5Xk(*RK;xCm z&f&-m97I@w|2FDwXgrjCF5jDhg9x;-QGbHQL)qo}dj<|7(8fmH1C58W%hjkpF?d7^ z|83MtXgri%t|E=1jg4Amq3j%P(kR;4sCzAxomN@{97Ldvjk*sSFNby=4%aB!*r?SO z%Ff~K8buo$b-#tON1N9*iZ(Xt0SjfX^wLkmK?K^^s0X3(%4M%A`)d?!Y}7**%3cxO zpi#83Q4d=vdqwnTjiQZ>dc;E6tCX}%97Ldvjd~OsuUzl!_@W0bRLIpR+SsTy7Rqj~ zn>C6yHtI18W%v1aG>SGh>TwHY=kScvaS(wvHtGpzymHZo7Ao*gE(2|B)RWM7D7#z_ zX%ua2)KeD9F4sYgqK%DOYoYK1!OdawGt_U|*r=zW@p5RVHASOnW24qtDEnMquTiwI zQO{T?yEZ=8DB9Sl^%ly`VS_Vq5P>!}>RD*Ka@jc?tWmVFQ5!6jeOBJAQM9p98!eRG zqu$Uc+SsV)DnK3I5C;)xW22sj#w(Yd)+HK68ymH$0@MnPqK%E(TmfpIM$yJbZLv^x zE1z{14kFOTMs0=0E0^8MS7{V&Y}B?2P#ZLgHa6-73uX6>A2fl^Ne$F5P>!}>NRM*a{co3$_}(pVWdXU#zwtvq3qs! zpGMKfM!jL7>=n`9G>SGh>P-t}r*(1@97Ldvjd}|juUvLomuM7iY}DHp%1&#sM$yJb zy#!em;Q4L)kS}pi#83QGc~i zc3Mws6m4wOhZf3CtBI}$+SsVQ7RpX*l}6FVMtx+V?6fkP;~)ZUfErO)C_nM%Z}=Zd z_|E-l#Y;7cHmY^Lh9(iel%@$@-YL?Ej}eCwPS%#=FTHlC!uX%w|3qvu64Z0*1b!?| zIViPh!N1gG#FT3vw4sC){-uG0Bpvq$ius|9%HfrohX!u_WESw(-|;_`kS==uW>6UH zLunLkfbw1@a6W}5lu!?Uk!|Pim!EjPhq_OrXrq`mA2Id)!jqq`AlZ%1d4~?RY zo#z9BsxEr`k>KX}9~wm)8}$!pRGw)&{J3AA_0n=ZpwPxf9kfv0ro7wEL!H_Z2N7sv z*Ux9rc=hwmfDQdU)CC$v8#}Gf1?ASpoz4ThJ=9>0qK%FELQqxlmu;bfTN@KKiZ)6& zPiq|MQMA6>rx}~@XPCKY#l^qR85>F6*TcWWQPmHL`gGr*WQF(l@UO&%<*kPQ3}2ca z{=R1Z(&Xp+Bc}B=kfDTz{EPqfU(b0knASI9!xUK~3||{5y_KuU&}GD@g><0Cf98G* zz4z|G>K|WO5=`qmvGJ$%tx4+w&HSyD%g_A1pxm|!-!ehhxWC2@i4AMaEyedn>ZO^# z4>12As44i%@Z3#*SsBdpk2n%a7=`3r<{ykSL^J;oVE#!^Cy^H6;wsGs2AO}xkx+s^ z&p#RFGR^!`fcY0e@mxlhoIYP>UlC;fRcz9IdH%&PKd7015oY)(pD=Rrbl5Xw#I)&e z(5cawY4z*XM6ay;HUGQV)PsTBSAR2Uy{XgsO_*Wm9M&4jcKH}G0zF2$X&p9c9djOF2!~Btt+j?)J1xHa5K1@^dI-*>Ise!aOsk66q~WjI?g{3d zq^_DdAt3|Iti!_mA}}#f%$hzx2mfgUn&EVJo}L)eZ9}nz_0#gTl#d&A$w>^;1K5Qg8%E$*ATz_fBc^qX@bnNXczXVDLfc?kbgYL~#9y~u$C$L9(9Fjq#Fipe zP^K*g)``;=?4_Xuu2Eg)RKxtCW=;(-^Zhn&1-rE*0oO0F^+RW7p@h9Y=30iiTN|hm zY9++xnJ;{L%&)xi8261cu{nU6Qj_0i%C$0x+r#t9blgo90S%EmIE7+^lZFb~qq zCj^*J64Y@_mf^t;Yl6%inL`QwIrk*P9M#MxCB)|WWI?3~E#7?oy*_$TY@SaM8~?d; zvSEHnGoKt_=J$?62`=*+kN-6iWac@dt|r`iKGiT+!FrP6)P&eP*B2Dm@eC~s8{HaY zZXh=PIk&!H&e6>E6JnW9vzXie^v&f#W{y{O-#E=M&(X}M1(;74lv^A1-aqgAAoCew z!*z&T8>buQCp7cv0p>FW<@SxYGw;F38QX$%7;D$_nTGi{&3tBn`7A-X^?d7~M=?0X zGM_CrdwqF6%P@D$f*Rqhgbd*Pb7dnzRXo-;4lp+|%yTt!qX0AC%JoL1_+uUYPunec zj$!^nGoKS+KG$N7Ki2V8b$g|Eu3;YD9#w&GZbEErG_#mr3cs^2SkKJ^%*_n*+nTvq zfVqXm9KQwWdeR>GTNvhExO!!1kr12bRu=QkH*dWnnCJ7v#y>u{GRzA#bE^PzYm3=Q z8ZauzOmE?K3$`}Qn>2Il0CQW5IsTl|PHgr%-Z|LTF#n*L+Xk5VO%1Qt-BI_%M}v88 zFE;+#$TG~$E^@gw^;RJDU#-Fb^=y^ELB; z0P`S=IetH+dwP3yI><1;pqU2+m@hdB=1T+2ml);~JE4LRE=h>3jmrd8@d{*!*z5(~ zJu5FW%(rRg%L2?ptvttHfm|*&{*h#;VGeahf(SzsV)H!AVvfH886L>-dj>^=P0pm!J-0p_U|bNm*Z7Rd8d!`!2rs*R}u=IIu5{Cd7xZ2Y}$x?wKY z%+mwRGX&+H-FLmRp8s@VvQpLD2zlVYj zQZwHYU|wu7$G^tEHIV1UhWSIyyg0yoo5dXe8h?q{_|KHv4D<09I}&aSFyC%5$G;N4 zBar9Y4RcS;e0zX-sm0uMZ8zLrj=h>#CN};vWvO8<)67c)%*zGk?v!5j;8*>E%y){- zuPC*9rYtwi+cop@0P|fI^P9t(z%n+^E5yb>r`%?_cx5 z#vt>(0p?YP`D4wzDj~Ku?z5OT>^XTykeOGXp#*=P?=#FN^pY$&_XU{m7gP-#hTy!m z_>p-*<_E;aU(fd&=H8n5{s8lXf;t_n49(UjH4HL8BsS^z>-M?_4f8_H{9rud!#-cCl&bV}8Lff1#OQ2r%yu zRFEo-5@6nA<@u^tX2&^GUK5*K{B>(%k73Tz%zFaN zuM5h}^HujRULDNy8)Dk!|0*_J@Yn4d9~kCkn)!nO^M@95Mz5uh2ATJY zjlVWNG|Vq+<_`nR9|_7`ufCPN;>;lP-^9khs{F_>R~?`#@}mIr$AWU#QSq-vKM|Yn zK;hQL$A-DRX8t(9yiZUmDq-iXEvwcB^Za+Q@z1dP4D-X9d0&9}Q!CH$_dxcGjlVWN zHO!xC=1&962LyGD&U0wlLvfxb`9~nn2MqIN0~Pc@fcc=H>fkU0r$h5)SW?B#R-cKD zKhFmZ^J2|>P?$mCyr(sk?X}J4!ZQtew(Id*cbyST>kF~@4u5Nq0O50!*2#lhO@_;y zNj5y8Ehx|lb7_}1-tvb^4oD(=b?mJ`q#0acl}9~$N#MC_hM7m$NZgP9-*1P z3osuNl$+=H=fw|VQkH1qGmjKrPrW&EpxeJ(T0p@d=_VjZ2=dvVKP zDH6nn{oFm5ohoj5y1UF(O#SF{xr(6t=dy=dtWi~f3Q4xUb9o%{Fq|?(rKfC~_|DUi zF#FF_k9jIkJWs_&c=kZUpfvt#v_#>lxNlSy8-EKXnzA<@s+beKvMYs?WHHA-Q>q1+ zlMM5nnmH-JoGd8!Oj-9$({91`sxCHZXfL;wk`43gnmIYZ9JcZte|NV=AkSgLe9Yyl z@ZkV+ilDgGg5Z4TTo)(L$B2!8L`pHtBQ$eLfVrli+;z+18zz4otc_H$`4uUG)utPYUGuM8iB^GoKh> zu4m;r{!{KJ2l8CcFmKb$^#aVNSb5%;u&_}u&-@A~o=o%gx>F2uyF67Jrv#WYtUSlR z4^m%j{4JPam}h9_i~w^3E6)QOeuaq(Dy!F>CN};SY+#rVY32q2=1f7QfeVFoZvC{l zUXb~8vGI@3nTEO92vr-I!c2L()=;+R!83#hT}0-=siE?mU|MIYw2&Eh9z4UOwLvqV z;gv$qgAE1cp9eiu%1GwKaT)>@5^18=I8KJtBFYU7(^EG7dGIV@_RoVJ^EW_o9uym4 z?mbE(t?|!;XA6&e4#r<2H4+>DdgE+U_J=j|*;SZlKXYS2x#PyO<-M*7*6KN8fDB8p@57x|0gqf+_sWp`CQZyBwvCy-QK3Mtw zpBkb3yt0hKFi0nmKWt=0Jr+x>J9)-#1za zv%hb6%&AwXz9BZkJPsNLrSZ35OW~=wZ?qB{e+#xWW#6uuTY6F3)%4EBU9vGI?h z?F{o1nz>zoxxJv={`}QNtG);_pD#B4dTwu+ztPO?g_$+ei5*r4yFXtbJZ^tJVPeXu z!L&Mv4OedNSa*R*E25b%@JgZkbGD%T{n{Kq1?BdQ_+wo+vGMnfu7-J#X6`D?OyeG{p=|e!?!x2tjre0- z53%9ZliN4Co3!?8=I&l8blBJYtd}>J?zlwV2~ywc!(;s2_i?%QejJY3AGjb6-KZ{dxZf8!^{FWv%P_ z1(^F9<^hvcp8E!v`wPnL&wCc{!`KzeJV0#xwb9=&-=vxQ3o}!BPirXK{du79xc&Ls z{q@!a(;6f;%!1pW2b#1_#fpVtpjQgrp9c%d-=96yRT?!IsF2{_)Ecip{|*h)Q#Sto ze2Fmo`?JS9q(Jp&u@UBHp*PWtjV|;*lqM)j& z!%nqb1AvFh8bv3GjsJ>%qG2AYnI{IACkx8WbCV`ZTLhV}5*vS>CmZHFHS^>EbAh1T zJpZ}IuW{}m6bABKV3q@M^AwdIUC;5~ z?V2h!{yAleVIHZOrv#X%S$V$Uz4tZ*^E^F}=V^v{xn`agV7}VQ^RAMYF(W`_^^F-~ z(4U{^MGjzIWxdKTTr#sVQ2B$HF54u z%n2~hHq19`=Gg(}5{r5KCFjN2ah)qR{xhY-Fz?aKB?0DZ1XW+>`S6~f_6KXDRBSSR zwQ-GMt~FgjuL&^E6V&lI44`x2ySx{_2Exz{!yeA5u19xwC0<%s$I>pz&DLa ztGU)tYo~R+@YLr4gk!h7H6z$MQL*tqiE+J2tBYp7KF~S~1eKeC4GcO1*-ykRqxY8EyHM^@U$b6&N`15>&VSZLK-(c$Jkg1=HnEF{LJR@}} zPAz@1S1_%c#HIvo;jV}lnzYV9eKITzl;UPVx%G4S&&`_!nQsvr|61#2!#qA(sT0?+}!m=kB`~of~9cDmMO+?GD4-TQlDg zU|wc1_jq8++931t0P`}#e4}Pw7GS>9VvZF5h`9zTt2XWmFyCpI-_Xo=2AEe^%;Di% zai=Vn`R)Mo3d3A?ma69!0p>qh%)6fNc~_A6o&fWo40E1l{!@T?rN#WxyN@OXnO6mv zR~qKknt5e_`Cf~;MpFG9LFW4c%=a4RFEsPL0p`_$8ji}Uj{p0LQ^p0E?-v_B%jEXX z)rPtGY*o*zg*o%$UTyh13;)TS52!jU z@LY~QB&ZaiLin!&nqI<_K=Im|Hki=_rM#OyEU0uGgP?;e9n@*j1}HBn=Mh1*hdoQN z>bW}oJp5^M6b)_cv>p`{$8e%-@0~+6iZ(WCji6W)M5zFkgj+Ov?j-=8JjQ-4W=wzJI2@eY>>Lo=jY=v4kgrw4NjdTQV7+zI{_es0c}8sfv&=ff zoUfVJ1(?@c%pd)7c8?(Qvtr}F(p+ztpVrLl1I!x))e8~036noSn!lP=RXc&I#$q7D8b%+wn1OnES%`8=Q*S*Fs` zz1KHtZI;wC_2JsDo&`&l61;b76m9H0ZxNJR(jPA77o%L%n;JzMrTgapFm@;4HkDl* z!0$EBLkO9!d7cR&gb*@^kU4}9GKUaC<|%UsA%rATLgtVuA#(^JWafL{|Jr-qb*%I4 z=iSfu-L8HA>$lhY?tS*zXSnD7->q+hlil0;PhYir=+~In7eAxbHbc&bW{o|2(Y}z+ zf^LUn?>=l#>C={J7QF`x45un&K;ATK>_ThgZFvWrSIp1sk=6Bli$(ev`vn~r-tEczqh;^*egIXk8`X|9OXWwqsLEWW;OZic zS!*-)Y+%kLqwpWI#?G_6y&r^=mVO+OcJdf=XJS@iY3Ehh46U1G*4V7)i1#QSf+L^9 zj~>NMQ)SOT$UuH$H2&kQk^AB|IQD3=3w>_0{g=GgJB*CHC;E+NY>FrU7CmE-%qN|r z>Xi9cBJ=+ZUtczl(O#5~BJ;cXnvkpfBk8CoABmQ|eQ^v`_A1b3-(FR`_Yv-=<`{yG zVdm}k$GtUlYqDz+e__Ac#lOW>3|S-h*Kuqs2gM^&&05sJ-#6y(r+QU3WBzBB)n<*I zdD^->+t@LNzJ?gxbBVE3g$$gHW{q8Fjoe=+;Mgk=JF9zQG%y#;FV5;8$ec1?{aHQ1 z^Yg|y>zcp#pl0krS zxo0t}u+*4D|Fs!fH_WWD^W!<<3~(NfoS*2eCzwoC$bcMY*4TyC$oaVdXP5bzou3aE z&-+!+&qZY9{9NGqNj=57=C3)Z`MHEDIX}@=mQ<2hn}F2j-Y6TS6QUKKKMT2I4&B4~}ApDS=;(U1SnCrVvKM&9RM z;rY4d$ycK1$Fu%MmA$93%aJ9Fgt$s@+Aw@?++lf!?$ z)@@|u^~NohU;C0uZz=g-2l);%@;SYKSzh7E|0?+|s{B1z>{*htdN%GM^Tagg&+}cD zbIhQg?<)B}RQZoc(yg9SUCZ~8kw@KsEI0Aw|CIb7r04G%*Z*G250R12Ek9s+f+s&v z@}rQR2VYBHL(7kmsU(h#M=U@0|nj^iN5MW(#yIS$K* zJUNb%<2lIjk&(|H#ACVcT(le!Pss^T6?_{^h)k5|IRVSVJvo7r6NU8L^FXSH`q)T} zOd}yDVtKPCCsJ~fke=&aYnwvLNs;L!||H z`K6Ga!=LL?AR}kvC6>EcS?dU6^izk;gZ`|fne$UXQ9%en0XYqPwfm4ANz zdSK=&`Zkyq8F?1X!ty~+&Z6XOsLE_M9K-xS{BzXVk+F{u%{N%Gv0UzJe@zqwbG`4a ziHNXkQUrGCXF}_bMUsNdvXpnid+tIZYAep`LZYHQgR+t*~c+< zetOoNXI{Os-^nZLyvW$=UVm(PST1g!yR%Ck$mY47qV``lXJx!5RV;Lk{nsF`%6=dE zoM%34E1CU)S>`sM`5E7r_dXERLT-Jc=%!TnM9(M`jUJ znJ-w{48C5L`jLCNC^F`T$7l5-EPv(6MU-3&RsQ|Jp0R_>a|JPsA?4!8$m{uHEN}7T zVoH7$RT-(}h`C>@647J8oc#hyzcBOf=FWI1XHRhCrp zYp4p|gQby?J-^0s8&7^s$z@PwzF-Nz2g@RJ-6Z_|QHJFio?J%BuZPIt?}^GGBhS6B zv;3nczpmu+sPcP>yQ0V%y$35Oxjf5>zoF5VSMnRE3O+U}A~RFmQr=*>wI{!!@)pbGmQzn}DY=G&Toai|VxDWT+}D$9DEVzv1s@x=keMsw zw^_d8$!{yUc1X|RkBvIWEEaNYmXCi+vr${gbx{?3Y}7+0Dn|6NQJ3X?D@d-Z=kUiyGi2mEH)T1ed9BATO_lr}s)CP==E%sS?md=I zd-8iqZV}RR_+z6bGKIu!v|zc#YU;U#l3O{*t&x$>x3pq;p(nReavKM^Ei!VR+pzq= zliMiyeFwQ6GCzsgc%S8}=HAUN?<=`Is)CQY4#?yaa(k9{d2)Lte-P4h_@k~PGR1`a z0n2gBBNV%QpyW=dGDTRzUyF7|rlgQNvHX@NcT)0)Aw7pb>bfBFz--&UdiaoK`>4t; zA1b*ks)Faa8#3~!>&o(6PwuMZk3xD5KhNEf86;-oBbFPRXN>Lgk&=6$DtMlIBJ;bD zd$62l9mzeE{BcOn;pe#*GF65AG0R_h^2bWuGgWL}pdEeca z<@!I+Z1h!fe+PL0G6zM^{aOCellv?A6I7+34M%L>e{zVv${mPI)fmyo^Cv97v7Sml zQSu;E1s~6Yk&*XSgIJ#VBguo5{3)u;7cAkA=OM_*v*@QRm)$^>pDKAMs>~E(34h)g zhKxKmhO&IolZPt#GgO%`Si&FA!;z8qR-dulY$H{ErsNT*3hsF%GV*$31k1BLd4!Tb zN0s>!(DNu{E}DdYuKS$jgP#1kl1HN|xaTp*+!e?3XqIny@@OT0fhzMQpy#p3)EDv> zEPuL*D!)+jxDYw~BhB&1j27}ZmJfRJI3-U&RUEJ9Z_Yk4*YGjSzvQzJ6Ooax98F;P zhs{(vLCKRGdY+7oybVrb`J*i)Pg3#}RHgEIJ~8%{zPjhB$jE!EDJJ@o2*lJ!=0F=KVy*46RsJh1+XgPGqmRrVNfxuQp5>~0NM5hx4X6s9jg832d$bKKXW2{g1|@Go zm47saKWlA9ri_^9O)Ovc$y=4Y4OPKsfbGaEFaz_?0NYqjYVIlQvJJ9416Voq3_xq-8DIxwe_b|E9LJa@93@c@l$r;>N0DtKS)K_-_tes;6G&69U4c`vGh z_r*SB>{-j-7kgPQaFBZ5tM-MJL-z%(k^5plC`Sxc2kbr+8c6uf}x%Rl)n> zATn~s4zPU0lMg8Q5UPUr#c#+|57pBMwu~CzN~=Ri+&*;qSjrA=60Qf1PA`yCj|3s#R==n6um5x$R zr@PVzY=UqDsx zeeOkM(g^ti%jZv!d_l>VLV7+qy0Uq8)DR($$o^72Ut+o5DUvTK`ErQ7rDt>VT*Qm= z6(wJ0`IkRQzO3Y{A#&@}@0e$kUX=e<@>P~go+J6HlCMz}{WzjkWT~@SzK%?k*`R-H zTw^)bMJm0fd_&1MQ5AgNxP?q3(eq7~A9(UjCErF> z@HzZnWD<#prT2_r(Kb{%&%ZnL%&hlbUey-$5R0a1O1DOcZgP)6x<$ss^I`teG zE6N=IayDY3%Cv(e{QYSxWTFh_dofuqc7rNoDmk`8&vB4>5+hoU&2qe(B*#{AT!)_H zA#=-o^?Q!Xa=Ke2$5nECRQVO*&zT93vCn1sx%ez!zD;s`B_~8x@H{6%roCZ(IU&mv z?vR{N$%!3$PJ)bmyx_};S^ni7$%&Pm)S>5O$SgLjFDGSr@CGE;a}T& z37PHUmXe(1)8<|Jc1f<}6d`iUjKizyvsOwar(k*JBa%}nIaP=pzUP;bStEK*#d4F! zB&Skx>JT}6&uNsLn&p&FNKUQfw5SSxhVvC;?|vx z<>?W0TS%wm45$iz{UReWa-K7=yfKpG3`)-A(6hY)j~OXn6VJr*xELg7QgUX8p0gm+ zLL3{JS*~e5wAU_~m7LX~=WNI%67!su0}81${{z)7d<&QWO)^5<kh+E{}}74VGj1 zUr#QlYelDewk}I-2B?-wDm0UTb z=kU*Xys6~MEU&gVO|w*1autW3t0E(xJ*dL+p_fRmqU36*3O?7pg-kYak5-N4#3@Ox zrsV1@+cAZ|4c0(LK4(>(b%*Hm&XR0Ut5 z)ka1>mr{%6?P*D_rQ|xHJ%@d_MqOm486vhfwmK|tdxhjWO0MV7bA4ozi9J}4<)P_F zuBYS%sPf-$lQHu1OZqnW4l?q*(SYT~=}B&&7m6!O~!5TJspt3_Ilc%y*HwV%El{SVUu%M`fg*8!Nd9s{Gm5eEP8Y_C>iVGWOxU zFE?R%g(o*rax+x<5Ha!Z!Scydc6w+@jjBOQAF9GSDC=aDS8DMIo{ zC699Gc{DQe-f9%fCySCiO37m!dj0~L?V{%~EEg_D@)#wLb?A8 zdAvi<6OfT-{_!lAeU;?#N}h-+^99ScL6Q0OnST;8DMil{SzcU%T~dzT@3s*tF`Ubt{lOL&>v3u>3y_ho zPR?if&x$0^SMoxKp1(#$-clB_eAr&#m}Q}o7diC27?~f$9$duo>^DhXq~s+IJ%5AD z10gSAIYAYYmneCuL(j{Qxgu^UOIcoGpAs|6QY9~U==ob@;t6><%U@O_dAX8TILIrJ zk$Z3j%gw5jyh6#VP!$^^`hVAT-ytL4VY`auHZ@6JrR3EPJ+C2I%*JY#N4`z+Y9+6A z==pnOE*iog+gg^_)FyeYlGi!({DbOw9m{XjA$gsW*E{t5BQll5Gbig=?of~9^-A90 z(DO!QiivsN!1C<+ByUjiCR7DKU$+^V+CtvM^3``p-lXI$s0zMM`3V_$mAi%Iv5iUI zqU5a(J^zf1JR@yo`IskfRq{4e`S;zuhJWy_zPH+r%uv%@Z0{DejpbHNsON1;-Vq{~ zzp;3QmVZ(54wipuO7adR??hGbW7u6v-pO*F_ekEUBXfZ0u%vVsnyr zD|v5-9RAVqKGpMHmY=mCd9RZ9qsrcQ+a>%n+rJ{SM)bU&<@T*e-ml~XA#(UvmkuiV z0L!npCi#Gp524C@!4m!|_cvtZbEjC|GO z1k0;Bk$ghQCsE};OC0|9<4z$XpEEzn^103=pH%W`2l-EADmKl9{sO1|JAUqoi6==lQ6>AKTw zTu|~Q2l+2#N{XH@u{_3;FDdzQh&;YS-O~Ctcm)|b&zD*5+k<+(tmLbx^6z28zk={L zGV+$v0U3qZi3HlzbCa z{%nMQ4d@m!%M20Q8{18mOZ6rBrjl=?%0G*SKiB<>OeG=TW;ty?l5Z>d4yuCZ`7Sc@ zn*R>V&pi2#lJB7^_^RMPWTuIp@3FjW0QG!N$@fteJR1*`e4piOpOAcC$qz&1@K*(o zkeMWUe#mm3K_ov^@?%s5&+`*xmWku}G0PJNll)l8Pf-;-&(DyN*GNxU{(cC_PnG-} zRl)OY5964TQhv_zReOhEmgh>2M3paxpJ)4F;V~oSeM)3(vkFW4&q$7p9c5k%mGAqC ziK^gvwhhLN94F>ECd(fWCpo5)Z6u~`9836Td*UEdQarYb&GPV(B*#{ATvP?`!Fb5* zGKAkjT$ay&PI6o&$48Yv&*9G-36vb4<({KSj<4i|s0!{m5i%P^&k0$M_XWubm7Lh2 z=Oju_%<{ysBqvsKQiqwUX01$gdzHkGixh zfB7ZJX_cHVR1W(Nob<@76g{V7`PmGT(4ssMS_A<+S zgC!HoooA7pNy(W}75v&n7G(MhIWx=YXOo;+$yrh5pOL~pw#tT#Jo9H|x&IuJvnn|| zs{Gd`R<;>5RA1%hK*pZb%r{uFv;1r>$=Q{h6IJQGikSIJn~(G`cOD_{8p@^QoGiEb zisYP1&W$R+m+pD- zWPT9$u=!bTvXJEbN-l`1;PXZyWaO>8Aj>lrkz7#8g;C{SnTLOzQUn?K{6=AxOD!R} zu#$_SD)^RCOvy!AuJR4ZMU`9}RsQi@e`yA@GhaOFUPVTp`HQpMWEsiDm0SW<{_%YI z{MS>pTvEv;Snl~P$t9Fr3RUI{mhi{(YsefF$3`iZ$J&#tSxPCnG^+U62z!1mgG?bq z_#KpH`QR#&ODnmogZw%&c0zr*EXzf|Be|@S%Q?v9ktrkOaxBMRO>#LUS8$NuKt^7f zS75o5Cs$B%MO4MYUND~y6881(O33sUJy&Eo%NpvrqLM44DuE~WjI-y6KI+~?M&83# zW_gzhl9CcM#9=4WxuA<~>4n4nxjJ@+P-(ac6@}PAjS5tCzR0a23 z0~vW1tkv-n@O&x`a(kdg0WY{2rpEhINka>Ecg{ND^}gv=l@&kb3gvz6qAN^Xp*;NQu57n#LI_OH?! zvs`%_$&De)-^sFa=ly#@jf#0-E?hPUc8Uwwn}an zB8T4>?U9)#dTz&Zo?l6Br{oT(3f>nVAoG*h7adq$e1PN*YF}76bYIXKxi30G4&E1? zc_z)R+Ch5#_!^0$ZR&tjRIsCrpii~`Pr3=gZkC5C& z$=y&Dye~dNW`Woj-B>PnjO1==UsySGU(g!4FS*gCQ-FfTZ9jC2#SL5o5 zs^ER`F*5R!Tmw)Qye~dMM!q|10Lu^0 zkvu@j14HES`(h9>7sb99$nwq$Bo9>bU{nR~i%%&d_Qhb9$6q3Ou-X?^4&4{DM(&Ft zkc0QdP~N)v2FnoMdeh6a^&x6p!%!8xFFr#?zBgML*(%LVgxc#W?<$U zEW=qYW*=CaWw??@qAGY_e2z?2u`fol{Qf^Ak5v1@%Axy$*2sM^3Ucti7|mNZ-(VTV zTc2((qRlc&jcW|5g7?K2$jJAPjbZut9g@c=d2EOreqW43ro7k}V_DAsAIW2tJRViS z`(gqz?Zv(r&+@;YH{W2H$XoyI5p8{<8rNi01wTTZ zf{c8@pOHLS$x|KVX~@Xi#Z;Ep+ly$kOjYu92l-26nu@(Vo#h-cNuI9c84mJH zWaRr>X0Ti^4#_i=Jj+3zjg0*r5c3U|SuD4YPx34!&vB6FA~RIX#vGPo*e89>GDpet z9OSQ%vF{@_-(Z=?^0mYy&r|Yz2YCT9_BW4wc|Ob4l94=L$qOCiuSqsveR(0vlV2iv zp^_Il$cvG&&rbOAB9^SLB`(Mn{TkJW_eI%l2pM7e?EL)Vk)j|FlnPo!W%JNrv zNZzXCZ4UBwWb%polx-}(VW0Fh%QhwNaFBmNCZ&*fM9T$8-l6234zfLe#*C~je+MI~Qgxp66)jSEV?eyrrD4)QZ(o`~c5Da(I*@>3;0caY5! zXy&@kyqwRsl;|6a$E=5K1&cYQodFjm*s^ONRF%I z_zrRcWUh;zF4U*$4IU%Zo_h2HD#U4z^@}Ct+PN?L>4m~G9Mm}mw%<{ELBqvsK zQiq5=JV2!9WzW4S>slG7WmIq~y#Fau#IdnLjhj8R}EdnU$Q?LC%KETrnG2S$^G z@{tDAb9N=?bdYl)vrNc2S-$%Y$vKsr+dEj{n-x;h2xw#LU0CAlGQBk&iu#AY;!_{>&HV zng7L;3x~|S^{gB{^YwX++$FC0y|lyD%OKN9Y`rvZ z{fxKu(rW8g4&6Gfky|ed+22>;uX|rd=83pBFUwnR(2T}jR_)Vrs0uz-%Of++5dN%| zV|h?>lFNmR%X(Ih9+y2RU=BWO|FOSLChd_O@P8ZQaVDTcy<;c9{wElCNlDfs?1xT?`^%Z z+PalPw@z#1)~i4czKW}gOoSP`f8knSNOQT<@GGZdIuT#3U346`Xc)v!z>NdxEi9$A6L!~$6V0kYJ`mabsB$vHDq~E zXObJLaalQZT(m}xt1;x@alMPoKC>A=*O<57{X^P%V>PZOsPe}Z{`S=rnRtfq$JK=8 zC0$5vqQ+(A&~eckIj&}q{eHvmulJByEXLK0xBg#O+IllJuI8xnZ(q}r9y1rSHY=|N zTOcFP8_ijc`iSJ_A>*>1m7~XHZ(p=Vj;kf);BmD=#=eiy&$Z;Ox9m<^Z>h%B8ddh5 z)mGhTzjBoxR~uyPQ_ueXYR&Ss9wfI88JG2}96hdgc#RxaTgZOD;rG}3$jDd8+w#^& ze@t6%tH#w1Rl&z$dt~g3*8aHKv7Dqg$?ZbMWj!lLkIU{sS|i8R0dnxTK0v0o*k2uZ z>x=r();p+ibwpM0xH=(YpM3Gh)sf}#{YdVp#%1NuanTw%uFjBy$MqpHbH%ti^VTN} zpsjaS}M4@KspkcY6m_zRMUD0!HJ z{24N*gglJpj`qQ&S%xWjxPv?b8Top_aF+8-AbGfwM>@!#BO|X5N3wirBFQ6_Jjy{H zjm%v!8>3iGG==0*N*?1Ne}POQL-=Q;F)SCHM)DXXk9Cm8Arni;V_E+AOOnSbc|5B8 zdx!9kb0=`m{=MFKmes(FZ``fgi=g`(CtF2o(bnCQ6Zhfl5)~6w3j~0LHQ+ewb z>;pctOjTRAa_H7+jokWlhpm5!jJ(>J&RehY6>WXG+PalPw@z#1)@L|ueI_#H#n@-? z))OwEt!Dcuu)=ebh zZEubJKJ=Xi^Wns@KQPOL3ESG~Z7o11jX2ZJ=WTWOEc&3zfVGRsQGGhX3s1#mLBehea&k_2flLUg98sgN(d#Si7%;s37U8f4^E@;Zl}e?X>&n2mKT|KrK)l)T=d=O2-=uMYTo za6QYDR#VUGmAt{B=Z(n7$6p&*&a#H&4NBhR(DP;`Z({kTCvQ^n7F1>Qj*YdW-fgY- z;7`bm5VNs`<*93_=PgR!imEi8T;tSh<_!flD{m=3Bhz2VTUk!y6oU&wG%`CFI>K&;NmX-mT=lsPgXz!~ZSFeX8fZEbsH= zy-MC6B8UH5kiQ}`N%Xv*GgI_@oaLQAk$haqCmeeI1DPvAKEZOgtt6jN@<~($-%?H?Q%T4tS-!B1 zK{#`;mIqoHszrSCFyiXaD?indRA@d>OL*d@U>E(M>Ts z&$g1*$j1d&A)7B)!e3SXjm%jwuB*KDBD-i@SJk+#p~~ME-S17=sK<3($=6tZZ#T); zlzanK{v(d?e-Yy!WaJ}`8!T7eL-GwJ-$a%95-=OLkU1h|<0i`m_L6*4$+uAzJRAQi z`8Lb-_mO;C$#+l{JR5hBk!P(tESK0%@*O4LLzVdwFdP3NBj@=Z%jth5`JR&Rqbhhd z9w_-f%i|7^d|$~AQ58HJkC2g%>>jeb=pe}tmHZf0=1ahAJV8c2qxhKRpAM1ySjkUO z6+9cyl>C(C8iz@Ks^sUW3Z9LKxc0XIp61Dkm7LT;PKL}uAtz|lPfuegPanXCqhoaa=TL`r%-Y#RQZpR!v9wI%g7WHaw?Wb zoF+Myl2fB9_?D6e8T&+-e@jWt@*Pi3t>m;0@+-*Lm(YAUEz2*TrJmC&Ih})?9+_n3 zqSlwwv7GZf$?24w!9mW5%mdML29|eSBsqhUGdajn$P^PjXJWb8Ws)-~IkSVD1)2In z&dl-`f0LY9$yreq{QiV&$Xqe!7Jr_zvV8Lf$yt@09aX{4+vK30#qpe-<&^)BoL$K| z9eU1%jC^-!PL|*HmcVtCYG3uye$9f$$6EW-$5>b zjQmZU{4AHaN%Ndv$pszcLdc{SJr`v89ZxQ(z|5)(H-s!t* zxg;_v#XOf_Iqq%hxrCBSp(^;+{TebC#qnH<<*J@sO39^B zs0zNNyoJmp(Q`GHKmU*9YD%t-s^D8n4P>$jxjM_0?~`0z$u&_Gd`o#7nQ20<$?`={ zuBqf&4n5aKM$U6BmXFvA9JAC?avf9!@4>prJQ3%OIxKg8NOBz|*F#nC9;}Z{88I96 zSU%{<^_1Meq33syNhIV3ELV9%JvUHtLx-LlAtN6THe`9TCpT1bV^jqnb?+i0uL>Ho zT zd3g-F{kBzdI|sQvGV*$(9m_dllH5+o9USBjkdeo82bSk}at9@ML{;$d+zA;GYKFvlS zCHHgaxj!;z%?$f;Kb9XPB)OlG2ZZ#zVcV;n^&b2L8Tp%l16Y0~5y=CTJkX)%LCCZb z^E{B{{z*t4sN}&RJ%@jf$EU~?Gf$BDvoV$}pB+dWqy=N*?YYk3eRZkcYE8!IOt8c_gZWZz-R1&;C4*WI107 z>UpG+N1-bCmNFWdSaG8F;3$@7*pC!7%P1v}ap?IAWaf&aZVbymzfAHNC69IJc^oqK zGmZV(7|U|@G$fBz@_1AQpX(+dBOhswXZf{PNFJ}`iKq%bo+lw=&!XlVEE8Go=gAY5 zJQ-ENJx@WVlbGkpEN}JX$x5E;AWuW4hmfbT+&CT0##ALwM^*6g{3T_?)z@^EpLz0h zCC@;We>{gji_S!5t~evjV7W;~>UoBeXQ9dr6ib4M_SbFgHDG}@ZCmwhm#v;%JsTPM zsBIR@e`O|lmXhZ<$a9ftFXnj;%XPAlJV(j%9OSQ%DKF%CEO*UH@;oKacaRq#Q$xt} zSt4}@{^(@Z&30k2YE9x^3~E!ESD)x@+Kv3agcvP zM!s6Qh2=f3lDtL9TOH(|k&&;KZe_WK{R1*)*{bAi4)S(n>&oaSECGLO#iI;=ahT_Rl&1y5gGa1*9DgU ztVi+%C0{~S@NE2r%o@@2C6+5SAo-G#FQY1WHm)FZM97y}UiuEnmz8`KRl&3IH!>H+ zHPTg<%QPbSs*%)Ecb3s@@*yGK~>hkv*=x9?A^aF-(k5# zOOo#>`5vl*XX8I)9*Ehv$8uC_lJ6<`KB|Ie;{h`E@bY`U&+?mXNxrY-hp5ULI2(_U z=`G}kEO%~4@iH?lu{x3bRLRd#l{IiS zBFvCtMou$?KhMuuuKpp(&y^gBD*97a(pExbdVDvb4thwSx#YZKxRp(TxuE^?s%FWoaKgAR~|G+$?t-MRIN>=S7wIf~808U*_mD zQa)tTh@SJZe9n{eDmlM{TmTvQZkGHkw;N48=T~w;2e}Y3mBcktL6&cLazP~*c94r8 zBi}VtnB|sVP|t;xT+~4>hRj^ib5WL0j3v3Kl8ZaYuOhQi$i-QXJ%QxnN-p6bmqccP zI5tYK+;|enC6rtWRrYt2?LE=9t)H0}PEB(mueH5~%pfEC&r_FTIdTfgr6BvC?qxkI zM}O9k{cKfQBY*d;H00pl6EA~IHZiW!y!8>@)=R5#l|@xsvsL^1Lho9$7a3?&zx5r_yYcGgb86&)%Ad2z%XYmm6k{-5zD+ zUuq~%{g|KG}#paRf5vzY!6C+e>(}&>A_b72vcoKeJ=ccWuLby-(jj zro0$?1s?kc(@CzN#$FLsa_rGn7rm;AJoc_%k`q1lIcAL=J7wh9D?!d@e&&xoTFyR$ z#*U0hL_{nzYwSX6NpfX1_9|-Z(N$}_swzD8H)p*#_TFZV z9Xn;@*sH3sN6WEh)7X*0n8%wncA+(L?A1cX-tlo!b2nvYQ@(Eg7BW@E*sJl_GtD8n zni_j`HTLML8D3R&9((S&FOI#jS!2ge89DYEYV6VSIa6hR9D$7aZ$!ig^GK#Oa_lwX zv@#ic%-@+CFU)5|zl}_9G4`4~_Pd^3Q;oeAs^l>rT{ZM8>ZcZuJ;(eP$KJxMv16x< z9D8lZ@|cg7pO`B1;|OHTensh>U*!MA&>pdB`=P>msw-CM;STxMr!QQ za^yEOc4W}&XtTyHv__7-F`VGfP>$&I7OjxCw@%c9C3QTWeLYKly4 zalhPz<$0dmM9Ixi70267_|M;X4;gvQ-;Cu#%c!enN^b5Tw?O8g=(#z|?<^;|xsqEt z$gPl(k0x5O{PDLWw^VX#2e}P0PejkHS-!Y}~y-(E{{7bSNKk;C`= z5i;`mx^66&`<~=(O70#ahwr%uGIBP$vs`=~$=#LQGei#G^T){8>pFinda_*L2aq+jVbg*=DlWyeXLqvUy1 z<=v;`z1yLVJ~qBWW`Q`K=dqmlB+2uXJReoT^Sl6=V&bTq&+@0INS?3cg{bncpTmFF z(AUVw*MJtXe9Ds-DtS>z&*>jFoTz7GF*5l?&x=^@ahiHwq~s+IJ%58te<3end9Nog zQS#D|o@-v4d_woU44E22UdnQ_KdI-XN?z{J^S8)s6!LPG_j&SiC9eqSIs6%EB{K50 zwiPUYafW(cq2yH#J%5Lcd^E9&<;R}9O3AAolyT%J;}L z74lk^m!2bet&-O{^!x)dr-ZzY<=4)WyiUpMQDweh3IB@NkI2a5c|FTzE|9!l$r~Kx zjmR_-J#Sz+-$jx)D0!2Eycroe&zo32=E<9syv0HO37Hn6=PfLcxI{f~QSw#?`DZ0> zWx4!cByUynHV1h-GVMjr+gQHq$=j5?!$JN9nKnY+!Scq-)bkD{?{tuNAtUE`C(FIB zki1jLyB*{`$jI5)&2oXOB=1)8UQ`ADe#$;%hKkwP%ksaTyjRKl9pqn;87JiZEcgAJ zdfu<(0}k>*WCjWO0Lw|Pk$gbOhfrm{1e`a1LnfDy53xMOlMgBRu!DRAneswD%yQ=I z)bn8_A9awAArmF!qbwiuiM{mPdLbbAS15|POzNlACgZf z`J{t<3K{um;v~zrJ^7@PPov6z&OC35!wvP7%%8}}tAf)k|8> z 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%0A`y5L^zTQ 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

_5WCv{Q1Tv;aFgrr}jQ1B5DK4PXS_ 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

y7lMq$mO)I*wj&JpNUN2bfXvS~ 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 - -#include "logger.h" -#include "utils.h" - -CLogger* g_Logger; - -CLogger::CLogger( const char *szBaseDir ) -{ - memset( m_szDir, 0, sizeof( m_szDir ) ); - - const char *szLastSlash = strrchr( szBaseDir, '\\' ); - - memcpy( m_szDir, szBaseDir, szLastSlash - szBaseDir ); - - sprintf_s( m_szDir, MAX_PATH, "%s\\netlogs\\", m_szDir ); // build the netlogs dir - - CreateDirectoryA( m_szDir, NULL ); -} - - -void CLogger::LogConsole( const char *szFmt, ... ) -{ - va_list args; - va_start( args, szFmt ); - - int buffSize = _vscprintf( szFmt, args ) + 1; - - if ( buffSize == 0 ) - return; - - char *szBuff = new char[ buffSize ]; - memset( szBuff, 0, buffSize ); - - int len = vsprintf_s( szBuff, buffSize, szFmt, args ); - - szBuff[ buffSize - 1 ] = 0; - - HANDLE hOutput = GetStdHandle( STD_OUTPUT_HANDLE ); - - DWORD numWritten = 0; - WriteFile( hOutput, szBuff, len, &numWritten, NULL ); - - delete [] szBuff; -} - - -void CLogger::AppendFile( const char *szFileName, const char *szString, ... ) -{ - va_list args; - va_start( args, szString ); - - int buffSize = _vscprintf( szString, args ) + 1; - - if ( buffSize == 0 ) - return; - - char *szBuff = new char[ buffSize ]; - memset( szBuff, 0, buffSize ); - - int len = vsprintf_s( szBuff, buffSize, szString, args ); - - szBuff[ buffSize - 1 ] = 0; - - this->LogFileData( szFileName, (uint8 *)szBuff, len, true ); - - delete [] szBuff; -} - -void CLogger::LogFileData( const char *szFileName, const uint8 *pData, uint32 cubData, bool bAppend ) -{ - DWORD fileFlags = CREATE_ALWAYS; - - if ( bAppend ) - fileFlags = OPEN_ALWAYS; - - HANDLE hFile = CreateFileA( GetFileDir(szFileName), GENERIC_WRITE, FILE_SHARE_READ, NULL, fileFlags, FILE_ATTRIBUTE_NORMAL, NULL ); - - if ( bAppend ) - SetFilePointer( hFile, 0, NULL, FILE_END ); - - DWORD lNumBytes = 0; - WriteFile( hFile, pData, cubData, &lNumBytes, NULL ); - - CloseHandle( hFile ); -} - -void CLogger::CreateDir(const char *szDir) -{ - const char* szCreatePath = this->GetFileDir(szDir); - - DWORD dwAttribs = GetFileAttributes(szCreatePath); - - if ( dwAttribs == INVALID_FILE_ATTRIBUTES ) - CreateDirectory(szCreatePath, NULL); -} - -const char *CLogger::GetFileDir( const char *szFile ) -{ - static char szFilePath[ MAX_PATH ]; - memset( szFilePath, 0, sizeof( szFilePath ) ); - - sprintf_s( szFilePath, sizeof( szFilePath ), "%s\\%s", m_szDir, szFile ); - - return szFilePath; -} \ No newline at end of file diff --git a/Resources/NetHook/logger.h b/Resources/NetHook/logger.h deleted file mode 100644 index 44b230d4..00000000 --- a/Resources/NetHook/logger.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef LOGGER_H_ -#define LOGGER_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#include "steam/steamtypes.h" - -#define _WINSOCKAPI_ -#include - - - -class CLogger -{ - -public: - CLogger( const char *szBaseDir ); - - - void LogConsole( const char *szString, ... ); - - void AppendFile( const char *szFileName, const char *szString, ... ); - - void LogFileData( const char *szFileName, const uint8 *pData, uint32 cubData, bool bAppend = false ); - - void CreateDir( const char* szDir ); - - -private: - const char *GetFileDir( const char *szFile ); - -private: - char m_szDir[ MAX_PATH ]; - -}; - -extern CLogger* g_Logger; - -#endif // !LOGGER_H_ diff --git a/Resources/NetHook/mathlib/IceKey.H b/Resources/NetHook/mathlib/IceKey.H deleted file mode 100644 index 635482ab..00000000 --- a/Resources/NetHook/mathlib/IceKey.H +++ /dev/null @@ -1,62 +0,0 @@ -// Purpose: Header file for the C++ ICE encryption class. -// Taken from public domain code, as written by Matthew Kwan - July 1996 -// http://www.darkside.com.au/ice/ - -#ifndef _IceKey_H -#define _IceKey_H - -/* -The IceKey class is used for encrypting and decrypting 64-bit blocks of data -with the ICE (Information Concealment Engine) encryption algorithm. - -The constructor creates a new IceKey object that can be used to encrypt and decrypt data. -The level of encryption determines the size of the key, and hence its speed. -Level 0 uses the Thin-ICE variant, which is an 8-round cipher taking an 8-byte key. -This is the fastest option, and is generally considered to be at least as secure as DES, -although it is not yet certain whether it is as secure as its key size. - -For levels n greater than zero, a 16n-round cipher is used, taking 8n-byte keys. -Although not as fast as level 0, these are very very secure. - -Before an IceKey can be used to encrypt data, its key schedule must be set with the set() member function. -The length of the key required is determined by the level, as described above. - -The member functions encrypt() and decrypt() encrypt and decrypt respectively data -in blocks of eight chracters, using the specified key. - -Two functions keySize() and blockSize() are provided -which return the key and block size respectively, measured in bytes. -The key size is determined by the level, while the block size is always 8. - -The destructor zeroes out and frees up all memory associated with the key. -*/ - -class IceSubkey; - -class IceKey { - public: - IceKey (int n); - ~IceKey (); - - void set (const unsigned char *key); - - void encrypt (const unsigned char *plaintext, - unsigned char *ciphertext) const; - - void decrypt (const unsigned char *ciphertext, - unsigned char *plaintext) const; - - int keySize () const; - - int blockSize () const; - - private: - void scheduleBuild (unsigned short *k, int n, - const int *keyrot); - - int _size; - int _rounds; - IceSubkey *_keysched; -}; - -#endif diff --git a/Resources/NetHook/mathlib/amd3dx.h b/Resources/NetHook/mathlib/amd3dx.h deleted file mode 100644 index 1cff7e8e..00000000 --- a/Resources/NetHook/mathlib/amd3dx.h +++ /dev/null @@ -1,1187 +0,0 @@ -/****************************************************************************** - - Copyright (c) 1999 Advanced Micro Devices, Inc. - - LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED *AS IS* WITHOUT ANY - EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, - NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY - PARTICULAR PURPOSE. IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY - DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, - BUSINESS INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR - INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY - OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION - OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY - NOT APPLY TO YOU. - - AMD does not assume any responsibility for any errors which may appear in the - Materials nor any responsibility to support or update the Materials. AMD retains - the right to make changes to its test specifications at any time, without notice. - - NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any - further information, software, technical information, know-how, or show-how - available to you. - - So that all may benefit from your experience, please report any problems - or suggestions about this software to 3dsdk.support@amd.com - - AMD Developer Technologies, M/S 585 - Advanced Micro Devices, Inc. - 5900 E. Ben White Blvd. - Austin, TX 78741 - 3dsdk.support@amd.com - -******************************************************************************* - - AMD3DX.H - - MACRO FORMAT - ============ - This file contains inline assembly macros that - generate AMD-3D instructions in binary format. - Therefore, C or C++ programmer can use AMD-3D instructions - without any penalty in their C or C++ source code. - - The macro's name and format conventions are as follow: - - - 1. First argument of macro is a destination and - second argument is a source operand. - ex) _asm PFCMPEQ (mm3, mm4) - | | - dst src - - 2. The destination operand can be m0 to m7 only. - The source operand can be any one of the register - m0 to m7 or _eax, _ecx, _edx, _ebx, _esi, or _edi - that contains effective address. - ex) _asm PFRCP (MM7, MM6) - ex) _asm PFRCPIT2 (mm0, mm4) - ex) _asm PFMUL (mm3, _edi) - - 3. The prefetch(w) takes one src operand _eax, ecx, _edx, - _ebx, _esi, or _edi that contains effective address. - ex) _asm PREFETCH (_edi) - - For WATCOM C/C++ users, when using #pragma aux instead if - _asm, all macro names should be prefixed by a p_ or P_. - Macros should not be enclosed in quotes. - ex) p_pfrcp (MM7,MM6) - - NOTE: Not all instruction macros, nor all possible - combinations of operands have been explicitely - tested. If any errors are found, please report - them. - - EXAMPLE - ======= - Following program doesn't do anything but it shows you - how to use inline assembly AMD-3D instructions in C. - Note that this will only work in flat memory model which - segment registers cs, ds, ss and es point to the same - linear address space total less than 4GB. - - Used Microsoft VC++ 5.0 - - #include - #include "amd3d.h" - - void main () - { - float x = (float)1.25; - float y = (float)1.25; - float z, zz; - - _asm { - movd mm1, x - movd mm2, y - pfmul (mm1, mm2) - movd z, mm1 - femms - } - - printf ("value of z = %f\n", z); - - // - // Demonstration of using the memory instead of - // multimedia register - // - _asm { - movd mm3, x - lea esi, y // load effective address of y - pfmul (mm3, _esi) - movd zz, mm3 - femms - } - - printf ("value of zz = %f\n", zz); - } - - #pragma aux EXAMPLE with WATCOM C/C++ v11.x - =========================================== - - extern void Add(float *__Dest, float *__A, float *__B); - #pragma aux Add = \ - p_femms \ - "movd mm6,[esi]" \ - p_pfadd(mm6,_edi) \ - "movd [ebx],mm6" \ - p_femms \ - parm [ebx] [esi] [edi]; - -*******************************************************************************/ - -#ifndef _K3DMACROSINCLUDED_ -#define _K3DMACROSINCLUDED_ - -#if defined (__WATCOMC__) - -// The WATCOM C/C++ version of the 3DNow! macros. -// -// The older, compbined register style for WATCOM C/C++ macros is not -// supported. - -/* Operand defines for instructions two operands */ -#define _k3d_mm0_mm0 0xc0 -#define _k3d_mm0_mm1 0xc1 -#define _k3d_mm0_mm2 0xc2 -#define _k3d_mm0_mm3 0xc3 -#define _k3d_mm0_mm4 0xc4 -#define _k3d_mm0_mm5 0xc5 -#define _k3d_mm0_mm6 0xc6 -#define _k3d_mm0_mm7 0xc7 -#define _k3d_mm0_eax 0x00 -#define _k3d_mm0_ecx 0x01 -#define _k3d_mm0_edx 0x02 -#define _k3d_mm0_ebx 0x03 -#define _k3d_mm0_esi 0x06 -#define _k3d_mm0_edi 0x07 -#define _k3d_mm1_mm0 0xc8 -#define _k3d_mm1_mm1 0xc9 -#define _k3d_mm1_mm2 0xca -#define _k3d_mm1_mm3 0xcb -#define _k3d_mm1_mm4 0xcc -#define _k3d_mm1_mm5 0xcd -#define _k3d_mm1_mm6 0xce -#define _k3d_mm1_mm7 0xcf -#define _k3d_mm1_eax 0x08 -#define _k3d_mm1_ecx 0x09 -#define _k3d_mm1_edx 0x0a -#define _k3d_mm1_ebx 0x0b -#define _k3d_mm1_esi 0x0e -#define _k3d_mm1_edi 0x0f -#define _k3d_mm2_mm0 0xd0 -#define _k3d_mm2_mm1 0xd1 -#define _k3d_mm2_mm2 0xd2 -#define _k3d_mm2_mm3 0xd3 -#define _k3d_mm2_mm4 0xd4 -#define _k3d_mm2_mm5 0xd5 -#define _k3d_mm2_mm6 0xd6 -#define _k3d_mm2_mm7 0xd7 -#define _k3d_mm2_eax 0x10 -#define _k3d_mm2_ecx 0x11 -#define _k3d_mm2_edx 0x12 -#define _k3d_mm2_ebx 0x13 -#define _k3d_mm2_esi 0x16 -#define _k3d_mm2_edi 0x17 -#define _k3d_mm3_mm0 0xd8 -#define _k3d_mm3_mm1 0xd9 -#define _k3d_mm3_mm2 0xda -#define _k3d_mm3_mm3 0xdb -#define _k3d_mm3_mm4 0xdc -#define _k3d_mm3_mm5 0xdd -#define _k3d_mm3_mm6 0xde -#define _k3d_mm3_mm7 0xdf -#define _k3d_mm3_eax 0x18 -#define _k3d_mm3_ecx 0x19 -#define _k3d_mm3_edx 0x1a -#define _k3d_mm3_ebx 0x1b -#define _k3d_mm3_esi 0x1e -#define _k3d_mm3_edi 0x1f -#define _k3d_mm4_mm0 0xe0 -#define _k3d_mm4_mm1 0xe1 -#define _k3d_mm4_mm2 0xe2 -#define _k3d_mm4_mm3 0xe3 -#define _k3d_mm4_mm4 0xe4 -#define _k3d_mm4_mm5 0xe5 -#define _k3d_mm4_mm6 0xe6 -#define _k3d_mm4_mm7 0xe7 -#define _k3d_mm4_eax 0x20 -#define _k3d_mm4_ecx 0x21 -#define _k3d_mm4_edx 0x22 -#define _k3d_mm4_ebx 0x23 -#define _k3d_mm4_esi 0x26 -#define _k3d_mm4_edi 0x27 -#define _k3d_mm5_mm0 0xe8 -#define _k3d_mm5_mm1 0xe9 -#define _k3d_mm5_mm2 0xea -#define _k3d_mm5_mm3 0xeb -#define _k3d_mm5_mm4 0xec -#define _k3d_mm5_mm5 0xed -#define _k3d_mm5_mm6 0xee -#define _k3d_mm5_mm7 0xef -#define _k3d_mm5_eax 0x28 -#define _k3d_mm5_ecx 0x29 -#define _k3d_mm5_edx 0x2a -#define _k3d_mm5_ebx 0x2b -#define _k3d_mm5_esi 0x2e -#define _k3d_mm5_edi 0x2f -#define _k3d_mm6_mm0 0xf0 -#define _k3d_mm6_mm1 0xf1 -#define _k3d_mm6_mm2 0xf2 -#define _k3d_mm6_mm3 0xf3 -#define _k3d_mm6_mm4 0xf4 -#define _k3d_mm6_mm5 0xf5 -#define _k3d_mm6_mm6 0xf6 -#define _k3d_mm6_mm7 0xf7 -#define _k3d_mm6_eax 0x30 -#define _k3d_mm6_ecx 0x31 -#define _k3d_mm6_edx 0x32 -#define _k3d_mm6_ebx 0x33 -#define _k3d_mm6_esi 0x36 -#define _k3d_mm6_edi 0x37 -#define _k3d_mm7_mm0 0xf8 -#define _k3d_mm7_mm1 0xf9 -#define _k3d_mm7_mm2 0xfa -#define _k3d_mm7_mm3 0xfb -#define _k3d_mm7_mm4 0xfc -#define _k3d_mm7_mm5 0xfd -#define _k3d_mm7_mm6 0xfe -#define _k3d_mm7_mm7 0xff -#define _k3d_mm7_eax 0x38 -#define _k3d_mm7_ecx 0x39 -#define _k3d_mm7_edx 0x3a -#define _k3d_mm7_ebx 0x3b -#define _k3d_mm7_esi 0x3e -#define _k3d_mm7_edi 0x3f - -#define _k3d_name_xlat_m0 _mm0 -#define _k3d_name_xlat_m1 _mm1 -#define _k3d_name_xlat_m2 _mm2 -#define _k3d_name_xlat_m3 _mm3 -#define _k3d_name_xlat_m4 _mm4 -#define _k3d_name_xlat_m5 _mm5 -#define _k3d_name_xlat_m6 _mm6 -#define _k3d_name_xlat_m7 _mm7 -#define _k3d_name_xlat_M0 _mm0 -#define _k3d_name_xlat_M1 _mm1 -#define _k3d_name_xlat_M2 _mm2 -#define _k3d_name_xlat_M3 _mm3 -#define _k3d_name_xlat_M4 _mm4 -#define _k3d_name_xlat_M5 _mm5 -#define _k3d_name_xlat_M6 _mm6 -#define _k3d_name_xlat_M7 _mm7 -#define _k3d_name_xlat_mm0 _mm0 -#define _k3d_name_xlat_mm1 _mm1 -#define _k3d_name_xlat_mm2 _mm2 -#define _k3d_name_xlat_mm3 _mm3 -#define _k3d_name_xlat_mm4 _mm4 -#define _k3d_name_xlat_mm5 _mm5 -#define _k3d_name_xlat_mm6 _mm6 -#define _k3d_name_xlat_mm7 _mm7 -#define _k3d_name_xlat_MM0 _mm0 -#define _k3d_name_xlat_MM1 _mm1 -#define _k3d_name_xlat_MM2 _mm2 -#define _k3d_name_xlat_MM3 _mm3 -#define _k3d_name_xlat_MM4 _mm4 -#define _k3d_name_xlat_MM5 _mm5 -#define _k3d_name_xlat_MM6 _mm6 -#define _k3d_name_xlat_MM7 _mm7 -#define _k3d_name_xlat_eax _eax -#define _k3d_name_xlat_ebx _ebx -#define _k3d_name_xlat_ecx _ecx -#define _k3d_name_xlat_edx _edx -#define _k3d_name_xlat_esi _esi -#define _k3d_name_xlat_edi _edi -#define _k3d_name_xlat_ebp _ebp -#define _k3d_name_xlat_EAX _eax -#define _k3d_name_xlat_EBX _ebx -#define _k3d_name_xlat_ECX _ecx -#define _k3d_name_xlat_EDX _edx -#define _k3d_name_xlat_ESI _esi -#define _k3d_name_xlat_EDI _edi -#define _k3d_name_xlat_EBP _ebp -#define _k3d_name_xlat__eax _eax -#define _k3d_name_xlat__ebx _ebx -#define _k3d_name_xlat__ecx _ecx -#define _k3d_name_xlat__edx _edx -#define _k3d_name_xlat__esi _esi -#define _k3d_name_xlat__edi _edi -#define _k3d_name_xlat__ebp _ebp -#define _k3d_name_xlat__EAX _eax -#define _k3d_name_xlat__EBX _ebx -#define _k3d_name_xlat__ECX _ecx -#define _k3d_name_xlat__EDX _edx -#define _k3d_name_xlat__ESI _esi -#define _k3d_name_xlat__EDI _edi -#define _k3d_name_xlat__EBP _ebp - -#define _k3d_xglue3(a,b,c) a##b##c -#define _k3d_glue3(a,b,c) _k3d_xglue3(a,b,c) -#define _k3d_MODRM(dst, src) _k3d_glue3(_k3d,_k3d_name_xlat_##dst,_k3d_name_xlat_##src) - -/* Operand defines for prefetch and prefetchw */ - -#define _k3d_pref_eax 0x00 -#define _k3d_pref_ecx 0x01 -#define _k3d_pref_edx 0x02 -#define _k3d_pref_ebx 0x03 -#define _k3d_pref_esi 0x06 -#define _k3d_pref_edi 0x07 -#define _k3d_pref_EAX 0x00 -#define _k3d_pref_ECX 0x01 -#define _k3d_pref_EDX 0x02 -#define _k3d_pref_EBX 0x03 -#define _k3d_pref_ESI 0x06 -#define _k3d_pref_EDI 0x07 -#define _k3d_prefw_eax 0x08 -#define _k3d_prefw_ecx 0x09 -#define _k3d_prefw_edx 0x0A -#define _k3d_prefw_ebx 0x0B -#define _k3d_prefw_esi 0x0E -#define _k3d_prefw_edi 0x0F -#define _k3d_prefw_EAX 0x08 -#define _k3d_prefw_ECX 0x09 -#define _k3d_prefw_EDX 0x0A -#define _k3d_prefw_EBX 0x0B -#define _k3d_prefw_ESI 0x0E -#define _k3d_prefw_EDI 0x0F - -/* Defines for 3DNow! instructions */ -#define PF2ID(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x1d -#define PFACC(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xae -#define PFADD(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x9e -#define PFCMPEQ(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xb0 -#define PFCMPGE(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x90 -#define PFCMPGT(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xa0 -#define PFMAX(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xa4 -#define PFMIN(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x94 -#define PFMUL(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xb4 -#define PFRCP(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x96 -#define PFRCPIT1(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xa6 -#define PFRCPIT2(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xb6 -#define PFRSQRT(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x97 -#define PFRSQIT1(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xa7 -#define PFSUB(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x9a -#define PFSUBR(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xaa -#define PI2FD(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0x0d -#define FEMMS db 0x0f, 0x0e -#define PAVGUSB(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xbf -#define PMULHRW(dst, src) db 0x0f, 0x0f, _k3d_MODRM(dst, src), 0xb7 -#define PREFETCH(src) db 0x0f, 0x0d, _k3d_pref_##src -#define PREFETCHW(src) db 0x0f, 0x0d, _k3d_prefw_##src -#define CPUID db 0x0f, 0xa2 - -/* Defines for new, K7 opcodes */ -#define PFNACC(dst,src) db 0x0f, 0x0f, _k3d_MODRM(dst,src), 0x8a -#define FPPNACC(dst,src) db 0x0f, 0x0f, _k3d_MODRM(dst,src), 0x8e -#define PSWAPD(dst,src) db 0x0f, 0x0f, _k3d_MODRM(dst,src), 0xbb -#define PMINUB(dst,src) db 0x0f, 0xda, _k3d_MODRM(dst,src) -#define PMAXUB(dst,src) db 0x0f, 0xde, _k3d_MODRM(dst,src) -#define PMINSW(dst,src) db 0x0f, 0xea, _k3d_MODRM(dst,src) -#define PMAXSW(dst,src) db 0x0f, 0xee, _k3d_MODRM(dst,src) -#define PMULHUW(dst,src) db 0x0f, 0xe4, _k3d_MODRM(dst,src) -#define PAVGB(dst,src) db 0x0f, 0xe0, _k3d_MODRM(dst,src) -#define PAVGW(dst,src) db 0x0f, 0xe3, _k3d_MODRM(dst,src) -#define PSADBW(dst,src) db 0x0f, 0xf6, _k3d_MODRM(dst,src) -#define PMOVMSKB(dst,src) db 0x0f, 0xd7, _k3d_MODRM(dst,src) -#define PMASKMOVQ(dst,src) db 0x0f, 0xf7, _k3d_MODRM(dst,src) -#define PINSRW(dst,src,msk) db 0x0f, 0xc4, _k3d_MODRM(dst,src), msk -#define PEXTRW(dst,src,msk) db 0x0f, 0xc5, _k3d_MODRM(dst,src), msk -#define PSHUFW(dst,src,msk) db 0x0f, 0x70, _k3d_MODRM(dst,src), msk -#define MOVNTQ(dst,src) db 0x0f, 0xe7, _k3d_MODRM(src,dst) -#define SFENCE db 0x0f, 0xae, 0xf8 - -/* Memory/offset versions of the opcodes */ -#define PF2IDM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x1d -#define PFACCM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xae -#define PFADDM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x9e -#define PFCMPEQM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xb0 -#define PFCMPGEM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x90 -#define PFCMPGTM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xa0 -#define PFMAXM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xa4 -#define PFMINM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x94 -#define PFMULM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xb4 -#define PFRCPM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x96 -#define PFRCPIT1M(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xa6 -#define PFRCPIT2M(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xb6 -#define PFRSQRTM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x97 -#define PFRSQIT1M(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xa7 -#define PFSUBM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x9a -#define PFSUBRM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xaa -#define PI2FDM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x0d -#define PAVGUSBM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xbf -#define PMULHRWM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xb7 - - -/* Memory/offset versions of the new, K7 opcodes */ -#define PFNACCM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x8a -#define FPPNACCM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0x8e -#define PSWAPDM(dst,src,off) db 0x0f, 0x0f, _k3d_MODRM(dst,src) | 0x40, off, 0xbb -#define PMINUBM(dst,src,off) db 0x0f, 0xda, _k3d_MODRM(dst,src) | 0x40, off -#define PMAXUBM(dst,src,off) db 0x0f, 0xde, _k3d_MODRM(dst,src) | 0x40, off -#define PMINSWM(dst,src,off) db 0x0f, 0xea, _k3d_MODRM(dst,src) | 0x40, off -#define PMAXSWM(dst,src,off) db 0x0f, 0xee, _k3d_MODRM(dst,src) | 0x40, off -#define PMULHUWM(dst,src,off) db 0x0f, 0xe4, _k3d_MODRM(dst,src) | 0x40, off -#define PAVGBM(dst,src,off) db 0x0f, 0xe0, _k3d_MODRM(dst,src) | 0x40, off -#define PAVGWM(dst,src,off) db 0x0f, 0xe3, _k3d_MODRM(dst,src) | 0x40, off -#define PSADBWM(dst,src,off) db 0x0f, 0xf6, _k3d_MODRM(dst,src) | 0x40, off -#define PMOVMSKBM(dst,src,off) db 0x0f, 0xd7, _k3d_MODRM(dst,src) | 0x40, off -#define PMASKMOVQM(dst,src,off) db 0x0f, 0xf7, _k3d_MODRM(dst,src) | 0x40, off -#define MOVNTQM(dst,src,off) db 0x0f, 0xe7, _k3d_MODRM(src,dst) | 0x40, off -#define PINSRWM(dst,src,off,msk) db 0x0f, 0xc4, _k3d_MODRM(dst,src) | 0x40, off, msk -#define PSHUFWM(dst,src,off,msk) db 0x0f, 0x70, _k3d_MODRM(dst,src) | 0x40, off, msk - - -/* Defines for 3DNow! instructions for use in pragmas */ -#define p_pf2id(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x1d -#define p_pfacc(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xae -#define p_pfadd(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x9e -#define p_pfcmpeq(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xb0 -#define p_pfcmpge(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x90 -#define p_pfcmpgt(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xa0 -#define p_pfmax(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xa4 -#define p_pfmin(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x94 -#define p_pfmul(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xb4 -#define p_pfrcp(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x96 -#define p_pfrcpit1(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xa6 -#define p_pfrcpit2(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xb6 -#define p_pfrsqrt(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x97 -#define p_pfrsqit1(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xa7 -#define p_pfsub(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x9a -#define p_pfsubr(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xaa -#define p_pi2fd(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0x0d -#define p_femms 0x0f 0x0e -#define p_pavgusb(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xbf -#define p_pmulhrw(dst,src) 0x0f 0x0f _k3d_MODRM(dst,src) 0xb7 -#define p_prefetch(src) 0x0f 0x0d _k3d_pref_##src -#define p_prefetchw(src) 0x0f 0x0d _k3d_prefw_##src -#define P_PFNACC(dst,src) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x8a -#define P_FPPNACC(dst,src) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x8e -#define P_PSWAPD(dst,src) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xbb -#define P_PMINUB(dst,src) 0x0f 0xda (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMAXUB(dst,src) 0x0f 0xde (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMINSW(dst,src) 0x0f 0xea (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMAXSW(dst,src) 0x0f 0xee (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMULHUW(dst,src) 0x0f 0xe4 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PAVGB(dst,src) 0x0f 0xe0 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PAVGW(dst,src) 0x0f 0xe3 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PSADBW(dst,src) 0x0f 0xf6 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMOVMSKB(dst,src) 0x0f 0xd7 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMASKMOVQ(dst,src) 0x0f 0xf7 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PINSRW(dst,src,msk) 0x0f 0xc4 (_k3d_MODRM(dst,src) | 0x40) off msk -#define P_PEXTRW(dst,src,msk) 0x0f 0xc5 (_k3d_MODRM(dst,src) | 0x40) off msk -#define P_PSHUFW(dst,src,msk) 0x0f 0x70 (_k3d_MODRM(dst,src) | 0x40) off msk -#define P_MOVNTQ(dst,src) 0x0f 0xe7 (_k3d_MODRM(src,dst) | 0x40) off - -#define P_PF2IDM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x1d -#define P_PFACCM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xae -#define P_PFADDM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x9e -#define P_PFCMPEQM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xb0 -#define P_PFCMPGEM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x90 -#define P_PFCMPGTM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xa0 -#define P_PFMAXM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xa4 -#define P_PFMINM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x94 -#define P_PFMULM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xb4 -#define P_PFRCPM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x96 -#define P_PFRCPIT1M(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xa6 -#define P_PFRCPIT2M(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xb6 -#define P_PFRSQRTM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x97 -#define P_PFRSQIT1M(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xa7 -#define P_PFSUBM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x9a -#define P_PFSUBRM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xaa -#define P_PI2FDM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x0d -#define P_PAVGUSBM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xbf -#define P_PMULHRWM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xb7 -#define P_PFNACCM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x8a -#define P_FPPNACCM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0x8e -#define P_PSWAPDM(dst,src,off) 0x0f 0x0f (_k3d_MODRM(dst,src) | 0x40) off 0xbb -#define P_PMINUBM(dst,src,off) 0x0f 0xda (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMAXUBM(dst,src,off) 0x0f 0xde (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMINSWM(dst,src,off) 0x0f 0xea (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMAXSWM(dst,src,off) 0x0f 0xee (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMULHUWM(dst,src,off) 0x0f 0xe4 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PAVGBM(dst,src,off) 0x0f 0xe0 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PAVGWM(dst,src,off) 0x0f 0xe3 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PSADBWM(dst,src,off) 0x0f 0xf6 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PMOVMSKBM(dst,src,off) 0x0f 0xd7 (_k3d_MODRM(dst,src) | 0x40) off -#define P_MOVNTQM(dst,src,off) 0x0f 0xe7 (_k3d_MODRM(src,dst) | 0x40) off -#define P_PMASKMOVQM(dst,src,off) 0x0f 0xf7 (_k3d_MODRM(dst,src) | 0x40) off -#define P_PINSRWM(dst,src,off,msk) 0x0f 0xc4 (_k3d_MODRM(dst,src) | 0x40) off msk -#define P_PSHUFWM(dst,src,off,msk) 0x0f 0x70 (_k3d_MODRM(dst,src) | 0x40) off msk - - -#define P_PF2ID(dst,src) p_pf2id(dst,src) -#define P_PFACC(dst,src) p_pfacc(dst,src) -#define P_PFADD(dst,src) p_pfadd(dst,src) -#define P_PFCMPEQ(dst,src) p_pfcmpeq(dst,src) -#define P_PFCMPGE(dst,src) p_pfcmpge(dst,src) -#define P_PFCMPGT(dst,src) p_pfcmpgt(dst,src) -#define P_PFMAX(dst,src) p_pfmax(dst,src) -#define P_PFMIN(dst,src) p_pfmin(dst,src) -#define P_PFMUL(dst,src) p_pfmul(dst,src) -#define P_PFRCP(dst,src) p_pfrcp(dst,src) -#define P_PFRCPIT1(dst,src) p_pfrcpit1(dst,src) -#define P_PFRCPIT2(dst,src) p_pfrcpit2(dst,src) -#define P_PFRSQRT(dst,src) p_pfrsqrt(dst,src) -#define P_PFRSQIT1(dst,src) p_pfrsqit1(dst,src) -#define P_PFSUB(dst,src) p_pfsub(dst,src) -#define P_PFSUBR(dst,src) p_pfsubr(dst,src) -#define P_PI2FD(dst,src) p_pi2fd(dst,src) -#define P_FEMMS p_femms -#define P_PAVGUSB(dst,src) p_pavgusb(dst,src) -#define P_PMULHRW(dst,src) p_pmulhrw(dst,src) -#define P_PREFETCH(src) p_prefetch(src) -#define P_PREFETCHW(src) p_prefetchw(src) -#define p_CPUID 0x0f 0xa2 -#define p_pf2idm(dst,src,off) P_PF2IDM(dst,src,off) -#define p_pfaccm(dst,src,off) P_PFACCM(dst,src,off) -#define p_pfaddm(dst,src,off) P_PFADDM(dst,src,off) -#define p_pfcmpeqm(dst,src,off) P_PFCMPEQM(dst,src,off) -#define p_pfcmpgem(dst,src,off) P_PFCMPGEM(dst,src,off) -#define p_pfcmpgtm(dst,src,off) P_PFCMPGTM(dst,src,off) -#define p_pfmaxm(dst,src,off) P_PFMAXM(dst,src,off) -#define p_pfminm(dst,src,off) P_PFMINM(dst,src,off) -#define p_pfmulm(dst,src,off) P_PFMULM(dst,src,off) -#define p_pfrcpm(dst,src,off) P_PFRCPM(dst,src,off) -#define p_pfrcpit1m(dst,src,off) P_PFRCPIT1M(dst,src,off) -#define p_pfrcpit2m(dst,src,off) P_PFRCPIT2M(dst,src,off) -#define p_pfrsqrtm(dst,src,off) P_PFRSQRTM(dst,src,off) -#define p_pfrsqit1m(dst,src,off) P_PFRSQIT1M(dst,src,off) -#define p_pfsubm(dst,src,off) P_PFSUBM(dst,src,off) -#define p_pfsubrm(dst,src,off) P_PFSUBRM(dst,src,off) -#define p_pi2fdm(dst,src,off) P_PI2FDM(dst,src,off) -#define p_pavgusbm(dst,src,off) P_PAVGUSBM(dst,src,off) -#define p_pmulhrwm(dst,src,off) P_PMULHRWM(dst,src,off) - -#define P_PFNACC(dst,src) p_pfnacc(dst,src) -#define P_FPPNACC(dst,src) p_pfpnacc(dst,src) -#define P_PSWAPD(dst,src) p_pswapd(dst,src) -#define P_PMINUB(dst,src) p_pminub(dst,src) -#define P_PMAXUB(dst,src) p_pmaxub(dst,src) -#define P_PMINSW(dst,src) p_pminsw(dst,src) -#define P_PMAXSW(dst,src) p_pmaxsw(dst,src) -#define P_PMULHUW(dst,src) p_pmulhuw(dst,src) -#define P_PAVGB(dst,src) p_pavgb(dst,src) -#define P_PAVGW(dst,src) p_avgw(dst,src) -#define P_PSADBW(dst,src) p_psadbw(dst,src) -#define P_PMOVMSKB(dst,src) p_pmovmskb(dst,src) -#define P_PMASKMOVQ(dst,src) p_pmaskmovq(dst,src) -#define P_PINSRW(dst,src,msk) p_pinsrw(dst,src) -#define P_PEXTRW(dst,src,msk) p_pextrw(dst,src) -#define P_PSHUFW(dst,src,msk) p_pshufw(dst,src) -#define P_MOVNTQ(dst,src) p_movntq(dst,src) - -#define P_PFNACCM(dst,src,off) p_pfnaccm(dst,src,off) -#define P_FPPNACCM(dst,src,off) p_pfpnaccm(dst,src,off) -#define P_PSWAPDM(dst,src,off) p_pswapdm(dst,src,off) -#define P_PMINUBM(dst,src,off) p_pminubm(dst,src,off) -#define P_PMAXUBM(dst,src,off) p_pmaxubm(dst,src,off) -#define P_PMINSWM(dst,src,off) p_pminswm(dst,src,off) -#define P_PMAXSWM(dst,src,off) p_pmaxswm(dst,src,off) -#define P_PMULHUWM(dst,src,off) p_pmulhuwm(dst,src,off) -#define P_PAVGBM(dst,src,off) p_pavgbm(dst,src,off) -#define P_PAVGWM(dst,src,off) p_avgwm(dst,src,off) -#define P_PSADBWM(dst,src,off) p_psadbwm(dst,src,off) -#define P_PMOVMSKBM(dst,src,off) p_pmovmskbm(dst,src,off) -#define P_PMASKMOVQM(dst,src,off) p_pmaskmovqm(dst,src,off) -#define P_PINSRWM(dst,src,off,msk) p_pinsrwm(dst,src,off,msk) -#define P_PSHUFWM(dst,src,off,msk) p_pshufwm(dst,src,off,msk) -#define P_MOVNTQM(dst,src,off) p_movntqm(dst,src,off) - -#elif defined (_MSC_VER) && !defined (__MWERKS__) -// The Microsoft Visual C++ version of the 3DNow! macros. - -// Stop the "no EMMS" warning, since it doesn't detect FEMMS properly -#pragma warning(disable:4799) - -// Defines for operands. -#define _K3D_MM0 0xc0 -#define _K3D_MM1 0xc1 -#define _K3D_MM2 0xc2 -#define _K3D_MM3 0xc3 -#define _K3D_MM4 0xc4 -#define _K3D_MM5 0xc5 -#define _K3D_MM6 0xc6 -#define _K3D_MM7 0xc7 -#define _K3D_mm0 0xc0 -#define _K3D_mm1 0xc1 -#define _K3D_mm2 0xc2 -#define _K3D_mm3 0xc3 -#define _K3D_mm4 0xc4 -#define _K3D_mm5 0xc5 -#define _K3D_mm6 0xc6 -#define _K3D_mm7 0xc7 -#define _K3D_EAX 0x00 -#define _K3D_ECX 0x01 -#define _K3D_EDX 0x02 -#define _K3D_EBX 0x03 -#define _K3D_ESI 0x06 -#define _K3D_EDI 0x07 -#define _K3D_eax 0x00 -#define _K3D_ecx 0x01 -#define _K3D_edx 0x02 -#define _K3D_ebx 0x03 -#define _K3D_esi 0x06 -#define _K3D_edi 0x07 - -// These defines are for compatibility with the previous version of the header file. -#define _K3D_M0 0xc0 -#define _K3D_M1 0xc1 -#define _K3D_M2 0xc2 -#define _K3D_M3 0xc3 -#define _K3D_M4 0xc4 -#define _K3D_M5 0xc5 -#define _K3D_M6 0xc6 -#define _K3D_M7 0xc7 -#define _K3D_m0 0xc0 -#define _K3D_m1 0xc1 -#define _K3D_m2 0xc2 -#define _K3D_m3 0xc3 -#define _K3D_m4 0xc4 -#define _K3D_m5 0xc5 -#define _K3D_m6 0xc6 -#define _K3D_m7 0xc7 -#define _K3D__EAX 0x00 -#define _K3D__ECX 0x01 -#define _K3D__EDX 0x02 -#define _K3D__EBX 0x03 -#define _K3D__ESI 0x06 -#define _K3D__EDI 0x07 -#define _K3D__eax 0x00 -#define _K3D__ecx 0x01 -#define _K3D__edx 0x02 -#define _K3D__ebx 0x03 -#define _K3D__esi 0x06 -#define _K3D__edi 0x07 - -// General 3DNow! instruction format that is supported by -// these macros. Note that only the most basic form of memory -// operands are supported by these macros. - -#define InjK3DOps(dst,src,inst) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0f \ - _asm _emit ((_K3D_##dst & 0x3f) << 3) | _K3D_##src \ - _asm _emit _3DNowOpcode##inst \ -} - -#define InjK3DMOps(dst,src,off,inst) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0f \ - _asm _emit (((_K3D_##dst & 0x3f) << 3) | _K3D_##src | 0x40) \ - _asm _emit off \ - _asm _emit _3DNowOpcode##inst \ -} - -#define InjMMXOps(dst,src,inst) \ -{ \ - _asm _emit 0x0f \ - _asm _emit _3DNowOpcode##inst \ - _asm _emit ((_K3D_##dst & 0x3f) << 3) | _K3D_##src \ -} - -#define InjMMXMOps(dst,src,off,inst) \ -{ \ - _asm _emit 0x0f \ - _asm _emit _3DNowOpcode##inst \ - _asm _emit (((_K3D_##dst & 0x3f) << 3) | _K3D_##src | 0x40) \ - _asm _emit off \ -} - -#define _3DNowOpcodePF2ID 0x1d -#define _3DNowOpcodePFACC 0xae -#define _3DNowOpcodePFADD 0x9e -#define _3DNowOpcodePFCMPEQ 0xb0 -#define _3DNowOpcodePFCMPGE 0x90 -#define _3DNowOpcodePFCMPGT 0xa0 -#define _3DNowOpcodePFMAX 0xa4 -#define _3DNowOpcodePFMIN 0x94 -#define _3DNowOpcodePFMUL 0xb4 -#define _3DNowOpcodePFRCP 0x96 -#define _3DNowOpcodePFRCPIT1 0xa6 -#define _3DNowOpcodePFRCPIT2 0xb6 -#define _3DNowOpcodePFRSQRT 0x97 -#define _3DNowOpcodePFRSQIT1 0xa7 -#define _3DNowOpcodePFSUB 0x9a -#define _3DNowOpcodePFSUBR 0xaa -#define _3DNowOpcodePI2FD 0x0d -#define _3DNowOpcodePAVGUSB 0xbf -#define _3DNowOpcodePMULHRW 0xb7 -#define _3DNowOpcodePFNACC 0x8a -#define _3DNowOpcodeFPPNACC 0x8e -#define _3DNowOpcodePSWAPD 0xbb -#define _3DNowOpcodePMINUB 0xda -#define _3DNowOpcodePMAXUB 0xde -#define _3DNowOpcodePMINSW 0xea -#define _3DNowOpcodePMAXSW 0xee -#define _3DNowOpcodePMULHUW 0xe4 -#define _3DNowOpcodePAVGB 0xe0 -#define _3DNowOpcodePAVGW 0xe3 -#define _3DNowOpcodePSADBW 0xf6 -#define _3DNowOpcodePMOVMSKB 0xd7 -#define _3DNowOpcodePMASKMOVQ 0xf7 -#define _3DNowOpcodePINSRW 0xc4 -#define _3DNowOpcodePEXTRW 0xc5 -#define _3DNowOpcodePSHUFW 0x70 -#define _3DNowOpcodeMOVNTQ 0xe7 -#define _3DNowOpcodePREFETCHT 0x18 - - -#define PF2ID(dst,src) InjK3DOps(dst, src, PF2ID) -#define PFACC(dst,src) InjK3DOps(dst, src, PFACC) -#define PFADD(dst,src) InjK3DOps(dst, src, PFADD) -#define PFCMPEQ(dst,src) InjK3DOps(dst, src, PFCMPEQ) -#define PFCMPGE(dst,src) InjK3DOps(dst, src, PFCMPGE) -#define PFCMPGT(dst,src) InjK3DOps(dst, src, PFCMPGT) -#define PFMAX(dst,src) InjK3DOps(dst, src, PFMAX) -#define PFMIN(dst,src) InjK3DOps(dst, src, PFMIN) -#define PFMUL(dst,src) InjK3DOps(dst, src, PFMUL) -#define PFRCP(dst,src) InjK3DOps(dst, src, PFRCP) -#define PFRCPIT1(dst,src) InjK3DOps(dst, src, PFRCPIT1) -#define PFRCPIT2(dst,src) InjK3DOps(dst, src, PFRCPIT2) -#define PFRSQRT(dst,src) InjK3DOps(dst, src, PFRSQRT) -#define PFRSQIT1(dst,src) InjK3DOps(dst, src, PFRSQIT1) -#define PFSUB(dst,src) InjK3DOps(dst, src, PFSUB) -#define PFSUBR(dst,src) InjK3DOps(dst, src, PFSUBR) -#define PI2FD(dst,src) InjK3DOps(dst, src, PI2FD) -#define PAVGUSB(dst,src) InjK3DOps(dst, src, PAVGUSB) -#define PMULHRW(dst,src) InjK3DOps(dst, src, PMULHRW) - -#define FEMMS \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0e \ -} - -#define PREFETCH(src) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit (_K3D_##src & 0x07) \ -} - -/* Prefetch with a short offset, < 127 or > -127 - Carefull! Doesn't check for your offset being - in range. */ - -#define PREFETCHM(src,off) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit (0x40 | (_K3D_##src & 0x07)) \ - _asm _emit off \ -} - -/* Prefetch with a long offset */ - -#define PREFETCHMLONG(src,off) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit (0x80 | (_K3D_##src & 0x07)) \ - _asm _emit (off & 0x000000ff) \ - _asm _emit (off & 0x0000ff00) >> 8 \ - _asm _emit (off & 0x00ff0000) >> 16 \ - _asm _emit (off & 0xff000000) >> 24 \ -} - -#define PREFETCHW(src) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit (0x08 | (_K3D_##src & 0x07)) \ -} - -#define PREFETCHWM(src,off) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit 0x48 | (_K3D_##src & 0x07) \ - _asm _emit off \ -} - -#define PREFETCHWMLONG(src,off) \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0x0d \ - _asm _emit 0x88 | (_K3D_##src & 0x07) \ - _asm _emit (off & 0x000000ff) \ - _asm _emit (off & 0x0000ff00) >> 8 \ - _asm _emit (off & 0x00ff0000) >> 16 \ - _asm _emit (off & 0xff000000) >> 24 \ -} - -#define CPUID \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0xa2 \ -} - - -/* Defines for new, K7 opcodes */ -#define SFENCE \ -{ \ - _asm _emit 0x0f \ - _asm _emit 0xae \ - _asm _emit 0xf8 \ -} - -#define PFNACC(dst,src) InjK3DOps(dst,src,PFNACC) -#define PFPNACC(dst,src) InjK3DOps(dst,src,PFPNACC) -#define PSWAPD(dst,src) InjK3DOps(dst,src,PSWAPD) -#define PMINUB(dst,src) InjMMXOps(dst,src,PMINUB) -#define PMAXUB(dst,src) InjMMXOps(dst,src,PMAXUB) -#define PMINSW(dst,src) InjMMXOps(dst,src,PMINSW) -#define PMAXSW(dst,src) InjMMXOps(dst,src,PMAXSW) -#define PMULHUW(dst,src) InjMMXOps(dst,src,PMULHUW) -#define PAVGB(dst,src) InjMMXOps(dst,src,PAVGB) -#define PAVGW(dst,src) InjMMXOps(dst,src,PAVGW) -#define PSADBW(dst,src) InjMMXOps(dst,src,PSADBW) -#define PMOVMSKB(dst,src) InjMMXOps(dst,src,PMOVMSKB) -#define PMASKMOVQ(dst,src) InjMMXOps(dst,src,PMASKMOVQ) -#define PINSRW(dst,src,msk) InjMMXOps(dst,src,PINSRW) _asm _emit msk -#define PEXTRW(dst,src,msk) InjMMXOps(dst,src,PEXTRW) _asm _emit msk -#define PSHUFW(dst,src,msk) InjMMXOps(dst,src,PSHUFW) _asm _emit msk -#define MOVNTQ(dst,src) InjMMXOps(src,dst,MOVNTQ) -#define PREFETCHNTA(mem) InjMMXOps(mm0,mem,PREFETCHT) -#define PREFETCHT0(mem) InjMMXOps(mm1,mem,PREFETCHT) -#define PREFETCHT1(mem) InjMMXOps(mm2,mem,PREFETCHT) -#define PREFETCHT2(mem) InjMMXOps(mm3,mem,PREFETCHT) - - -/* Memory/offset versions of the opcodes */ -#define PAVGUSBM(dst,src,off) InjK3DMOps(dst,src,off,PAVGUSB) -#define PF2IDM(dst,src,off) InjK3DMOps(dst,src,off,PF2ID) -#define PFACCM(dst,src,off) InjK3DMOps(dst,src,off,PFACC) -#define PFADDM(dst,src,off) InjK3DMOps(dst,src,off,PFADD) -#define PFCMPEQM(dst,src,off) InjK3DMOps(dst,src,off,PFCMPEQ) -#define PFCMPGEM(dst,src,off) InjK3DMOps(dst,src,off,PFCMPGE) -#define PFCMPGTM(dst,src,off) InjK3DMOps(dst,src,off,PFCMPGT) -#define PFMAXM(dst,src,off) InjK3DMOps(dst,src,off,PFMAX) -#define PFMINM(dst,src,off) InjK3DMOps(dst,src,off,PFMIN) -#define PFMULM(dst,src,off) InjK3DMOps(dst,src,off,PFMUL) -#define PFRCPM(dst,src,off) InjK3DMOps(dst,src,off,PFRCP) -#define PFRCPIT1M(dst,src,off) InjK3DMOps(dst,src,off,PFRCPIT1) -#define PFRCPIT2M(dst,src,off) InjK3DMOps(dst,src,off,PFRCPIT2) -#define PFRSQRTM(dst,src,off) InjK3DMOps(dst,src,off,PFRSQRT) -#define PFRSQIT1M(dst,src,off) InjK3DMOps(dst,src,off,PFRSQIT1) -#define PFSUBM(dst,src,off) InjK3DMOps(dst,src,off,PFSUB) -#define PFSUBRM(dst,src,off) InjK3DMOps(dst,src,off,PFSUBR) -#define PI2FDM(dst,src,off) InjK3DMOps(dst,src,off,PI2FD) -#define PMULHRWM(dst,src,off) InjK3DMOps(dst,src,off,PMULHRW) - - -/* Memory/offset versions of the K7 opcodes */ -#define PFNACCM(dst,src,off) InjK3DMOps(dst,src,off,PFNACC) -#define PFPNACCM(dst,src,off) InjK3DMOps(dst,src,off,PFPNACC) -#define PSWAPDM(dst,src,off) InjK3DMOps(dst,src,off,PSWAPD) -#define PMINUBM(dst,src,off) InjMMXMOps(dst,src,off,PMINUB) -#define PMAXUBM(dst,src,off) InjMMXMOps(dst,src,off,PMAXUB) -#define PMINSWM(dst,src,off) InjMMXMOps(dst,src,off,PMINSW) -#define PMAXSWM(dst,src,off) InjMMXMOps(dst,src,off,PMAXSW) -#define PMULHUWM(dst,src,off) InjMMXMOps(dst,src,off,PMULHUW) -#define PAVGBM(dst,src,off) InjMMXMOps(dst,src,off,PAVGB) -#define PAVGWM(dst,src,off) InjMMXMOps(dst,src,off,PAVGW) -#define PSADBWM(dst,src,off) InjMMXMOps(dst,src,off,PSADBW) -#define PMOVMSKBM(dst,src,off) InjMMXMOps(dst,src,off,PMOVMSKB) -#define PMASKMOVQM(dst,src,off) InjMMXMOps(dst,src,off,PMASKMOVQ) -#define PINSRWM(dst,src,off,msk) InjMMXMOps(dst,src,off,PINSRW) _asm _emit msk -#define PSHUFWM(dst,src,off,msk) InjMMXMOps(dst,src,off,PSHUFW) _asm _emit msk -#define MOVNTQM(dst,src,off) InjMMXMOps(src,dst,off,MOVNTQ) -#define PREFETCHNTAM(mem,off) InjMMXMOps(mm0,mem,off,PREFETCHT) -#define PREFETCHT0M(mem,off) InjMMXMOps(mm1,mem,off,PREFETCHT) -#define PREFETCHT1M(mem,off) InjMMXMOps(mm2,mem,off,PREFETCHT) -#define PREFETCHT2M(mem,off) InjMMXMOps(mm3,mem,off,PREFETCHT) - - -#else - -/* Assume built-in support for 3DNow! opcodes, replace macros with opcodes */ -#define PAVGUSB(dst,src) pavgusb dst,src -#define PF2ID(dst,src) pf2id dst,src -#define PFACC(dst,src) pfacc dst,src -#define PFADD(dst,src) pfadd dst,src -#define PFCMPEQ(dst,src) pfcmpeq dst,src -#define PFCMPGE(dst,src) pfcmpge dst,src -#define PFCMPGT(dst,src) pfcmpgt dst,src -#define PFMAX(dst,src) pfmax dst,src -#define PFMIN(dst,src) pfmin dst,src -#define PFMUL(dst,src) pfmul dst,src -#define PFRCP(dst,src) pfrcp dst,src -#define PFRCPIT1(dst,src) pfrcpit1 dst,src -#define PFRCPIT2(dst,src) pfrcpit2 dst,src -#define PFRSQRT(dst,src) pfrsqrt dst,src -#define PFRSQIT1(dst,src) pfrsqit1 dst,src -#define PFSUB(dst,src) pfsub dst,src -#define PFSUBR(dst,src) pfsubr dst,src -#define PI2FD(dst,src) pi2fd dst,src -#define PMULHRW(dst,src) pmulhrw dst,src -#define PREFETCH(src) prefetch src -#define PREFETCHW(src) prefetchw src - -#define PAVGUSBM(dst,src,off) pavgusb dst,[src+off] -#define PF2IDM(dst,src,off) PF2ID dst,[src+off] -#define PFACCM(dst,src,off) PFACC dst,[src+off] -#define PFADDM(dst,src,off) PFADD dst,[src+off] -#define PFCMPEQM(dst,src,off) PFCMPEQ dst,[src+off] -#define PFCMPGEM(dst,src,off) PFCMPGE dst,[src+off] -#define PFCMPGTM(dst,src,off) PFCMPGT dst,[src+off] -#define PFMAXM(dst,src,off) PFMAX dst,[src+off] -#define PFMINM(dst,src,off) PFMIN dst,[src+off] -#define PFMULM(dst,src,off) PFMUL dst,[src+off] -#define PFRCPM(dst,src,off) PFRCP dst,[src+off] -#define PFRCPIT1M(dst,src,off) PFRCPIT1 dst,[src+off] -#define PFRCPIT2M(dst,src,off) PFRCPIT2 dst,[src+off] -#define PFRSQRTM(dst,src,off) PFRSQRT dst,[src+off] -#define PFRSQIT1M(dst,src,off) PFRSQIT1 dst,[src+off] -#define PFSUBM(dst,src,off) PFSUB dst,[src+off] -#define PFSUBRM(dst,src,off) PFSUBR dst,[src+off] -#define PI2FDM(dst,src,off) PI2FD dst,[src+off] -#define PMULHRWM(dst,src,off) PMULHRW dst,[src+off] - - -#if defined (__MWERKS__) -// At the moment, CodeWarrior does not support these opcodes, so hand-assemble them - -// Defines for operands. -#define _K3D_MM0 0xc0 -#define _K3D_MM1 0xc1 -#define _K3D_MM2 0xc2 -#define _K3D_MM3 0xc3 -#define _K3D_MM4 0xc4 -#define _K3D_MM5 0xc5 -#define _K3D_MM6 0xc6 -#define _K3D_MM7 0xc7 -#define _K3D_mm0 0xc0 -#define _K3D_mm1 0xc1 -#define _K3D_mm2 0xc2 -#define _K3D_mm3 0xc3 -#define _K3D_mm4 0xc4 -#define _K3D_mm5 0xc5 -#define _K3D_mm6 0xc6 -#define _K3D_mm7 0xc7 -#define _K3D_EAX 0x00 -#define _K3D_ECX 0x01 -#define _K3D_EDX 0x02 -#define _K3D_EBX 0x03 -#define _K3D_ESI 0x06 -#define _K3D_EDI 0x07 -#define _K3D_eax 0x00 -#define _K3D_ecx 0x01 -#define _K3D_edx 0x02 -#define _K3D_ebx 0x03 -#define _K3D_esi 0x06 -#define _K3D_edi 0x07 -#define _K3D_EAX 0x00 -#define _K3D_ECX 0x01 -#define _K3D_EDX 0x02 -#define _K3D_EBX 0x03 -#define _K3D_ESI 0x06 -#define _K3D_EDI 0x07 -#define _K3D_eax 0x00 -#define _K3D_ecx 0x01 -#define _K3D_edx 0x02 -#define _K3D_ebx 0x03 -#define _K3D_esi 0x06 -#define _K3D_edi 0x07 - -#define InjK3DOps(dst,src,inst) \ - db 0x0f, 0x0f, (((_K3D_##dst & 0x3f) << 3) | _K3D_##src), _3DNowOpcode##inst - -#define InjK3DMOps(dst,src,off,inst) \ - db 0x0f, 0x0f, (((_K3D_##dst & 0x3f) << 3) | _K3D_##src | 0x40), off, _3DNowOpcode##inst - -#define InjMMXOps(dst,src,inst) \ - db 0x0f, _3DNowOpcode##inst, (((_K3D_##dst & 0x3f) << 3) | _K3D_##src) - -#define InjMMXMOps(dst,src,off,inst) \ - db 0x0f, _3DNowOpcode##inst, (((_K3D_##dst & 0x3f) << 3) | _K3D_##src | 0x40), off - -#define PFNACC(dst,src) InjK3DOps(dst,src,PFNACC) -#define PFPNACC(dst,src) InjK3DOps(dst,src,PFPNACC) -#define PSWAPD(dst,src) InjK3DOps(dst,src,PSWAPD) -#define PMINUB(dst,src) InjMMXOps(dst,src,PMINUB) -#define PMAXUB(dst,src) InjMMXOps(dst,src,PMAXUB) -#define PMINSW(dst,src) InjMMXOps(dst,src,PMINSW) -#define PMAXSW(dst,src) InjMMXOps(dst,src,PMAXSW) -#define PMULHUW(dst,src) InjMMXOps(dst,src,PMULHUW) -#define PAVGB(dst,src) InjMMXOps(dst,src,PAVGB) -#define PAVGW(dst,src) InjMMXOps(dst,src,PAVGW) -#define PSADBW(dst,src) InjMMXOps(dst,src,PSADBW) -#define PMOVMSKB(dst,src) InjMMXOps(dst,src,PMOVMSKB) -#define PMASKMOVQ(dst,src) InjMMXOps(dst,src,PMASKMOVQ) -#define PINSRW(dst,src,msk) InjMMXOps(dst,src,PINSRW) db msk -#define PEXTRW(dst,src,msk) InjMMXOps(dst,src,PEXTRW) db msk -#define PSHUFW(dst,src,msk) InjMMXOps(dst,src,PSHUFW) db msk -#define MOVNTQ(dst,src) InjMMXOps(src,dst,MOVNTQ) -#define PREFETCHNTA(mem) InjMMXOps(mm0,mem,PREFETCHT) -#define PREFETCHT0(mem) InjMMXOps(mm1,mem,PREFETCHT) -#define PREFETCHT1(mem) InjMMXOps(mm2,mem,PREFETCHT) -#define PREFETCHT2(mem) InjMMXOps(mm3,mem,PREFETCHT) - - -/* Memory/offset versions of the K7 opcodes */ -#define PFNACCM(dst,src,off) InjK3DMOps(dst,src,off,PFNACC) -#define PFPNACCM(dst,src,off) InjK3DMOps(dst,src,off,PFPNACC) -#define PSWAPDM(dst,src,off) InjK3DMOps(dst,src,off,PSWAPD) -#define PMINUBM(dst,src,off) InjMMXMOps(dst,src,off,PMINUB) -#define PMAXUBM(dst,src,off) InjMMXMOps(dst,src,off,PMAXUB) -#define PMINSWM(dst,src,off) InjMMXMOps(dst,src,off,PMINSW) -#define PMAXSWM(dst,src,off) InjMMXMOps(dst,src,off,PMAXSW) -#define PMULHUWM(dst,src,off) InjMMXMOps(dst,src,off,PMULHUW) -#define PAVGBM(dst,src,off) InjMMXMOps(dst,src,off,PAVGB) -#define PAVGWM(dst,src,off) InjMMXMOps(dst,src,off,PAVGW) -#define PSADBWM(dst,src,off) InjMMXMOps(dst,src,off,PSADBW) -#define PMOVMSKBM(dst,src,off) InjMMXMOps(dst,src,off,PMOVMSKB) -#define PMASKMOVQM(dst,src,off) InjMMXMOps(dst,src,off,PMASKMOVQ) -#define PINSRWM(dst,src,off,msk) InjMMXMOps(dst,src,off,PINSRW), msk -#define PEXTRWM(dst,src,off,msk) InjMMXMOps(dst,src,off,PEXTRW), msk -#define PSHUFWM(dst,src,off,msk) InjMMXMOps(dst,src,off,PSHUFW), msk -#define MOVNTQM(dst,src,off) InjMMXMOps(src,dst,off,MOVNTQ) -#define PREFETCHNTAM(mem,off) InjMMXMOps(mm0,mem,off,PREFETCHT) -#define PREFETCHT0M(mem,off) InjMMXMOps(mm1,mem,off,PREFETCHT) -#define PREFETCHT1M(mem,off) InjMMXMOps(mm2,mem,off,PREFETCHT) -#define PREFETCHT2M(mem,off) InjMMXMOps(mm3,mem,off,PREFETCHT) - - -#else - -#define PFNACC(dst,src) PFNACC dst,src -#define PFPNACC(dst,src) PFPNACC dst,src -#define PSWAPD(dst,src) PSWAPD dst,src -#define PMINUB(dst,src) PMINUB dst,src -#define PMAXUB(dst,src) PMAXUB dst,src -#define PMINSW(dst,src) PMINSW dst,src -#define PMAXSW(dst,src) PMAXSW dst,src -#define PMULHUW(dst,src) PMULHUW dst,src -#define PAVGB(dst,src) PAVGB dst,src -#define PAVGW(dst,src) PAVGW dst,src -#define PSADBW(dst,src) PSADBW dst,src -#define PMOVMSKB(dst,src) PMOVMSKB dst,src -#define PMASKMOVQ(dst,src) PMASKMOVQ dst,src -#define PINSRW(dst,src,msk) PINSRW dst,src,msk -#define PEXTRW(dst,src,msk) PEXTRW dst,src,msk -#define PSHUFW(dst,src,msk) PSHUFW dst,src,msk -#define MOVNTQ(dst,src) MOVNTQ dst,src - -#define PFNACCM(dst,src,off) PFNACC dst,[src+off] -#define PFPNACCM(dst,src,off) PFPNACC dst,[src+off] -#define PSWAPDM(dst,src,off) PSWAPD dst,[src+off] -#define PMINUBM(dst,src,off) PMINUB dst,[src+off] -#define PMAXUBM(dst,src,off) PMAXUB dst,[src+off] -#define PMINSWM(dst,src,off) PMINSW dst,[src+off] -#define PMAXSWM(dst,src,off) PMAXSW dst,[src+off] -#define PMULHUWM(dst,src,off) PMULHUW dst,[src+off] -#define PAVGBM(dst,src,off) PAVGB dst,[src+off] -#define PAVGWM(dst,src,off) PAVGW dst,[src+off] -#define PSADBWM(dst,src,off) PSADBW dst,[src+off] -#define PMOVMSKBM(dst,src,off) PMOVMSKB dst,[src+off] -#define PMASKMOVQM(dst,src,off) PMASKMOVQ dst,[src+off] -#define PINSRWM(dst,src,off,msk) PINSRW dst,[src+off],msk -#define PEXTRWM(dst,src,off,msk) PEXTRW dst,[src+off],msk -#define PSHUFWM(dst,src,off,msk) PSHUFW dst,[src+off],msk -#define MOVNTQM(dst,src,off) MOVNTQ dst,[src+off] - -#endif - -#endif - -/* Just to deal with lower case. */ -#define pf2id(dst,src) PF2ID(dst,src) -#define pfacc(dst,src) PFACC(dst,src) -#define pfadd(dst,src) PFADD(dst,src) -#define pfcmpeq(dst,src) PFCMPEQ(dst,src) -#define pfcmpge(dst,src) PFCMPGE(dst,src) -#define pfcmpgt(dst,src) PFCMPGT(dst,src) -#define pfmax(dst,src) PFMAX(dst,src) -#define pfmin(dst,src) PFMIN(dst,src) -#define pfmul(dst,src) PFMUL(dst,src) -#define pfrcp(dst,src) PFRCP(dst,src) -#define pfrcpit1(dst,src) PFRCPIT1(dst,src) -#define pfrcpit2(dst,src) PFRCPIT2(dst,src) -#define pfrsqrt(dst,src) PFRSQRT(dst,src) -#define pfrsqit1(dst,src) PFRSQIT1(dst,src) -#define pfsub(dst,src) PFSUB(dst,src) -#define pfsubr(dst,src) PFSUBR(dst,src) -#define pi2fd(dst,src) PI2FD(dst,src) -#define femms FEMMS -#define pavgusb(dst,src) PAVGUSB(dst,src) -#define pmulhrw(dst,src) PMULHRW(dst,src) -#define prefetch(src) PREFETCH(src) -#define prefetchw(src) PREFETCHW(src) - -#define prefetchm(src,off) PREFETCHM(src,off) -#define prefetchmlong(src,off) PREFETCHMLONG(src,off) -#define prefetchwm(src,off) PREFETCHWM(src,off) -#define prefetchwmlong(src,off) PREFETCHWMLONG(src,off) - -#define pfnacc(dst,src) PFNACC(dst,src) -#define pfpnacc(dst,src) PFPNACC(dst,src) -#define pswapd(dst,src) PSWAPD(dst,src) -#define pminub(dst,src) PMINUB(dst,src) -#define pmaxub(dst,src) PMAXUB(dst,src) -#define pminsw(dst,src) PMINSW(dst,src) -#define pmaxsw(dst,src) PMAXSW(dst,src) -#define pmulhuw(dst,src) PMULHUW(dst,src) -#define pavgb(dst,src) PAVGB(dst,src) -#define pavgw(dst,src) PAVGW(dst,src) -#define psadbw(dst,src) PSADBW(dst,src) -#define pmovmskb(dst,src) PMOVMSKB(dst,src) -#define pmaskmovq(dst,src) PMASKMOVQ(dst,src) -#define pinsrw(dst,src,msk) PINSRW(dst,src,msk) -#define pextrw(dst,src,msk) PEXTRW(dst,src,msk) -#define pshufw(dst,src,msk) PSHUFW(dst,src,msk) -#define movntq(dst,src) MOVNTQ(dst,src) -#define prefetchnta(mem) PREFETCHNTA(mem) -#define prefetcht0(mem) PREFETCHT0(mem) -#define prefetcht1(mem) PREFETCHT1(mem) -#define prefetcht2(mem) PREFETCHT2(mem) - - -#define pavgusbm(dst,src,off) PAVGUSBM(dst,src,off) -#define pf2idm(dst,src,off) PF2IDM(dst,src,off) -#define pfaccm(dst,src,off) PFACCM(dst,src,off) -#define pfaddm(dst,src,off) PFADDM(dst,src,off) -#define pfcmpeqm(dst,src,off) PFCMPEQM(dst,src,off) -#define pfcmpgem(dst,src,off) PFCMPGEM(dst,src,off) -#define pfcmpgtm(dst,src,off) PFCMPGTM(dst,src,off) -#define pfmaxm(dst,src,off) PFMAXM(dst,src,off) -#define pfminm(dst,src,off) PFMINM(dst,src,off) -#define pfmulm(dst,src,off) PFMULM(dst,src,off) -#define pfrcpm(dst,src,off) PFRCPM(dst,src,off) -#define pfrcpit1m(dst,src,off) PFRCPIT1M(dst,src,off) -#define pfrcpit2m(dst,src,off) PFRCPIT2M(dst,src,off) -#define pfrsqrtm(dst,src,off) PFRSQRTM(dst,src,off) -#define pfrsqit1m(dst,src,off) PFRSQIT1M(dst,src,off) -#define pfsubm(dst,src,off) PFSUBM(dst,src,off) -#define pfsubrm(dst,src,off) PFSUBRM(dst,src,off) -#define pi2fdm(dst,src,off) PI2FDM(dst,src,off) -#define pmulhrwm(dst,src,off) PMULHRWM(dst,src,off) -#define cpuid CPUID -#define sfence SFENCE - -#define pfnaccm(dst,src,off) PFNACCM(dst,src,off) -#define pfpnaccm(dst,src,off) PFPNACCM(dst,src,off) -#define pswapdm(dst,src,off) PSWAPDM(dst,src,off) -#define pminubm(dst,src,off) PMINUBM(dst,src,off) -#define pmaxubm(dst,src,off) PMAXUBM(dst,src,off) -#define pminswm(dst,src,off) PMINSWM(dst,src,off) -#define pmaxswm(dst,src,off) PMAXSWM(dst,src,off) -#define pmulhuwm(dst,src,off) PMULHUWM(dst,src,off) -#define pavgbm(dst,src,off) PAVGBM(dst,src,off) -#define pavgwm(dst,src,off) PAVGWM(dst,src,off) -#define psadbwm(dst,src,off) PSADBWM(dst,src,off) -#define pmovmskbm(dst,src,off) PMOVMSKBM(dst,src,off) -#define pmaskmovqm(dst,src,off) PMASKMOVQM(dst,src,off) -#define pinsrwm(dst,src,off,msk) PINSRWM(dst,src,off,msk) -#define pextrwm(dst,src,off,msk) PEXTRWM(dst,src,off,msk) -#define pshufwm(dst,src,off,msk) PSHUFWM(dst,src,off,msk) -#define movntqm(dst,src,off) MOVNTQM(dst,src,off) -#define prefetchntam(mem,off) PREFETCHNTA(mem,off) -#define prefetcht0m(mem,off) PREFETCHT0(mem,off) -#define prefetcht1m(mem,off) PREFETCHT1(mem,off) -#define prefetcht2m(mem,off) PREFETCHT2(mem,off) - -#endif diff --git a/Resources/NetHook/mathlib/anorms.h b/Resources/NetHook/mathlib/anorms.h deleted file mode 100644 index 873b5db6..00000000 --- a/Resources/NetHook/mathlib/anorms.h +++ /dev/null @@ -1,25 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef ANORMS_H -#define ANORMS_H -#ifdef _WIN32 -#pragma once -#endif - - -#include "mathlib/vector.h" - - -#define NUMVERTEXNORMALS 162 - -// the angle between consecutive g_anorms[] vectors is ~14.55 degrees -#define VERTEXNORMAL_CONE_INNER_ANGLE DEG2RAD(7.275) - -extern Vector g_anorms[NUMVERTEXNORMALS]; - - -#endif // ANORMS_H diff --git a/Resources/NetHook/mathlib/bumpvects.h b/Resources/NetHook/mathlib/bumpvects.h deleted file mode 100644 index 8eb6f030..00000000 --- a/Resources/NetHook/mathlib/bumpvects.h +++ /dev/null @@ -1,37 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef BUMPVECTS_H -#define BUMPVECTS_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "mathlib/mathlib.h" - -#define OO_SQRT_2 0.70710676908493042f -#define OO_SQRT_3 0.57735025882720947f -#define OO_SQRT_6 0.40824821591377258f -// sqrt( 2 / 3 ) -#define OO_SQRT_2_OVER_3 0.81649661064147949f - -#define NUM_BUMP_VECTS 3 - -const TableVector g_localBumpBasis[NUM_BUMP_VECTS] = -{ - { OO_SQRT_2_OVER_3, 0.0f, OO_SQRT_3 }, - { -OO_SQRT_6, OO_SQRT_2, OO_SQRT_3 }, - { -OO_SQRT_6, -OO_SQRT_2, OO_SQRT_3 } -}; - -void GetBumpNormals( const Vector& sVect, const Vector& tVect, const Vector& flatNormal, - const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ); - -#endif // BUMPVECTS_H diff --git a/Resources/NetHook/mathlib/compressed_3d_unitvec.h b/Resources/NetHook/mathlib/compressed_3d_unitvec.h deleted file mode 100644 index f118ae17..00000000 --- a/Resources/NetHook/mathlib/compressed_3d_unitvec.h +++ /dev/null @@ -1,284 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef _3D_UNITVEC_H -#define _3D_UNITVEC_H - - -#define UNITVEC_DECLARE_STATICS \ - float cUnitVector::mUVAdjustment[0x2000]; \ - Vector cUnitVector::mTmpVec; - -// upper 3 bits -#define SIGN_MASK 0xe000 -#define XSIGN_MASK 0x8000 -#define YSIGN_MASK 0x4000 -#define ZSIGN_MASK 0x2000 - -// middle 6 bits - xbits -#define TOP_MASK 0x1f80 - -// lower 7 bits - ybits -#define BOTTOM_MASK 0x007f - -// unitcomp.cpp : A Unit Vector to 16-bit word conversion -// algorithm based on work of Rafael Baptista (rafael@oroboro.com) -// Accuracy improved by O.D. (punkfloyd@rocketmail.com) -// Used with Permission. - -// a compressed unit vector. reasonable fidelty for unit -// vectors in a 16 bit package. Good enough for surface normals -// we hope. -class cUnitVector // : public c3dMathObject -{ -public: - cUnitVector() { mVec = 0; } - cUnitVector( const Vector& vec ) - { - packVector( vec ); - } - cUnitVector( unsigned short val ) { mVec = val; } - - cUnitVector& operator=( const Vector& vec ) - { packVector( vec ); return *this; } - - operator Vector() - { - unpackVector( mTmpVec ); - return mTmpVec; - } - - void packVector( const Vector& vec ) - { - // convert from Vector to cUnitVector - - Assert( vec.IsValid()); - Vector tmp = vec; - - // input vector does not have to be unit length - // Assert( tmp.length() <= 1.001f ); - - mVec = 0; - if ( tmp.x < 0 ) { mVec |= XSIGN_MASK; tmp.x = -tmp.x; } - if ( tmp.y < 0 ) { mVec |= YSIGN_MASK; tmp.y = -tmp.y; } - if ( tmp.z < 0 ) { mVec |= ZSIGN_MASK; tmp.z = -tmp.z; } - - // project the normal onto the plane that goes through - // X0=(1,0,0),Y0=(0,1,0),Z0=(0,0,1). - // on that plane we choose an (projective!) coordinate system - // such that X0->(0,0), Y0->(126,0), Z0->(0,126),(0,0,0)->Infinity - - // a little slower... old pack was 4 multiplies and 2 adds. - // This is 2 multiplies, 2 adds, and a divide.... - float w = 126.0f / ( tmp.x + tmp.y + tmp.z ); - long xbits = (long)( tmp.x * w ); - long ybits = (long)( tmp.y * w ); - - Assert( xbits < 127 ); - Assert( xbits >= 0 ); - Assert( ybits < 127 ); - Assert( ybits >= 0 ); - - // Now we can be sure that 0<=xp<=126, 0<=yp<=126, 0<=xp+yp<=126 - // however for the sampling we want to transform this triangle - // into a rectangle. - if ( xbits >= 64 ) - { - xbits = 127 - xbits; - ybits = 127 - ybits; - } - - // now we that have xp in the range (0,127) and yp in - // the range (0,63), we can pack all the bits together - mVec |= ( xbits << 7 ); - mVec |= ybits; - } - - void unpackVector( Vector& vec ) - { - // if we do a straightforward backward transform - // we will get points on the plane X0,Y0,Z0 - // however we need points on a sphere that goes through - // these points. Therefore we need to adjust x,y,z so - // that x^2+y^2+z^2=1 by normalizing the vector. We have - // already precalculated the amount by which we need to - // scale, so all we do is a table lookup and a - // multiplication - - // get the x and y bits - long xbits = (( mVec & TOP_MASK ) >> 7 ); - long ybits = ( mVec & BOTTOM_MASK ); - - // map the numbers back to the triangle (0,0)-(0,126)-(126,0) - if (( xbits + ybits ) >= 127 ) - { - xbits = 127 - xbits; - ybits = 127 - ybits; - } - - // do the inverse transform and normalization - // costs 3 extra multiplies and 2 subtracts. No big deal. - float uvadj = mUVAdjustment[mVec & ~SIGN_MASK]; - vec.x = uvadj * (float) xbits; - vec.y = uvadj * (float) ybits; - vec.z = uvadj * (float)( 126 - xbits - ybits ); - - // set all the sign bits - if ( mVec & XSIGN_MASK ) vec.x = -vec.x; - if ( mVec & YSIGN_MASK ) vec.y = -vec.y; - if ( mVec & ZSIGN_MASK ) vec.z = -vec.z; - - Assert( vec.IsValid()); - } - - static void initializeStatics() - { - for ( int idx = 0; idx < 0x2000; idx++ ) - { - long xbits = idx >> 7; - long ybits = idx & BOTTOM_MASK; - - // map the numbers back to the triangle (0,0)-(0,127)-(127,0) - if (( xbits + ybits ) >= 127 ) - { - xbits = 127 - xbits; - ybits = 127 - ybits; - } - - // convert to 3D vectors - float x = (float)xbits; - float y = (float)ybits; - float z = (float)( 126 - xbits - ybits ); - - // calculate the amount of normalization required - mUVAdjustment[idx] = 1.0f / sqrtf( y*y + z*z + x*x ); - Assert( _finite( mUVAdjustment[idx])); - - //cerr << mUVAdjustment[idx] << "\t"; - //if ( xbits == 0 ) cerr << "\n"; - } - } - -#if 0 - void test() - { - #define TEST_RANGE 4 - #define TEST_RANDOM 100 - #define TEST_ANGERROR 1.0 - - float maxError = 0; - float avgError = 0; - int numVecs = 0; - - {for ( int x = -TEST_RANGE; x < TEST_RANGE; x++ ) - { - for ( int y = -TEST_RANGE; y < TEST_RANGE; y++ ) - { - for ( int z = -TEST_RANGE; z < TEST_RANGE; z++ ) - { - if (( x + y + z ) == 0 ) continue; - - Vector vec( (float)x, (float)y, (float)z ); - Vector vec2; - - vec.normalize(); - packVector( vec ); - unpackVector( vec2 ); - - float ang = vec.dot( vec2 ); - ang = (( fabs( ang ) > 0.99999f ) ? 0 : (float)acos(ang)); - - if (( ang > TEST_ANGERROR ) | ( !_finite( ang ))) - { - cerr << "error: " << ang << endl; - cerr << "orig vec: " << vec.x << ",\t" - << vec.y << ",\t" << vec.z << "\tmVec: " - << mVec << endl; - cerr << "quantized vec2: " << vec2.x - << ",\t" << vec2.y << ",\t" - << vec2.z << endl << endl; - } - avgError += ang; - numVecs++; - if ( maxError < ang ) maxError = ang; - } - } - }} - - for ( int w = 0; w < TEST_RANDOM; w++ ) - { - Vector vec( genRandom(), genRandom(), genRandom()); - Vector vec2; - vec.normalize(); - - packVector( vec ); - unpackVector( vec2 ); - - float ang =vec.dot( vec2 ); - ang = (( ang > 0.999f ) ? 0 : (float)acos(ang)); - - if (( ang > TEST_ANGERROR ) | ( !_finite( ang ))) - { - cerr << "error: " << ang << endl; - cerr << "orig vec: " << vec.x << ",\t" - << vec.y << ",\t" << vec.z << "\tmVec: " - << mVec << endl; - cerr << "quantized vec2: " << vec2.x << ",\t" - << vec2.y << ",\t" - << vec2.z << endl << endl; - } - avgError += ang; - numVecs++; - if ( maxError < ang ) maxError = ang; - } - - { for ( int x = 0; x < 50; x++ ) - { - Vector vec( (float)x, 25.0f, 0.0f ); - Vector vec2; - - vec.normalize(); - packVector( vec ); - unpackVector( vec2 ); - - float ang = vec.dot( vec2 ); - ang = (( fabs( ang ) > 0.999f ) ? 0 : (float)acos(ang)); - - if (( ang > TEST_ANGERROR ) | ( !_finite( ang ))) - { - cerr << "error: " << ang << endl; - cerr << "orig vec: " << vec.x << ",\t" - << vec.y << ",\t" << vec.z << "\tmVec: " - << mVec << endl; - cerr << " quantized vec2: " << vec2.x << ",\t" - << vec2.y << ",\t" << vec2.z << endl << endl; - } - - avgError += ang; - numVecs++; - if ( maxError < ang ) maxError = ang; - }} - - cerr << "max angle error: " << maxError - << ", average error: " << avgError / numVecs - << ", num tested vecs: " << numVecs << endl; - } - - friend ostream& operator<< ( ostream& os, const cUnitVector& vec ) - { os << vec.mVec; return os; } -#endif - -//protected: // !!!! - - unsigned short mVec; - static float mUVAdjustment[0x2000]; - static Vector mTmpVec; -}; - -#endif // _3D_VECTOR_H - - diff --git a/Resources/NetHook/mathlib/compressed_light_cube.h b/Resources/NetHook/mathlib/compressed_light_cube.h deleted file mode 100644 index 81a638e0..00000000 --- a/Resources/NetHook/mathlib/compressed_light_cube.h +++ /dev/null @@ -1,24 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef COMPRESSED_LIGHT_CUBE_H -#define COMPRESSED_LIGHT_CUBE_H -#ifdef _WIN32 -#pragma once -#endif - - -#include "mathlib/mathlib.h" - - -struct CompressedLightCube -{ - DECLARE_BYTESWAP_DATADESC(); - ColorRGBExp32 m_Color[6]; -}; - - -#endif // COMPRESSED_LIGHT_CUBE_H diff --git a/Resources/NetHook/mathlib/compressed_vector.h b/Resources/NetHook/mathlib/compressed_vector.h deleted file mode 100644 index 4dfb0f90..00000000 --- a/Resources/NetHook/mathlib/compressed_vector.h +++ /dev/null @@ -1,608 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef COMPRESSED_VECTOR_H -#define COMPRESSED_VECTOR_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include - -// For vec_t, put this somewhere else? -#include "basetypes.h" - -// For rand(). We really need a library! -#include - -#include "tier0/dbg.h" -#include "mathlib/vector.h" - -#include "mathlib/mathlib.h" - -#if defined( _X360 ) -#pragma bitfield_order( push, lsb_to_msb ) -#endif -//========================================================= -// fit a 3D vector into 32 bits -//========================================================= - -class Vector32 -{ -public: - // Construction/destruction: - Vector32(void); - Vector32(vec_t X, vec_t Y, vec_t Z); - - // assignment - Vector32& operator=(const Vector &vOther); - operator Vector (); - -private: - unsigned short x:10; - unsigned short y:10; - unsigned short z:10; - unsigned short exp:2; -}; - -inline Vector32& Vector32::operator=(const Vector &vOther) -{ - CHECK_VALID(vOther); - - static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f }; - - float fmax = max( fabs( vOther.x ), fabs( vOther.y ) ); - fmax = max( fmax, fabs( vOther.z ) ); - - for (exp = 0; exp < 3; exp++) - { - if (fmax < expScale[exp]) - break; - } - Assert( fmax < expScale[exp] ); - - float fexp = 512.0f / expScale[exp]; - - x = clamp( (int)(vOther.x * fexp) + 512, 0, 1023 ); - y = clamp( (int)(vOther.y * fexp) + 512, 0, 1023 ); - z = clamp( (int)(vOther.z * fexp) + 512, 0, 1023 ); - return *this; -} - - -inline Vector32::operator Vector () -{ - Vector tmp; - - static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f }; - - float fexp = expScale[exp] / 512.0f; - - tmp.x = (((int)x) - 512) * fexp; - tmp.y = (((int)y) - 512) * fexp; - tmp.z = (((int)z) - 512) * fexp; - return tmp; -} - - -//========================================================= -// Fit a unit vector into 32 bits -//========================================================= - -class Normal32 -{ -public: - // Construction/destruction: - Normal32(void); - Normal32(vec_t X, vec_t Y, vec_t Z); - - // assignment - Normal32& operator=(const Vector &vOther); - operator Vector (); - -private: - unsigned short x:15; - unsigned short y:15; - unsigned short zneg:1; -}; - - -inline Normal32& Normal32::operator=(const Vector &vOther) -{ - CHECK_VALID(vOther); - - x = clamp( (int)(vOther.x * 16384) + 16384, 0, 32767 ); - y = clamp( (int)(vOther.y * 16384) + 16384, 0, 32767 ); - zneg = (vOther.z < 0); - //x = vOther.x; - //y = vOther.y; - //z = vOther.z; - return *this; -} - - -inline Normal32::operator Vector () -{ - Vector tmp; - - tmp.x = ((int)x - 16384) * (1 / 16384.0); - tmp.y = ((int)y - 16384) * (1 / 16384.0); - tmp.z = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y ); - if (zneg) - tmp.z = -tmp.z; - return tmp; -} - - -//========================================================= -// 64 bit Quaternion -//========================================================= - -class Quaternion64 -{ -public: - // Construction/destruction: - Quaternion64(void); - Quaternion64(vec_t X, vec_t Y, vec_t Z); - - // assignment - // Quaternion& operator=(const Quaternion64 &vOther); - Quaternion64& operator=(const Quaternion &vOther); - operator Quaternion (); -private: - uint64 x:21; - uint64 y:21; - uint64 z:21; - uint64 wneg:1; -}; - - -inline Quaternion64::operator Quaternion () -{ - Quaternion tmp; - - // shift to -1048576, + 1048575, then round down slightly to -1.0 < x < 1.0 - tmp.x = ((int)x - 1048576) * (1 / 1048576.5f); - tmp.y = ((int)y - 1048576) * (1 / 1048576.5f); - tmp.z = ((int)z - 1048576) * (1 / 1048576.5f); - tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z ); - if (wneg) - tmp.w = -tmp.w; - return tmp; -} - -inline Quaternion64& Quaternion64::operator=(const Quaternion &vOther) -{ - CHECK_VALID(vOther); - - x = clamp( (int)(vOther.x * 1048576) + 1048576, 0, 2097151 ); - y = clamp( (int)(vOther.y * 1048576) + 1048576, 0, 2097151 ); - z = clamp( (int)(vOther.z * 1048576) + 1048576, 0, 2097151 ); - wneg = (vOther.w < 0); - return *this; -} - -//========================================================= -// 48 bit Quaternion -//========================================================= - -class Quaternion48 -{ -public: - // Construction/destruction: - Quaternion48(void); - Quaternion48(vec_t X, vec_t Y, vec_t Z); - - // assignment - // Quaternion& operator=(const Quaternion48 &vOther); - Quaternion48& operator=(const Quaternion &vOther); - operator Quaternion (); -private: - unsigned short x:16; - unsigned short y:16; - unsigned short z:15; - unsigned short wneg:1; -}; - - -inline Quaternion48::operator Quaternion () -{ - Quaternion tmp; - - tmp.x = ((int)x - 32768) * (1 / 32768.0); - tmp.y = ((int)y - 32768) * (1 / 32768.0); - tmp.z = ((int)z - 16384) * (1 / 16384.0); - tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z ); - if (wneg) - tmp.w = -tmp.w; - return tmp; -} - -inline Quaternion48& Quaternion48::operator=(const Quaternion &vOther) -{ - CHECK_VALID(vOther); - - x = clamp( (int)(vOther.x * 32768) + 32768, 0, 65535 ); - y = clamp( (int)(vOther.y * 32768) + 32768, 0, 65535 ); - z = clamp( (int)(vOther.z * 16384) + 16384, 0, 32767 ); - wneg = (vOther.w < 0); - return *this; -} - -//========================================================= -// 32 bit Quaternion -//========================================================= - -class Quaternion32 -{ -public: - // Construction/destruction: - Quaternion32(void); - Quaternion32(vec_t X, vec_t Y, vec_t Z); - - // assignment - // Quaternion& operator=(const Quaternion48 &vOther); - Quaternion32& operator=(const Quaternion &vOther); - operator Quaternion (); -private: - unsigned int x:11; - unsigned int y:10; - unsigned int z:10; - unsigned int wneg:1; -}; - - -inline Quaternion32::operator Quaternion () -{ - Quaternion tmp; - - tmp.x = ((int)x - 1024) * (1 / 1024.0); - tmp.y = ((int)y - 512) * (1 / 512.0); - tmp.z = ((int)z - 512) * (1 / 512.0); - tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z ); - if (wneg) - tmp.w = -tmp.w; - return tmp; -} - -inline Quaternion32& Quaternion32::operator=(const Quaternion &vOther) -{ - CHECK_VALID(vOther); - - x = clamp( (int)(vOther.x * 1024) + 1024, 0, 2047 ); - y = clamp( (int)(vOther.y * 512) + 512, 0, 1023 ); - z = clamp( (int)(vOther.z * 512) + 512, 0, 1023 ); - wneg = (vOther.w < 0); - return *this; -} - -//========================================================= -// 16 bit float -//========================================================= - - -const int float32bias = 127; -const int float16bias = 15; - -const float maxfloat16bits = 65504.0f; - -class float16 -{ -public: - //float16() {} - //float16( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); } - - void Init() { m_storage.rawWord = 0; } -// float16& operator=(const float16 &other) { m_storage.rawWord = other.m_storage.rawWord; return *this; } -// float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; } -// operator unsigned short () { return m_storage.rawWord; } -// operator float () { return Convert16bitFloatTo32bits( m_storage.rawWord ); } - unsigned short GetBits() const - { - return m_storage.rawWord; - } - float GetFloat() const - { - return Convert16bitFloatTo32bits( m_storage.rawWord ); - } - void SetFloat( float in ) - { - m_storage.rawWord = ConvertFloatTo16bits( in ); - } - - bool IsInfinity() const - { - return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa == 0; - } - bool IsNaN() const - { - return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa != 0; - } - - bool operator==(const float16 other) const { return m_storage.rawWord == other.m_storage.rawWord; } - bool operator!=(const float16 other) const { return m_storage.rawWord != other.m_storage.rawWord; } - -// bool operator< (const float other) const { return GetFloat() < other; } -// bool operator> (const float other) const { return GetFloat() > other; } - -protected: - union float32bits - { - float rawFloat; - struct - { - unsigned int mantissa : 23; - unsigned int biased_exponent : 8; - unsigned int sign : 1; - } bits; - }; - - union float16bits - { - unsigned short rawWord; - struct - { - unsigned short mantissa : 10; - unsigned short biased_exponent : 5; - unsigned short sign : 1; - } bits; - }; - - static bool IsNaN( float16bits in ) - { - return in.bits.biased_exponent == 31 && in.bits.mantissa != 0; - } - static bool IsInfinity( float16bits in ) - { - return in.bits.biased_exponent == 31 && in.bits.mantissa == 0; - } - - // 0x0001 - 0x03ff - static unsigned short ConvertFloatTo16bits( float input ) - { - if ( input > maxfloat16bits ) - input = maxfloat16bits; - else if ( input < -maxfloat16bits ) - input = -maxfloat16bits; - - float16bits output; - float32bits inFloat; - - inFloat.rawFloat = input; - - output.bits.sign = inFloat.bits.sign; - - if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa==0) ) - { - // zero - output.bits.mantissa = 0; - output.bits.biased_exponent = 0; - } - else if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa!=0) ) - { - // denorm -- denorm float maps to 0 half - output.bits.mantissa = 0; - output.bits.biased_exponent = 0; - } - else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa==0) ) - { -#if 0 - // infinity - output.bits.mantissa = 0; - output.bits.biased_exponent = 31; -#else - // infinity maps to maxfloat - output.bits.mantissa = 0x3ff; - output.bits.biased_exponent = 0x1e; -#endif - } - else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa!=0) ) - { -#if 0 - // NaN - output.bits.mantissa = 1; - output.bits.biased_exponent = 31; -#else - // NaN maps to zero - output.bits.mantissa = 0; - output.bits.biased_exponent = 0; -#endif - } - else - { - // regular number - int new_exp = inFloat.bits.biased_exponent-127; - - if (new_exp<-24) - { - // this maps to 0 - output.bits.mantissa = 0; - output.bits.biased_exponent = 0; - } - - if (new_exp<-14) - { - // this maps to a denorm - output.bits.biased_exponent = 0; - unsigned int exp_val = ( unsigned int )( -14 - ( inFloat.bits.biased_exponent - float32bias ) ); - if( exp_val > 0 && exp_val < 11 ) - { - output.bits.mantissa = ( 1 << ( 10 - exp_val ) ) + ( inFloat.bits.mantissa >> ( 13 + exp_val ) ); - } - } - else if (new_exp>15) - { -#if 0 - // map this value to infinity - output.bits.mantissa = 0; - output.bits.biased_exponent = 31; -#else - // to big. . . maps to maxfloat - output.bits.mantissa = 0x3ff; - output.bits.biased_exponent = 0x1e; -#endif - } - else - { - output.bits.biased_exponent = new_exp+15; - output.bits.mantissa = (inFloat.bits.mantissa >> 13); - } - } - return output.rawWord; - } - - static float Convert16bitFloatTo32bits( unsigned short input ) - { - float32bits output; - const float16bits &inFloat = *((float16bits *)&input); - - if( IsInfinity( inFloat ) ) - { - return maxfloat16bits * ( ( inFloat.bits.sign == 1 ) ? -1.0f : 1.0f ); - } - if( IsNaN( inFloat ) ) - { - return 0.0; - } - if( inFloat.bits.biased_exponent == 0 && inFloat.bits.mantissa != 0 ) - { - // denorm - const float half_denorm = (1.0f/16384.0f); // 2^-14 - float mantissa = ((float)(inFloat.bits.mantissa)) / 1024.0f; - float sgn = (inFloat.bits.sign)? -1.0f :1.0f; - output.rawFloat = sgn*mantissa*half_denorm; - } - else - { - // regular number - unsigned mantissa = inFloat.bits.mantissa; - unsigned biased_exponent = inFloat.bits.biased_exponent; - unsigned sign = ((unsigned)inFloat.bits.sign) << 31; - biased_exponent = ( (biased_exponent - float16bias + float32bias) * (biased_exponent != 0) ) << 23; - mantissa <<= (23-10); - - *((unsigned *)&output) = ( mantissa | biased_exponent | sign ); - } - - return output.rawFloat; - } - - - float16bits m_storage; -}; - -class float16_with_assign : public float16 -{ -public: - float16_with_assign() {} - float16_with_assign( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); } - - float16& operator=(const float16 &other) { m_storage.rawWord = ((float16_with_assign &)other).m_storage.rawWord; return *this; } - float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; } -// operator unsigned short () const { return m_storage.rawWord; } - operator float () const { return Convert16bitFloatTo32bits( m_storage.rawWord ); } -}; - -//========================================================= -// Fit a 3D vector in 48 bits -//========================================================= - -class Vector48 -{ -public: - // Construction/destruction: - Vector48(void) {} - Vector48(vec_t X, vec_t Y, vec_t Z) { x.SetFloat( X ); y.SetFloat( Y ); z.SetFloat( Z ); } - - // assignment - Vector48& operator=(const Vector &vOther); - operator Vector (); - - const float operator[]( int i ) const { return (((float16 *)this)[i]).GetFloat(); } - - float16 x; - float16 y; - float16 z; -}; - -inline Vector48& Vector48::operator=(const Vector &vOther) -{ - CHECK_VALID(vOther); - - x.SetFloat( vOther.x ); - y.SetFloat( vOther.y ); - z.SetFloat( vOther.z ); - return *this; -} - - -inline Vector48::operator Vector () -{ - Vector tmp; - - tmp.x = x.GetFloat(); - tmp.y = y.GetFloat(); - tmp.z = z.GetFloat(); - - return tmp; -} - -//========================================================= -// Fit a 2D vector in 32 bits -//========================================================= - -class Vector2d32 -{ -public: - // Construction/destruction: - Vector2d32(void) {} - Vector2d32(vec_t X, vec_t Y) { x.SetFloat( X ); y.SetFloat( Y ); } - - // assignment - Vector2d32& operator=(const Vector &vOther); - Vector2d32& operator=(const Vector2D &vOther); - - operator Vector2D (); - - void Init( vec_t ix = 0.f, vec_t iy = 0.f); - - float16_with_assign x; - float16_with_assign y; -}; - -inline Vector2d32& Vector2d32::operator=(const Vector2D &vOther) -{ - x.SetFloat( vOther.x ); - y.SetFloat( vOther.y ); - return *this; -} - -inline Vector2d32::operator Vector2D () -{ - Vector2D tmp; - - tmp.x = x.GetFloat(); - tmp.y = y.GetFloat(); - - return tmp; -} - -inline void Vector2d32::Init( vec_t ix, vec_t iy ) -{ - x.SetFloat(ix); - y.SetFloat(iy); -} - -#if defined( _X360 ) -#pragma bitfield_order( pop ) -#endif - -#endif - diff --git a/Resources/NetHook/mathlib/halton.h b/Resources/NetHook/mathlib/halton.h deleted file mode 100644 index 47c2fab1..00000000 --- a/Resources/NetHook/mathlib/halton.h +++ /dev/null @@ -1,70 +0,0 @@ -// $Id$ - -// halton.h - classes, etc for generating numbers using the Halton pseudo-random sequence. See -// http://halton-sequences.wikiverse.org/. -// -// what this function is useful for is any sort of sampling/integration problem where -// you want to solve it by random sampling. Each call the NextValue() generates -// a random number between 0 and 1, in an unclumped manner, so that the space can be more -// or less evenly sampled with a minimum number of samples. -// -// It is NOT useful for generating random numbers dynamically, since the outputs aren't -// particularly random. -// -// To generate multidimensional sample values (points in a plane, etc), use two -// HaltonSequenceGenerator_t's, with different (primes) bases. - -#ifndef HALTON_H -#define HALTON_H - -#include -#include - -class HaltonSequenceGenerator_t -{ - int seed; - int base; - float fbase; //< base as a float - -public: - HaltonSequenceGenerator_t(int base); //< base MUST be prime, >=2 - - float GetElement(int element); - - inline float NextValue(void) - { - return GetElement(seed++); - } - -}; - - -class DirectionalSampler_t //< pseudo-random sphere sampling -{ - HaltonSequenceGenerator_t zdot; - HaltonSequenceGenerator_t vrot; -public: - DirectionalSampler_t(void) - : zdot(2),vrot(3) - { - } - - Vector NextValue(void) - { - float zvalue=zdot.NextValue(); - zvalue=2*zvalue-1.0; // map from 0..1 to -1..1 - float phi=acos(zvalue); - // now, generate a random rotation angle for x/y - float theta=2.0*M_PI*vrot.NextValue(); - float sin_p=sin(phi); - return Vector(cos(theta)*sin_p, - sin(theta)*sin_p, - zvalue); - - } -}; - - - - -#endif // halton_h diff --git a/Resources/NetHook/mathlib/lightdesc.h b/Resources/NetHook/mathlib/lightdesc.h deleted file mode 100644 index 4ac74a43..00000000 --- a/Resources/NetHook/mathlib/lightdesc.h +++ /dev/null @@ -1,167 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -// light structure definitions. -#ifndef LIGHTDESC_H -#define LIGHTDESC_H - -#include -#include - -//----------------------------------------------------------------------------- -// Light structure -//----------------------------------------------------------------------------- - -enum LightType_t -{ - MATERIAL_LIGHT_DISABLE = 0, - MATERIAL_LIGHT_POINT, - MATERIAL_LIGHT_DIRECTIONAL, - MATERIAL_LIGHT_SPOT, -}; - -enum LightType_OptimizationFlags_t -{ - LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1, - LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2, - LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4, -}; - -struct LightDesc_t -{ - LightType_t m_Type; //< MATERIAL_LIGHT_xxx - Vector m_Color; //< color+intensity - Vector m_Position; //< light source center position - Vector m_Direction; //< for SPOT, direction it is pointing - float m_Range; //< distance range for light.0=infinite - float m_Falloff; //< angular falloff exponent for spot lights - float m_Attenuation0; //< constant distance falloff term - float m_Attenuation1; //< linear term of falloff - float m_Attenuation2; //< quadatic term of falloff - float m_Theta; //< inner cone angle. no angular falloff - //< within this cone - float m_Phi; //< outer cone angle - - // the values below are derived from the above settings for optimizations - // These aren't used by DX8. . used for software lighting. - float m_ThetaDot; - float m_PhiDot; - unsigned int m_Flags; -protected: - float OneOver_ThetaDot_Minus_PhiDot; - float m_RangeSquared; -public: - - void RecalculateDerivedValues(void); // calculate m_xxDot, m_Type for changed parms - - LightDesc_t(void) - { - } - - // constructors for various useful subtypes - - // a point light with infinite range - LightDesc_t( const Vector &pos, const Vector &color ) - { - InitPoint( pos, color ); - } - - /// a simple light. cone boundaries in radians. you pass a look_at point and the - /// direciton is derived from that. - LightDesc_t( const Vector &pos, const Vector &color, const Vector &point_at, - float inner_cone_boundary, float outer_cone_boundary ) - { - InitSpot( pos, color, point_at, inner_cone_boundary, outer_cone_boundary ); - } - - void InitPoint( const Vector &pos, const Vector &color ); - void InitDirectional( const Vector &dir, const Vector &color ); - void InitSpot(const Vector &pos, const Vector &color, const Vector &point_at, - float inner_cone_boundary, float outer_cone_boundary ); - - /// Given 4 points and 4 normals, ADD lighting from this light into "color". - void ComputeLightAtPoints( const FourVectors &pos, const FourVectors &normal, - FourVectors &color, bool DoHalfLambert=false ) const; - void ComputeNonincidenceLightAtPoints( const FourVectors &pos, FourVectors &color ) const; - void ComputeLightAtPointsForDirectional( const FourVectors &pos, - const FourVectors &normal, - FourVectors &color, bool DoHalfLambert=false ) const; - - // warning - modifies color!!! set color first!! - void SetupOldStyleAttenuation( float fQuadatricAttn, float fLinearAttn, float fConstantAttn ); - - void SetupNewStyleAttenuation( float fFiftyPercentDistance, float fZeroPercentDistance ); - - -/// given a direction relative to the light source position, is this ray within the - /// light cone (for spotlights..non spots consider all rays to be within their cone) - bool IsDirectionWithinLightCone(const Vector &rdir) const - { - return ((m_Type!=MATERIAL_LIGHT_SPOT) || (rdir.Dot(m_Direction)>=m_PhiDot)); - } -}; - - -//----------------------------------------------------------------------------- -// a point light with infinite range -//----------------------------------------------------------------------------- -inline void LightDesc_t::InitPoint( const Vector &pos, const Vector &color ) -{ - m_Type=MATERIAL_LIGHT_POINT; - m_Color=color; - m_Position=pos; - m_Range=0.0; // infinite - m_Attenuation0=1.0; - m_Attenuation1=0; - m_Attenuation2=0; - RecalculateDerivedValues(); -} - - -//----------------------------------------------------------------------------- -// a directional light with infinite range -//----------------------------------------------------------------------------- -inline void LightDesc_t::InitDirectional( const Vector &dir, const Vector &color ) -{ - m_Type=MATERIAL_LIGHT_DIRECTIONAL; - m_Color=color; - m_Direction=dir; - m_Range=0.0; // infinite - m_Attenuation0=1.0; - m_Attenuation1=0; - m_Attenuation2=0; - RecalculateDerivedValues(); -} - - -//----------------------------------------------------------------------------- -// a simple light. cone boundaries in radians. you pass a look_at point and the -// direciton is derived from that. -//----------------------------------------------------------------------------- -inline void LightDesc_t::InitSpot(const Vector &pos, const Vector &color, const Vector &point_at, - float inner_cone_boundary, float outer_cone_boundary) -{ - m_Type=MATERIAL_LIGHT_SPOT; - m_Color=color; - m_Position=pos; - m_Direction=point_at; - m_Direction-=pos; - VectorNormalizeFast(m_Direction); - m_Falloff=5.0; // linear angle falloff - m_Theta=inner_cone_boundary; - m_Phi=outer_cone_boundary; - - m_Range=0.0; // infinite - - m_Attenuation0=1.0; - m_Attenuation1=0; - m_Attenuation2=0; - RecalculateDerivedValues(); -} - - -#endif - diff --git a/Resources/NetHook/mathlib/math_pfns.h b/Resources/NetHook/mathlib/math_pfns.h deleted file mode 100644 index 2fa0abfb..00000000 --- a/Resources/NetHook/mathlib/math_pfns.h +++ /dev/null @@ -1,72 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=====================================================================================// - -#ifndef _MATH_PFNS_H_ -#define _MATH_PFNS_H_ - -#if defined( _X360 ) -#include -#endif - -#if !defined( _X360 ) - -// These globals are initialized by mathlib and redirected based on available fpu features -extern float (*pfSqrt)(float x); -extern float (*pfRSqrt)(float x); -extern float (*pfRSqrtFast)(float x); -extern void (*pfFastSinCos)(float x, float *s, float *c); -extern float (*pfFastCos)(float x); - -// The following are not declared as macros because they are often used in limiting situations, -// and sometimes the compiler simply refuses to inline them for some reason -#define FastSqrt(x) (*pfSqrt)(x) -#define FastRSqrt(x) (*pfRSqrt)(x) -#define FastRSqrtFast(x) (*pfRSqrtFast)(x) -#define FastSinCos(x,s,c) (*pfFastSinCos)(x,s,c) -#define FastCos(x) (*pfFastCos)(x) - -#endif // !_X360 - -#if defined( _X360 ) - -FORCEINLINE float _VMX_Sqrt( float x ) -{ - return __fsqrts( x ); -} - -FORCEINLINE float _VMX_RSqrt( float x ) -{ - float rroot = __frsqrte( x ); - - // Single iteration NewtonRaphson on reciprocal square root estimate - return (0.5f * rroot) * (3.0f - (x * rroot) * rroot); -} - -FORCEINLINE float _VMX_RSqrtFast( float x ) -{ - return __frsqrte( x ); -} - -FORCEINLINE void _VMX_SinCos( float a, float *pS, float *pC ) -{ - XMScalarSinCos( pS, pC, a ); -} - -FORCEINLINE float _VMX_Cos( float a ) -{ - return XMScalarCos( a ); -} - -// the 360 has fixed hw and calls directly -#define FastSqrt(x) _VMX_Sqrt(x) -#define FastRSqrt(x) _VMX_RSqrt(x) -#define FastRSqrtFast(x) _VMX_RSqrtFast(x) -#define FastSinCos(x,s,c) _VMX_SinCos(x,s,c) -#define FastCos(x) _VMX_Cos(x) - -#endif // _X360 - -#endif // _MATH_PFNS_H_ diff --git a/Resources/NetHook/mathlib/mathlib.h b/Resources/NetHook/mathlib/mathlib.h deleted file mode 100644 index 5b0f8fd8..00000000 --- a/Resources/NetHook/mathlib/mathlib.h +++ /dev/null @@ -1,2073 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#ifndef MATH_LIB_H -#define MATH_LIB_H - -#include -#include "tier0/basetypes.h" -#include "mathlib/vector.h" -#include "mathlib/vector2d.h" -#include "tier0/dbg.h" - -#include "mathlib/math_pfns.h" - -// plane_t structure -// !!! if this is changed, it must be changed in asm code too !!! -// FIXME: does the asm code even exist anymore? -// FIXME: this should move to a different file -struct cplane_t -{ - Vector normal; - float dist; - byte type; // for fast side tests - byte signbits; // signx + (signy<<1) + (signz<<1) - byte pad[2]; - -#ifdef VECTOR_NO_SLOW_OPERATIONS - cplane_t() {} - -private: - // No copy constructors allowed if we're in optimal mode - cplane_t(const cplane_t& vOther); -#endif -}; - -// structure offset for asm code -#define CPLANE_NORMAL_X 0 -#define CPLANE_NORMAL_Y 4 -#define CPLANE_NORMAL_Z 8 -#define CPLANE_DIST 12 -#define CPLANE_TYPE 16 -#define CPLANE_SIGNBITS 17 -#define CPLANE_PAD0 18 -#define CPLANE_PAD1 19 - -// 0-2 are axial planes -#define PLANE_X 0 -#define PLANE_Y 1 -#define PLANE_Z 2 - -// 3-5 are non-axial planes snapped to the nearest -#define PLANE_ANYX 3 -#define PLANE_ANYY 4 -#define PLANE_ANYZ 5 - - -//----------------------------------------------------------------------------- -// Frustum plane indices. -// WARNING: there is code that depends on these values -//----------------------------------------------------------------------------- - -enum -{ - FRUSTUM_RIGHT = 0, - FRUSTUM_LEFT = 1, - FRUSTUM_TOP = 2, - FRUSTUM_BOTTOM = 3, - FRUSTUM_NEARZ = 4, - FRUSTUM_FARZ = 5, - FRUSTUM_NUMPLANES = 6 -}; - -extern int SignbitsForPlane( cplane_t *out ); - -class Frustum_t -{ -public: - void SetPlane( int i, int nType, const Vector &vecNormal, float dist ) - { - m_Plane[i].normal = vecNormal; - m_Plane[i].dist = dist; - m_Plane[i].type = nType; - m_Plane[i].signbits = SignbitsForPlane( &m_Plane[i] ); - m_AbsNormal[i].Init( fabs(vecNormal.x), fabs(vecNormal.y), fabs(vecNormal.z) ); - } - - inline const cplane_t *GetPlane( int i ) const { return &m_Plane[i]; } - inline const Vector &GetAbsNormal( int i ) const { return m_AbsNormal[i]; } - -private: - cplane_t m_Plane[FRUSTUM_NUMPLANES]; - Vector m_AbsNormal[FRUSTUM_NUMPLANES]; -}; - -// Computes Y fov from an X fov and a screen aspect ratio + X from Y -float CalcFovY( float flFovX, float flScreenAspect ); -float CalcFovX( float flFovY, float flScreenAspect ); - -// Generate a frustum based on perspective view parameters -// NOTE: FOV is specified in degrees, as the *full* view angle (not half-angle) -void GeneratePerspectiveFrustum( const Vector& origin, const QAngle &angles, float flZNear, float flZFar, float flFovX, float flAspectRatio, Frustum_t &frustum ); -void GeneratePerspectiveFrustum( const Vector& origin, const Vector &forward, const Vector &right, const Vector &up, float flZNear, float flZFar, float flFovX, float flFovY, Frustum_t &frustum ); - -// Cull the world-space bounding box to the specified frustum. -bool R_CullBox( const Vector& mins, const Vector& maxs, const Frustum_t &frustum ); -bool R_CullBoxSkipNear( const Vector& mins, const Vector& maxs, const Frustum_t &frustum ); - -struct matrix3x4_t -{ - matrix3x4_t() {} - matrix3x4_t( - float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23 ) - { - m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03; - m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13; - m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23; - } - - //----------------------------------------------------------------------------- - // Creates a matrix where the X axis = forward - // the Y axis = left, and the Z axis = up - //----------------------------------------------------------------------------- - void Init( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin ) - { - m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x; - m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y; - m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z; - } - - //----------------------------------------------------------------------------- - // Creates a matrix where the X axis = forward - // the Y axis = left, and the Z axis = up - //----------------------------------------------------------------------------- - matrix3x4_t( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin ) - { - Init( xAxis, yAxis, zAxis, vecOrigin ); - } - - inline void Invalidate( void ) - { - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 4; j++) - { - m_flMatVal[i][j] = VEC_T_NAN; - } - } - } - - float *operator[]( int i ) { Assert(( i >= 0 ) && ( i < 3 )); return m_flMatVal[i]; } - const float *operator[]( int i ) const { Assert(( i >= 0 ) && ( i < 3 )); return m_flMatVal[i]; } - float *Base() { return &m_flMatVal[0][0]; } - const float *Base() const { return &m_flMatVal[0][0]; } - - float m_flMatVal[3][4]; -}; - - -#ifndef M_PI - #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#define M_PI_F ((float)(M_PI)) // Shouldn't collide with anything. - -// NJS: Inlined to prevent floats from being autopromoted to doubles, as with the old system. -#ifndef RAD2DEG - #define RAD2DEG( x ) ( (float)(x) * (float)(180.f / M_PI_F) ) -#endif - -#ifndef DEG2RAD - #define DEG2RAD( x ) ( (float)(x) * (float)(M_PI_F / 180.f) ) -#endif - -// Used to represent sides of things like planes. -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS -2 // necessary for polylib.c - -#define ON_VIS_EPSILON 0.01 // necessary for vvis (flow.c) -- again look into moving later! -#define EQUAL_EPSILON 0.001 // necessary for vbsp (faces.c) -- should look into moving it there? - -extern bool s_bMathlibInitialized; - -extern const Vector vec3_origin; -extern const QAngle vec3_angle; -extern const Quaternion quat_identity; -extern const Vector vec3_invalid; -extern const int nanmask; - -#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) - -FORCEINLINE vec_t DotProduct(const vec_t *v1, const vec_t *v2) -{ - return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; -} -FORCEINLINE void VectorSubtract(const vec_t *a, const vec_t *b, vec_t *c) -{ - c[0]=a[0]-b[0]; - c[1]=a[1]-b[1]; - c[2]=a[2]-b[2]; -} -FORCEINLINE void VectorAdd(const vec_t *a, const vec_t *b, vec_t *c) -{ - c[0]=a[0]+b[0]; - c[1]=a[1]+b[1]; - c[2]=a[2]+b[2]; -} -FORCEINLINE void VectorCopy(const vec_t *a, vec_t *b) -{ - b[0]=a[0]; - b[1]=a[1]; - b[2]=a[2]; -} -FORCEINLINE void VectorClear(vec_t *a) -{ - a[0]=a[1]=a[2]=0; -} - -FORCEINLINE float VectorMaximum(const vec_t *v) -{ - return max( v[0], max( v[1], v[2] ) ); -} - -FORCEINLINE float VectorMaximum(const Vector& v) -{ - return max( v.x, max( v.y, v.z ) ); -} - -FORCEINLINE void VectorScale (const float* in, vec_t scale, float* out) -{ - out[0] = in[0]*scale; - out[1] = in[1]*scale; - out[2] = in[2]*scale; -} - - -// Cannot be forceinline as they have overloads: -inline void VectorFill(vec_t *a, float b) -{ - a[0]=a[1]=a[2]=b; -} - -inline void VectorNegate(vec_t *a) -{ - a[0]=-a[0]; - a[1]=-a[1]; - a[2]=-a[2]; -} - - -//#define VectorMaximum(a) ( max( (a)[0], max( (a)[1], (a)[2] ) ) ) -#define Vector2Clear(x) {(x)[0]=(x)[1]=0;} -#define Vector2Negate(x) {(x)[0]=-((x)[0]);(x)[1]=-((x)[1]);} -#define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];} -#define Vector2Subtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];} -#define Vector2Add(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];} -#define Vector2Scale(a,b,c) {(c)[0]=(b)*(a)[0];(c)[1]=(b)*(a)[1];} - -// NJS: Some functions in VBSP still need to use these for dealing with mixing vec4's and shorts with vec_t's. -// remove when no longer needed. -#define VECTOR_COPY( A, B ) do { (B)[0] = (A)[0]; (B)[1] = (A)[1]; (B)[2]=(A)[2]; } while(0) -#define DOT_PRODUCT( A, B ) ( (A)[0]*(B)[0] + (A)[1]*(B)[1] + (A)[2]*(B)[2] ) - -FORCEINLINE void VectorMAInline( const float* start, float scale, const float* direction, float* dest ) -{ - dest[0]=start[0]+direction[0]*scale; - dest[1]=start[1]+direction[1]*scale; - dest[2]=start[2]+direction[2]*scale; -} - -FORCEINLINE void VectorMAInline( const Vector& start, float scale, const Vector& direction, Vector& dest ) -{ - dest.x=start.x+direction.x*scale; - dest.y=start.y+direction.y*scale; - dest.z=start.z+direction.z*scale; -} - -FORCEINLINE void VectorMA( const Vector& start, float scale, const Vector& direction, Vector& dest ) -{ - VectorMAInline(start, scale, direction, dest); -} - -FORCEINLINE void VectorMA( const float * start, float scale, const float *direction, float *dest ) -{ - VectorMAInline(start, scale, direction, dest); -} - - -int VectorCompare (const float *v1, const float *v2); - -inline float VectorLength(const float *v) -{ - return FastSqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + FLT_EPSILON ); -} - -void CrossProduct (const float *v1, const float *v2, float *cross); - -qboolean VectorsEqual( const float *v1, const float *v2 ); - -inline vec_t RoundInt (vec_t in) -{ - return floor(in + 0.5f); -} - -int Q_log2(int val); - -// Math routines done in optimized assembly math package routines -void inline SinCos( float radians, float *sine, float *cosine ) -{ -#if defined( _X360 ) - XMScalarSinCos( sine, cosine, radians ); -#elif defined( _WIN32 ) - _asm - { - fld DWORD PTR [radians] - fsincos - - mov edx, DWORD PTR [cosine] - mov eax, DWORD PTR [sine] - - fstp DWORD PTR [edx] - fstp DWORD PTR [eax] - } -#elif defined( _LINUX ) - register double __cosr, __sinr; - __asm __volatile__ - ("fsincos" - : "=t" (__cosr), "=u" (__sinr) : "0" (radians)); - - *sine = __sinr; - *cosine = __cosr; -#endif -} - -#define SIN_TABLE_SIZE 256 -#define FTOIBIAS 12582912.f -extern float SinCosTable[SIN_TABLE_SIZE]; - -inline float TableCos( float theta ) -{ - union - { - int i; - float f; - } ftmp; - - // ideally, the following should compile down to: theta * constant + constant, changing any of these constants from defines sometimes fubars this. - ftmp.f = theta * ( float )( SIN_TABLE_SIZE / ( 2.0f * M_PI ) ) + ( FTOIBIAS + ( SIN_TABLE_SIZE / 4 ) ); - return SinCosTable[ ftmp.i & ( SIN_TABLE_SIZE - 1 ) ]; -} - -inline float TableSin( float theta ) -{ - union - { - int i; - float f; - } ftmp; - - // ideally, the following should compile down to: theta * constant + constant - ftmp.f = theta * ( float )( SIN_TABLE_SIZE / ( 2.0f * M_PI ) ) + FTOIBIAS; - return SinCosTable[ ftmp.i & ( SIN_TABLE_SIZE - 1 ) ]; -} - -template -FORCEINLINE T Square( T const &a ) -{ - return a * a; -} - - -FORCEINLINE bool IsPowerOfTwo( uint x ) -{ - return ( x & ( x - 1 ) ) == 0; -} - -// return the smallest power of two >= x. -// returns 0 if x == 0 or x > 0x80000000 (ie numbers that would be negative if x was signed) -// NOTE: the old code took an int, and if you pass in an int of 0x80000000 casted to a uint, -// you'll get 0x80000000, which is correct for uints, instead of 0, which was correct for ints -FORCEINLINE uint SmallestPowerOfTwoGreaterOrEqual( uint x ) -{ - x -= 1; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return x + 1; -} - -// return the largest power of two <= x. Will return 0 if passed 0 -FORCEINLINE uint LargestPowerOfTwoLessThanOrEqual( uint x ) -{ - if ( x >= 0x80000000 ) - return 0x80000000; - - return SmallestPowerOfTwoGreaterOrEqual( x + 1 ) >> 1; -} - - -// Math routines for optimizing division -void FloorDivMod (double numer, double denom, int *quotient, int *rem); -int GreatestCommonDivisor (int i1, int i2); - -// Test for FPU denormal mode -bool IsDenormal( const float &val ); - -// MOVEMENT INFO -enum -{ - PITCH = 0, // up / down - YAW, // left / right - ROLL // fall over -}; - -void MatrixAngles( const matrix3x4_t & matrix, float *angles ); // !!!! -void MatrixVectors( const matrix3x4_t &matrix, Vector* pForward, Vector *pRight, Vector *pUp ); -void VectorTransform (const float *in1, const matrix3x4_t & in2, float *out); -void VectorITransform (const float *in1, const matrix3x4_t & in2, float *out); -void VectorRotate( const float *in1, const matrix3x4_t & in2, float *out); -void VectorRotate( const Vector &in1, const QAngle &in2, Vector &out ); -void VectorRotate( const Vector &in1, const Quaternion &in2, Vector &out ); -void VectorIRotate( const float *in1, const matrix3x4_t & in2, float *out); - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -QAngle TransformAnglesToLocalSpace( const QAngle &angles, const matrix3x4_t &parentMatrix ); -QAngle TransformAnglesToWorldSpace( const QAngle &angles, const matrix3x4_t &parentMatrix ); - -#endif - -void MatrixInitialize( matrix3x4_t &mat, const Vector &vecOrigin, const Vector &vecXAxis, const Vector &vecYAxis, const Vector &vecZAxis ); -void MatrixCopy( const matrix3x4_t &in, matrix3x4_t &out ); -void MatrixInvert( const matrix3x4_t &in, matrix3x4_t &out ); - -// Matrix equality test -bool MatricesAreEqual( const matrix3x4_t &src1, const matrix3x4_t &src2, float flTolerance = 1e-5 ); - -void MatrixGetColumn( const matrix3x4_t &in, int column, Vector &out ); -void MatrixSetColumn( const Vector &in, int column, matrix3x4_t &out ); - -//void DecomposeRotation( const matrix3x4_t &mat, float *out ); -void ConcatRotations (const matrix3x4_t &in1, const matrix3x4_t &in2, matrix3x4_t &out); -void ConcatTransforms (const matrix3x4_t &in1, const matrix3x4_t &in2, matrix3x4_t &out); - -// For identical interface w/ VMatrix -inline void MatrixMultiply ( const matrix3x4_t &in1, const matrix3x4_t &in2, matrix3x4_t &out ) -{ - ConcatTransforms( in1, in2, out ); -} - -void QuaternionSlerp( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); -void QuaternionSlerpNoAlign( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); -void QuaternionBlend( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); -void QuaternionBlendNoAlign( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); -void QuaternionIdentityBlend( const Quaternion &p, float t, Quaternion &qt ); -float QuaternionAngleDiff( const Quaternion &p, const Quaternion &q ); -void QuaternionScale( const Quaternion &p, float t, Quaternion &q ); -void QuaternionAlign( const Quaternion &p, const Quaternion &q, Quaternion &qt ); -float QuaternionDotProduct( const Quaternion &p, const Quaternion &q ); -void QuaternionConjugate( const Quaternion &p, Quaternion &q ); -void QuaternionInvert( const Quaternion &p, Quaternion &q ); -float QuaternionNormalize( Quaternion &q ); -void QuaternionAdd( const Quaternion &p, const Quaternion &q, Quaternion &qt ); -void QuaternionMult( const Quaternion &p, const Quaternion &q, Quaternion &qt ); -void QuaternionMatrix( const Quaternion &q, matrix3x4_t &matrix ); -void QuaternionMatrix( const Quaternion &q, const Vector &pos, matrix3x4_t &matrix ); -void QuaternionAngles( const Quaternion &q, QAngle &angles ); -void AngleQuaternion( const QAngle& angles, Quaternion &qt ); -void QuaternionAngles( const Quaternion &q, RadianEuler &angles ); -void AngleQuaternion( RadianEuler const &angles, Quaternion &qt ); -void QuaternionAxisAngle( const Quaternion &q, Vector &axis, float &angle ); -void AxisAngleQuaternion( const Vector &axis, float angle, Quaternion &q ); -void BasisToQuaternion( const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, Quaternion &q ); -void MatrixQuaternion( const matrix3x4_t &mat, Quaternion &q ); - -// A couple methods to find the dot product of a vector with a matrix row or column... -inline float MatrixRowDotProduct( const matrix3x4_t &in1, int row, const Vector& in2 ) -{ - Assert( (row >= 0) && (row < 3) ); - return DotProduct( in1[row], in2.Base() ); -} - -inline float MatrixColumnDotProduct( const matrix3x4_t &in1, int col, const Vector& in2 ) -{ - Assert( (col >= 0) && (col < 4) ); - return in1[0][col] * in2[0] + in1[1][col] * in2[1] + in1[2][col] * in2[2]; -} - -int __cdecl BoxOnPlaneSide (const float *emins, const float *emaxs, const cplane_t *plane); - -inline float anglemod(float a) -{ - a = (360.f/65536) * ((int)(a*(65536.f/360.0f)) & 65535); - return a; -} - -// Remap a value in the range [A,B] to [C,D]. -inline float RemapVal( float val, float A, float B, float C, float D) -{ - if ( A == B ) - return val >= B ? D : C; - return C + (D - C) * (val - A) / (B - A); -} - -inline float RemapValClamped( float val, float A, float B, float C, float D) -{ - if ( A == B ) - return val >= B ? D : C; - float cVal = (val - A) / (B - A); - cVal = clamp( cVal, 0.0f, 1.0f ); - - return C + (D - C) * cVal; -} - -// Returns A + (B-A)*flPercent. -// float Lerp( float flPercent, float A, float B ); -template -FORCEINLINE T Lerp( float flPercent, T const &A, T const &B ) -{ - return A + (B - A) * flPercent; -} - -FORCEINLINE float Sqr( float f ) -{ - return f*f; -} - -// 5-argument floating point linear interpolation. -// FLerp(f1,f2,i1,i2,x)= -// f1 at x=i1 -// f2 at x=i2 -// smooth lerp between f1 and f2 at x>i1 and xi2 -// -// If you know a function f(x)'s value (f1) at position i1, and its value (f2) at position i2, -// the function can be linearly interpolated with FLerp(f1,f2,i1,i2,x) -// i2=i1 will cause a divide by zero. -static inline float FLerp(float f1, float f2, float i1, float i2, float x) -{ - return f1+(f2-f1)*(x-i1)/(i2-i1); -} - - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -// YWB: Specialization for interpolating euler angles via quaternions... -template<> FORCEINLINE QAngle Lerp( float flPercent, const QAngle& q1, const QAngle& q2 ) -{ - // Avoid precision errors - if ( q1 == q2 ) - return q1; - - Quaternion src, dest; - - // Convert to quaternions - AngleQuaternion( q1, src ); - AngleQuaternion( q2, dest ); - - Quaternion result; - - // Slerp - QuaternionSlerp( src, dest, flPercent, result ); - - // Convert to euler - QAngle output; - QuaternionAngles( result, output ); - return output; -} - -#else - -#pragma error - -// NOTE NOTE: I haven't tested this!! It may not work! Check out interpolatedvar.cpp in the client dll to try it -template<> FORCEINLINE QAngleByValue Lerp( float flPercent, const QAngleByValue& q1, const QAngleByValue& q2 ) -{ - // Avoid precision errors - if ( q1 == q2 ) - return q1; - - Quaternion src, dest; - - // Convert to quaternions - AngleQuaternion( q1, src ); - AngleQuaternion( q2, dest ); - - Quaternion result; - - // Slerp - QuaternionSlerp( src, dest, flPercent, result ); - - // Convert to euler - QAngleByValue output; - QuaternionAngles( result, output ); - return output; -} - -#endif // VECTOR_NO_SLOW_OPERATIONS - - -// Swap two of anything. -template -FORCEINLINE void swap( T& x, T& y ) -{ - T temp = x; - x = y; - y = temp; -} - -template FORCEINLINE T AVG(T a, T b) -{ - return (a+b)/2; -} - -// number of elements in an array of static size -#define NELEMS(x) ((sizeof(x))/sizeof(x[0])) - -// XYZ macro, for printf type functions - ex printf("%f %f %f",XYZ(myvector)); -#define XYZ(v) (v).x,(v).y,(v).z - -// -// Returns a clamped value in the range [min, max]. -// -#define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) - -inline float Sign( float x ) -{ - return (x <0.0f) ? -1.0f : 1.0f; -} - -// -// Clamps the input integer to the given array bounds. -// Equivalent to the following, but without using any branches: -// -// if( n < 0 ) return 0; -// else if ( n > maxindex ) return maxindex; -// else return n; -// -// This is not always a clear performance win, but when you have situations where a clamped -// value is thrashing against a boundary this is a big win. (ie, valid, invalid, valid, invalid, ...) -// -// Note: This code has been run against all possible integers. -// -inline int ClampArrayBounds( int n, unsigned maxindex ) -{ - // mask is 0 if less than 4096, 0xFFFFFFFF if greater than - unsigned int inrangemask = 0xFFFFFFFF + (((unsigned) n) > maxindex ); - unsigned int lessthan0mask = 0xFFFFFFFF + ( n >= 0 ); - - // If the result was valid, set the result, (otherwise sets zero) - int result = (inrangemask & n); - - // if the result was out of range or zero. - result |= ((~inrangemask) & (~lessthan0mask)) & maxindex; - - return result; -} - - -#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ - (((p)->type < 3)? \ - ( \ - ((p)->dist <= (emins)[(p)->type])? \ - 1 \ - : \ - ( \ - ((p)->dist >= (emaxs)[(p)->type])?\ - 2 \ - : \ - 3 \ - ) \ - ) \ - : \ - BoxOnPlaneSide( (emins), (emaxs), (p))) - -//----------------------------------------------------------------------------- -// FIXME: Vector versions.... the float versions will go away hopefully soon! -//----------------------------------------------------------------------------- - -void AngleVectors (const QAngle& angles, Vector *forward); -void AngleVectors (const QAngle& angles, Vector *forward, Vector *right, Vector *up); -void AngleVectorsTranspose (const QAngle& angles, Vector *forward, Vector *right, Vector *up); -void AngleMatrix (const QAngle &angles, matrix3x4_t &mat ); -void AngleMatrix( const QAngle &angles, const Vector &position, matrix3x4_t &mat ); -void AngleMatrix (const RadianEuler &angles, matrix3x4_t &mat ); -void AngleMatrix( RadianEuler const &angles, const Vector &position, matrix3x4_t &mat ); -void AngleIMatrix (const QAngle &angles, matrix3x4_t &mat ); -void AngleIMatrix (const QAngle &angles, const Vector &position, matrix3x4_t &mat ); -void AngleIMatrix (const RadianEuler &angles, matrix3x4_t &mat ); -void VectorAngles( const Vector &forward, QAngle &angles ); -void VectorAngles( const Vector &forward, const Vector &pseudoup, QAngle &angles ); -void VectorMatrix( const Vector &forward, matrix3x4_t &mat ); -void VectorVectors( const Vector &forward, Vector &right, Vector &up ); -void SetIdentityMatrix( matrix3x4_t &mat ); -void SetScaleMatrix( float x, float y, float z, matrix3x4_t &dst ); -void MatrixBuildRotationAboutAxis( const Vector &vAxisOfRot, float angleDegrees, matrix3x4_t &dst ); - -inline void SetScaleMatrix( float flScale, matrix3x4_t &dst ) -{ - SetScaleMatrix( flScale, flScale, flScale, dst ); -} - -inline void SetScaleMatrix( const Vector& scale, matrix3x4_t &dst ) -{ - SetScaleMatrix( scale.x, scale.y, scale.z, dst ); -} - -// Computes the inverse transpose -void MatrixTranspose( matrix3x4_t& mat ); -void MatrixTranspose( const matrix3x4_t& src, matrix3x4_t& dst ); -void MatrixInverseTranspose( const matrix3x4_t& src, matrix3x4_t& dst ); - -inline void PositionMatrix( const Vector &position, matrix3x4_t &mat ) -{ - MatrixSetColumn( position, 3, mat ); -} - -inline void MatrixPosition( const matrix3x4_t &matrix, Vector &position ) -{ - MatrixGetColumn( matrix, 3, position ); -} - -inline void VectorRotate( const Vector& in1, const matrix3x4_t &in2, Vector &out) -{ - VectorRotate( &in1.x, in2, &out.x ); -} - -inline void VectorIRotate( const Vector& in1, const matrix3x4_t &in2, Vector &out) -{ - VectorIRotate( &in1.x, in2, &out.x ); -} - -inline void MatrixAngles( const matrix3x4_t &matrix, QAngle &angles ) -{ - MatrixAngles( matrix, &angles.x ); -} - -inline void MatrixAngles( const matrix3x4_t &matrix, QAngle &angles, Vector &position ) -{ - MatrixAngles( matrix, angles ); - MatrixPosition( matrix, position ); -} - -inline void MatrixAngles( const matrix3x4_t &matrix, RadianEuler &angles ) -{ - MatrixAngles( matrix, &angles.x ); - - angles.Init( DEG2RAD( angles.z ), DEG2RAD( angles.x ), DEG2RAD( angles.y ) ); -} - -void MatrixAngles( const matrix3x4_t &mat, RadianEuler &angles, Vector &position ); - -void MatrixAngles( const matrix3x4_t &mat, Quaternion &q, Vector &position ); - -inline int VectorCompare (const Vector& v1, const Vector& v2) -{ - return v1 == v2; -} - -inline void VectorTransform (const Vector& in1, const matrix3x4_t &in2, Vector &out) -{ - VectorTransform( &in1.x, in2, &out.x ); -} - -inline void VectorITransform (const Vector& in1, const matrix3x4_t &in2, Vector &out) -{ - VectorITransform( &in1.x, in2, &out.x ); -} - -/* -inline void DecomposeRotation( const matrix3x4_t &mat, Vector &out ) -{ - DecomposeRotation( mat, &out.x ); -} -*/ - -inline int BoxOnPlaneSide (const Vector& emins, const Vector& emaxs, const cplane_t *plane ) -{ - return BoxOnPlaneSide( &emins.x, &emaxs.x, plane ); -} - -inline void VectorFill(Vector& a, float b) -{ - a[0]=a[1]=a[2]=b; -} - -inline void VectorNegate(Vector& a) -{ - a[0] = -a[0]; - a[1] = -a[1]; - a[2] = -a[2]; -} - -inline vec_t VectorAvg(Vector& a) -{ - return ( a[0] + a[1] + a[2] ) / 3; -} - -//----------------------------------------------------------------------------- -// Box/plane test (slow version) -//----------------------------------------------------------------------------- -inline int FASTCALL BoxOnPlaneSide2 (const Vector& emins, const Vector& emaxs, const cplane_t *p, float tolerance = 0.f ) -{ - Vector corners[2]; - - if (p->normal[0] < 0) - { - corners[0][0] = emins[0]; - corners[1][0] = emaxs[0]; - } - else - { - corners[1][0] = emins[0]; - corners[0][0] = emaxs[0]; - } - - if (p->normal[1] < 0) - { - corners[0][1] = emins[1]; - corners[1][1] = emaxs[1]; - } - else - { - corners[1][1] = emins[1]; - corners[0][1] = emaxs[1]; - } - - if (p->normal[2] < 0) - { - corners[0][2] = emins[2]; - corners[1][2] = emaxs[2]; - } - else - { - corners[1][2] = emins[2]; - corners[0][2] = emaxs[2]; - } - - int sides = 0; - - float dist1 = DotProduct (p->normal, corners[0]) - p->dist; - if (dist1 >= tolerance) - sides = 1; - - float dist2 = DotProduct (p->normal, corners[1]) - p->dist; - if (dist2 < -tolerance) - sides |= 2; - - return sides; -} - -//----------------------------------------------------------------------------- -// Helpers for bounding box construction -//----------------------------------------------------------------------------- - -void ClearBounds (Vector& mins, Vector& maxs); -void AddPointToBounds (const Vector& v, Vector& mins, Vector& maxs); - -// -// COLORSPACE/GAMMA CONVERSION STUFF -// -void BuildGammaTable( float gamma, float texGamma, float brightness, int overbright ); - -// convert texture to linear 0..1 value -inline float TexLightToLinear( int c, int exponent ) -{ - extern float power2_n[256]; - Assert( exponent >= -128 && exponent <= 127 ); - return ( float )c * power2_n[exponent+128]; -} - - -// convert texture to linear 0..1 value -int LinearToTexture( float f ); -// converts 0..1 linear value to screen gamma (0..255) -int LinearToScreenGamma( float f ); -float TextureToLinear( int c ); - -// compressed color format -struct ColorRGBExp32 -{ - byte r, g, b; - signed char exponent; -}; - -void ColorRGBExp32ToVector( const ColorRGBExp32& in, Vector& out ); -void VectorToColorRGBExp32( const Vector& v, ColorRGBExp32 &c ); - -// solve for "x" where "a x^2 + b x + c = 0", return true if solution exists -bool SolveQuadratic( float a, float b, float c, float &root1, float &root2 ); - -// solves for "a, b, c" where "a x^2 + b x + c = y", return true if solution exists -bool SolveInverseQuadratic( float x1, float y1, float x2, float y2, float x3, float y3, float &a, float &b, float &c ); - -// solves for a,b,c specified as above, except that it always creates a monotonically increasing or -// decreasing curve if the data is monotonically increasing or decreasing. In order to enforce the -// monoticity condition, it is possible that the resulting quadratic will only approximate the data -// instead of interpolating it. This code is not especially fast. -bool SolveInverseQuadraticMonotonic( float x1, float y1, float x2, float y2, - float x3, float y3, float &a, float &b, float &c ); - - - - -// solves for "a, b, c" where "1/(a x^2 + b x + c ) = y", return true if solution exists -bool SolveInverseReciprocalQuadratic( float x1, float y1, float x2, float y2, float x3, float y3, float &a, float &b, float &c ); - -// rotate a vector around the Z axis (YAW) -void VectorYawRotate( const Vector& in, float flYaw, Vector &out); - - -// Bias takes an X value between 0 and 1 and returns another value between 0 and 1 -// The curve is biased towards 0 or 1 based on biasAmt, which is between 0 and 1. -// Lower values of biasAmt bias the curve towards 0 and higher values bias it towards 1. -// -// For example, with biasAmt = 0.2, the curve looks like this: -// -// 1 -// | * -// | * -// | * -// | ** -// | ** -// | **** -// |********* -// |___________________ -// 0 1 -// -// -// With biasAmt = 0.8, the curve looks like this: -// -// 1 -// | ************** -// | ** -// | * -// | * -// |* -// |* -// |* -// |___________________ -// 0 1 -// -// With a biasAmt of 0.5, Bias returns X. -float Bias( float x, float biasAmt ); - - -// Gain is similar to Bias, but biasAmt biases towards or away from 0.5. -// Lower bias values bias towards 0.5 and higher bias values bias away from it. -// -// For example, with biasAmt = 0.2, the curve looks like this: -// -// 1 -// | * -// | * -// | ** -// | *************** -// | ** -// | * -// |* -// |___________________ -// 0 1 -// -// -// With biasAmt = 0.8, the curve looks like this: -// -// 1 -// | ***** -// | *** -// | * -// | * -// | * -// | *** -// |***** -// |___________________ -// 0 1 -float Gain( float x, float biasAmt ); - - -// SmoothCurve maps a 0-1 value into another 0-1 value based on a cosine wave -// where the derivatives of the function at 0 and 1 (and 0.5) are 0. This is useful for -// any fadein/fadeout effect where it should start and end smoothly. -// -// The curve looks like this: -// -// 1 -// | ** -// | * * -// | * * -// | * * -// | * * -// | ** ** -// |*** *** -// |___________________ -// 0 1 -// -float SmoothCurve( float x ); - - -// This works like SmoothCurve, with two changes: -// -// 1. Instead of the curve peaking at 0.5, it will peak at flPeakPos. -// (So if you specify flPeakPos=0.2, then the peak will slide to the left). -// -// 2. flPeakSharpness is a 0-1 value controlling the sharpness of the peak. -// Low values blunt the peak and high values sharpen the peak. -float SmoothCurve_Tweak( float x, float flPeakPos=0.5, float flPeakSharpness=0.5 ); - - -//float ExponentialDecay( float halflife, float dt ); -//float ExponentialDecay( float decayTo, float decayTime, float dt ); - -// halflife is time for value to reach 50% -inline float ExponentialDecay( float halflife, float dt ) -{ - // log(0.5) == -0.69314718055994530941723212145818 - return expf( -0.69314718f / halflife * dt); -} - -// decayTo is factor the value should decay to in decayTime -inline float ExponentialDecay( float decayTo, float decayTime, float dt ) -{ - return expf( logf( decayTo ) / decayTime * dt); -} - -// Get the integrated distanced traveled -// decayTo is factor the value should decay to in decayTime -// dt is the time relative to the last velocity update -inline float ExponentialDecayIntegral( float decayTo, float decayTime, float dt ) -{ - return (powf( decayTo, dt / decayTime) * decayTime - decayTime) / logf( decayTo ); -} - -// hermite basis function for smooth interpolation -// Similar to Gain() above, but very cheap to call -// value should be between 0 & 1 inclusive -inline float SimpleSpline( float value ) -{ - float valueSquared = value * value; - - // Nice little ease-in, ease-out spline-like curve - return (3 * valueSquared - 2 * valueSquared * value); -} - -// remaps a value in [startInterval, startInterval+rangeInterval] from linear to -// spline using SimpleSpline -inline float SimpleSplineRemapVal( float val, float A, float B, float C, float D) -{ - if ( A == B ) - return val >= B ? D : C; - float cVal = (val - A) / (B - A); - return C + (D - C) * SimpleSpline( cVal ); -} - -// remaps a value in [startInterval, startInterval+rangeInterval] from linear to -// spline using SimpleSpline -inline float SimpleSplineRemapValClamped( float val, float A, float B, float C, float D ) -{ - if ( A == B ) - return val >= B ? D : C; - float cVal = (val - A) / (B - A); - cVal = clamp( cVal, 0.0f, 1.0f ); - return C + (D - C) * SimpleSpline( cVal ); -} - -FORCEINLINE int RoundFloatToInt(float f) -{ -#if defined( _X360 ) -#ifdef Assert - Assert( IsFPUControlWordSet() ); -#endif - union - { - double flResult; - int pResult[2]; - }; - flResult = __fctiw( f ); - return pResult[1]; -#else // !X360 - int nResult; -#if defined( _WIN32 ) - __asm - { - fld f - fistp nResult - } -#elif _LINUX - __asm __volatile__ ( - "fistpl %0;": "=m" (nResult): "t" (f) : "st" - ); -#endif - return nResult; -#endif -} - -FORCEINLINE unsigned char RoundFloatToByte(float f) -{ -#if defined( _X360 ) -#ifdef Assert - Assert( IsFPUControlWordSet() ); -#endif - union - { - double flResult; - int pIntResult[2]; - unsigned char pResult[8]; - }; - flResult = __fctiw( f ); -#ifdef Assert - Assert( pIntResult[1] >= 0 && pIntResult[1] <= 255 ); -#endif - return pResult[8]; - -#else // !X360 - - int nResult; - -#if defined( _WIN32 ) - __asm - { - fld f - fistp nResult - } -#elif _LINUX - __asm __volatile__ ( - "fistpl %0;": "=m" (nResult): "t" (f) : "st" - ); -#endif - -#ifdef Assert - Assert( nResult >= 0 && nResult <= 255 ); -#endif - return nResult; - -#endif -} - -FORCEINLINE unsigned long RoundFloatToUnsignedLong(float f) -{ -#if defined( _X360 ) -#ifdef Assert - Assert( IsFPUControlWordSet() ); -#endif - union - { - double flResult; - int pIntResult[2]; - unsigned long pResult[2]; - }; - flResult = __fctiw( f ); - Assert( pIntResult[1] >= 0 ); - return pResult[1]; -#else // !X360 - - unsigned char nResult[8]; - -#if defined( _WIN32 ) - __asm - { - fld f - fistp qword ptr nResult - } -#elif _LINUX - __asm __volatile__ ( - "fistpl %0;": "=m" (nResult): "t" (f) : "st" - ); -#endif - - return *((unsigned long*)nResult); -#endif -} - -FORCEINLINE bool IsIntegralValue( float flValue, float flTolerance = 0.001f ) -{ - return fabs( RoundFloatToInt( flValue ) - flValue ) < flTolerance; -} - -// Fast, accurate ftol: -FORCEINLINE int Float2Int( float a ) -{ -#if defined( _X360 ) - union - { - double flResult; - int pResult[2]; - }; - flResult = __fctiwz( a ); - return pResult[1]; -#else // !X360 - - int RetVal; - -#if defined( _WIN32 ) - int CtrlwdHolder; - int CtrlwdSetter; - __asm - { - fld a // push 'a' onto the FP stack - fnstcw CtrlwdHolder // store FPU control word - movzx eax, CtrlwdHolder // move and zero extend word into eax - and eax, 0xFFFFF3FF // set all bits except rounding bits to 1 - or eax, 0x00000C00 // set rounding mode bits to round towards zero - mov CtrlwdSetter, eax // Prepare to set the rounding mode -- prepare to enter plaid! - fldcw CtrlwdSetter // Entering plaid! - fistp RetVal // Store and converted (to int) result - fldcw CtrlwdHolder // Restore control word - } -#elif _LINUX - RetVal = static_cast( a ); -#endif - - return RetVal; -#endif -} - -// Over 15x faster than: (int)floor(value) -inline int Floor2Int( float a ) -{ - int RetVal; - -#if defined( _X360 ) - RetVal = (int)floor( a ); -#elif defined( _WIN32 ) - int CtrlwdHolder; - int CtrlwdSetter; - __asm - { - fld a // push 'a' onto the FP stack - fnstcw CtrlwdHolder // store FPU control word - movzx eax, CtrlwdHolder // move and zero extend word into eax - and eax, 0xFFFFF3FF // set all bits except rounding bits to 1 - or eax, 0x00000400 // set rounding mode bits to round down - mov CtrlwdSetter, eax // Prepare to set the rounding mode -- prepare to enter plaid! - fldcw CtrlwdSetter // Entering plaid! - fistp RetVal // Store floored and converted (to int) result - fldcw CtrlwdHolder // Restore control word - } -#elif _LINUX - RetVal = static_cast( floor(a) ); -#endif - - return RetVal; -} - -//----------------------------------------------------------------------------- -// Fast color conversion from float to unsigned char -//----------------------------------------------------------------------------- -FORCEINLINE unsigned char FastFToC( float c ) -{ - volatile float dc; - - // ieee trick - dc = c * 255.0f + (float)(1 << 23); - - // return the lsb -#if defined( _X360 ) - return ((unsigned char*)&dc)[3]; -#else - return *(unsigned char*)&dc; -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Bound input float to .001 (millisecond) boundary -// Input : in - -// Output : inline float -//----------------------------------------------------------------------------- -inline float ClampToMsec( float in ) -{ - int msec = Floor2Int( in * 1000.0f + 0.5f ); - return msec / 1000.0f; -} - -// Over 15x faster than: (int)ceil(value) -inline int Ceil2Int( float a ) -{ - int RetVal; - -#if defined( _X360 ) - RetVal = (int)ceil( a ); -#elif defined( _WIN32 ) - int CtrlwdHolder; - int CtrlwdSetter; - __asm - { - fld a // push 'a' onto the FP stack - fnstcw CtrlwdHolder // store FPU control word - movzx eax, CtrlwdHolder // move and zero extend word into eax - and eax, 0xFFFFF3FF // set all bits except rounding bits to 1 - or eax, 0x00000800 // set rounding mode bits to round down - mov CtrlwdSetter, eax // Prepare to set the rounding mode -- prepare to enter plaid! - fldcw CtrlwdSetter // Entering plaid! - fistp RetVal // Store floored and converted (to int) result - fldcw CtrlwdHolder // Restore control word - } -#elif _LINUX - RetVal = static_cast( ceil(a) ); -#endif - - return RetVal; -} - - -// Regular signed area of triangle -#define TriArea2D( A, B, C ) \ - ( 0.5f * ( ( B.x - A.x ) * ( C.y - A.y ) - ( B.y - A.y ) * ( C.x - A.x ) ) ) - -// This version doesn't premultiply by 0.5f, so it's the area of the rectangle instead -#define TriArea2DTimesTwo( A, B, C ) \ - ( ( ( B.x - A.x ) * ( C.y - A.y ) - ( B.y - A.y ) * ( C.x - A.x ) ) ) - - -// Get the barycentric coordinates of "pt" in triangle [A,B,C]. -inline void GetBarycentricCoords2D( - Vector2D const &A, - Vector2D const &B, - Vector2D const &C, - Vector2D const &pt, - float bcCoords[3] ) -{ - // Note, because to top and bottom are both x2, the issue washes out in the composite - float invTriArea = 1.0f / TriArea2DTimesTwo( A, B, C ); - - // NOTE: We assume here that the lightmap coordinate vertices go counterclockwise. - // If not, TriArea2D() is negated so this works out right. - bcCoords[0] = TriArea2DTimesTwo( B, C, pt ) * invTriArea; - bcCoords[1] = TriArea2DTimesTwo( C, A, pt ) * invTriArea; - bcCoords[2] = TriArea2DTimesTwo( A, B, pt ) * invTriArea; -} - - -// Return true of the sphere might touch the box (the sphere is actually treated -// like a box itself, so this may return true if the sphere's bounding box touches -// a corner of the box but the sphere itself doesn't). -inline bool QuickBoxSphereTest( - const Vector& vOrigin, - float flRadius, - const Vector& bbMin, - const Vector& bbMax ) -{ - return vOrigin.x - flRadius < bbMax.x && vOrigin.x + flRadius > bbMin.x && - vOrigin.y - flRadius < bbMax.y && vOrigin.y + flRadius > bbMin.y && - vOrigin.z - flRadius < bbMax.z && vOrigin.z + flRadius > bbMin.z; -} - - -// Return true of the boxes intersect (but not if they just touch). -inline bool QuickBoxIntersectTest( - const Vector& vBox1Min, - const Vector& vBox1Max, - const Vector& vBox2Min, - const Vector& vBox2Max ) -{ - return - vBox1Min.x < vBox2Max.x && vBox1Max.x > vBox2Min.x && - vBox1Min.y < vBox2Max.y && vBox1Max.y > vBox2Min.y && - vBox1Min.z < vBox2Max.z && vBox1Max.z > vBox2Min.z; -} - - -extern float GammaToLinearFullRange( float gamma ); -extern float LinearToGammaFullRange( float linear ); -extern float GammaToLinear( float gamma ); -extern float LinearToGamma( float linear ); - -extern float SrgbGammaToLinear( float flSrgbGammaValue ); -extern float SrgbLinearToGamma( float flLinearValue ); -extern float X360GammaToLinear( float fl360GammaValue ); -extern float X360LinearToGamma( float flLinearValue ); -extern float SrgbGammaTo360Gamma( float flSrgbGammaValue ); - -// linear (0..4) to screen corrected vertex space (0..1?) -FORCEINLINE float LinearToVertexLight( float f ) -{ - extern float lineartovertex[4096]; - - // Gotta clamp before the multiply; could overflow... - // assume 0..4 range - int i = RoundFloatToInt( f * 1024.f ); - - // Presumably the comman case will be not to clamp, so check that first: - if( (unsigned)i > 4095 ) - { - if ( i < 0 ) - i = 0; // Compare to zero instead of 4095 to save 4 bytes in the instruction stream - else - i = 4095; - } - - return lineartovertex[i]; -} - - -FORCEINLINE unsigned char LinearToLightmap( float f ) -{ - extern unsigned char lineartolightmap[4096]; - - // Gotta clamp before the multiply; could overflow... - int i = RoundFloatToInt( f * 1024.f ); // assume 0..4 range - - // Presumably the comman case will be not to clamp, so check that first: - if ( (unsigned)i > 4095 ) - { - if ( i < 0 ) - i = 0; // Compare to zero instead of 4095 to save 4 bytes in the instruction stream - else - i = 4095; - } - - return lineartolightmap[i]; -} - -FORCEINLINE void ColorClamp( Vector& color ) -{ - float maxc = max( color.x, max( color.y, color.z ) ); - if ( maxc > 1.0f ) - { - float ooMax = 1.0f / maxc; - color.x *= ooMax; - color.y *= ooMax; - color.z *= ooMax; - } - - if ( color[0] < 0.f ) color[0] = 0.f; - if ( color[1] < 0.f ) color[1] = 0.f; - if ( color[2] < 0.f ) color[2] = 0.f; -} - -inline void ColorClampTruncate( Vector& color ) -{ - if (color[0] > 1.0f) color[0] = 1.0f; else if (color[0] < 0.0f) color[0] = 0.0f; - if (color[1] > 1.0f) color[1] = 1.0f; else if (color[1] < 0.0f) color[1] = 0.0f; - if (color[2] > 1.0f) color[2] = 1.0f; else if (color[2] < 0.0f) color[2] = 0.0f; -} - -// Interpolate a Catmull-Rom spline. -// t is a [0,1] value and interpolates a curve between p2 and p3. -void Catmull_Rom_Spline( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector &output ); - -// Interpolate a Catmull-Rom spline. -// Returns the tangent of the point at t of the spline -void Catmull_Rom_Spline_Tangent( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector &output ); - -// area under the curve [0..t] -void Catmull_Rom_Spline_Integral( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// area under the curve [0..1] -void Catmull_Rom_Spline_Integral( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - Vector& output ); - -// Interpolate a Catmull-Rom spline. -// Normalize p2->p1 and p3->p4 to be the same length as p2->p3 -void Catmull_Rom_Spline_Normalize( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector &output ); - -// area under the curve [0..t] -// Normalize p2->p1 and p3->p4 to be the same length as p2->p3 -void Catmull_Rom_Spline_Integral_Normalize( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// Interpolate a Catmull-Rom spline. -// Normalize p2.x->p1.x and p3.x->p4.x to be the same length as p2.x->p3.x -void Catmull_Rom_Spline_NormalizeX( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector &output ); - -// area under the curve [0..t] -void Catmull_Rom_Spline_NormalizeX( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// Interpolate a Hermite spline. -// t is a [0,1] value and interpolates a curve between p1 and p2 with the deltas d1 and d2. -void Hermite_Spline( - const Vector &p1, - const Vector &p2, - const Vector &d1, - const Vector &d2, - float t, - Vector& output ); - -float Hermite_Spline( - float p1, - float p2, - float d1, - float d2, - float t ); - -// t is a [0,1] value and interpolates a curve between p1 and p2 with the slopes p0->p1 and p1->p2 -void Hermite_Spline( - const Vector &p0, - const Vector &p1, - const Vector &p2, - float t, - Vector& output ); - -float Hermite_Spline( - float p0, - float p1, - float p2, - float t ); - - -void Hermite_SplineBasis( float t, float basis[] ); - -void Hermite_Spline( - const Quaternion &q0, - const Quaternion &q1, - const Quaternion &q2, - float t, - Quaternion &output ); - - -// See http://en.wikipedia.org/wiki/Kochanek-Bartels_curves -// -// Tension: -1 = Round -> 1 = Tight -// Bias: -1 = Pre-shoot (bias left) -> 1 = Post-shoot (bias right) -// Continuity: -1 = Box corners -> 1 = Inverted corners -// -// If T=B=C=0 it's the same matrix as Catmull-Rom. -// If T=1 & B=C=0 it's the same as Cubic. -// If T=B=0 & C=-1 it's just linear interpolation -// -// See http://news.povray.org/povray.binaries.tutorials/attachment/%3CXns91B880592482seed7@povray.org%3E/Splines.bas.txt -// for example code and descriptions of various spline types... -// -void Kochanek_Bartels_Spline( - float tension, - float bias, - float continuity, - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -void Kochanek_Bartels_Spline_NormalizeX( - float tension, - float bias, - float continuity, - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// See link at Kochanek_Bartels_Spline for info on the basis matrix used -void Cubic_Spline( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -void Cubic_Spline_NormalizeX( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// See link at Kochanek_Bartels_Spline for info on the basis matrix used -void BSpline( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -void BSpline_NormalizeX( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// See link at Kochanek_Bartels_Spline for info on the basis matrix used -void Parabolic_Spline( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -void Parabolic_Spline_NormalizeX( - const Vector &p1, - const Vector &p2, - const Vector &p3, - const Vector &p4, - float t, - Vector& output ); - -// quintic interpolating polynomial from Perlin. -// 0->0, 1->1, smooth-in between with smooth tangents -FORCEINLINE float QuinticInterpolatingPolynomial(float t) -{ - // 6t^5-15t^4+10t^3 - return t * t * t *( t * ( t* 6.0 - 15.0 ) + 10.0 ); -} - -// given a table of sorted tabulated positions, return the two indices and blendfactor to linear -// interpolate. Does a search. Can be used to find the blend value to interpolate between -// keyframes. -void GetInterpolationData( float const *pKnotPositions, - float const *pKnotValues, - int nNumValuesinList, - int nInterpolationRange, - float flPositionToInterpolateAt, - bool bWrap, - float *pValueA, - float *pValueB, - float *pInterpolationValue); - -float RangeCompressor( float flValue, float flMin, float flMax, float flBase ); - -// Get the minimum distance from vOrigin to the bounding box defined by [mins,maxs] -// using voronoi regions. -// 0 is returned if the origin is inside the box. -float CalcSqrDistanceToAABB( const Vector &mins, const Vector &maxs, const Vector &point ); -void CalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point, Vector &closestOut ); -void CalcSqrDistAndClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point, Vector &closestOut, float &distSqrOut ); - -inline float CalcDistanceToAABB( const Vector &mins, const Vector &maxs, const Vector &point ) -{ - float flDistSqr = CalcSqrDistanceToAABB( mins, maxs, point ); - return sqrt(flDistSqr); -} - -// Get the closest point from P to the (infinite) line through vLineA and vLineB and -// calculate the shortest distance from P to the line. -// If you pass in a value for t, it will tell you the t for (A + (B-A)t) to get the closest point. -// If the closest point lies on the segment between A and B, then 0 <= t <= 1. -void CalcClosestPointOnLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, Vector &vClosest, float *t=0 ); -float CalcDistanceToLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *t=0 ); -float CalcDistanceSqrToLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *t=0 ); - -// The same three functions as above, except now the line is closed between A and B. -void CalcClosestPointOnLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, Vector &vClosest, float *t=0 ); -float CalcDistanceToLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *t=0 ); -float CalcDistanceSqrToLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *t=0 ); - -// A function to compute the closes line segment connnection two lines (or false if the lines are parallel, etc.) -bool CalcLineToLineIntersectionSegment( - const Vector& p1,const Vector& p2,const Vector& p3,const Vector& p4,Vector *s1,Vector *s2, - float *t1, float *t2 ); - -// The above functions in 2D -void CalcClosestPointOnLine2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, Vector2D &vClosest, float *t=0 ); -float CalcDistanceToLine2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, float *t=0 ); -float CalcDistanceSqrToLine2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, float *t=0 ); -void CalcClosestPointOnLineSegment2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, Vector2D &vClosest, float *t=0 ); -float CalcDistanceToLineSegment2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, float *t=0 ); -float CalcDistanceSqrToLineSegment2D( Vector2D const &P, Vector2D const &vLineA, Vector2D const &vLineB, float *t=0 ); - -// Init the mathlib -void MathLib_Init( float gamma = 2.2f, float texGamma = 2.2f, float brightness = 0.0f, int overbright = 2.0f, bool bAllow3DNow = true, bool bAllowSSE = true, bool bAllowSSE2 = true, bool bAllowMMX = true ); -bool MathLib_3DNowEnabled( void ); -bool MathLib_MMXEnabled( void ); -bool MathLib_SSEEnabled( void ); -bool MathLib_SSE2Enabled( void ); - -float Approach( float target, float value, float speed ); -float ApproachAngle( float target, float value, float speed ); -float AngleDiff( float destAngle, float srcAngle ); -float AngleDistance( float next, float cur ); -float AngleNormalize( float angle ); - -// ensure that 0 <= angle <= 360 -float AngleNormalizePositive( float angle ); - -bool AnglesAreEqual( float a, float b, float tolerance = 0.0f ); - - -void RotationDeltaAxisAngle( const QAngle &srcAngles, const QAngle &destAngles, Vector &deltaAxis, float &deltaAngle ); -void RotationDelta( const QAngle &srcAngles, const QAngle &destAngles, QAngle *out ); - -void ComputeTrianglePlane( const Vector& v1, const Vector& v2, const Vector& v3, Vector& normal, float& intercept ); -int PolyFromPlane( Vector *outVerts, const Vector& normal, float dist, float fHalfScale = 9000.0f ); -int ClipPolyToPlane( Vector *inVerts, int vertCount, Vector *outVerts, const Vector& normal, float dist, float fOnPlaneEpsilon = 0.1f ); -int ClipPolyToPlane_Precise( double *inVerts, int vertCount, double *outVerts, const double *normal, double dist, double fOnPlaneEpsilon = 0.1 ); - -//----------------------------------------------------------------------------- -// Computes a reasonable tangent space for a triangle -//----------------------------------------------------------------------------- -void CalcTriangleTangentSpace( const Vector &p0, const Vector &p1, const Vector &p2, - const Vector2D &t0, const Vector2D &t1, const Vector2D& t2, - Vector &sVect, Vector &tVect ); - -//----------------------------------------------------------------------------- -// Transforms a AABB into another space; which will inherently grow the box. -//----------------------------------------------------------------------------- -void TransformAABB( const matrix3x4_t &in1, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ); - -//----------------------------------------------------------------------------- -// Uses the inverse transform of in1 -//----------------------------------------------------------------------------- -void ITransformAABB( const matrix3x4_t &in1, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ); - -//----------------------------------------------------------------------------- -// Rotates a AABB into another space; which will inherently grow the box. -// (same as TransformAABB, but doesn't take the translation into account) -//----------------------------------------------------------------------------- -void RotateAABB( const matrix3x4_t &in1, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ); - -//----------------------------------------------------------------------------- -// Uses the inverse transform of in1 -//----------------------------------------------------------------------------- -void IRotateAABB( const matrix3x4_t &in1, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ); - -//----------------------------------------------------------------------------- -// Transform a plane -//----------------------------------------------------------------------------- -inline void MatrixTransformPlane( const matrix3x4_t &src, const cplane_t &inPlane, cplane_t &outPlane ) -{ - // What we want to do is the following: - // 1) transform the normal into the new space. - // 2) Determine a point on the old plane given by plane dist * plane normal - // 3) Transform that point into the new space - // 4) Plane dist = DotProduct( new normal, new point ) - - // An optimized version, which works if the plane is orthogonal. - // 1) Transform the normal into the new space - // 2) Realize that transforming the old plane point into the new space - // is given by [ d * n'x + Tx, d * n'y + Ty, d * n'z + Tz ] - // where d = old plane dist, n' = transformed normal, Tn = translational component of transform - // 3) Compute the new plane dist using the dot product of the normal result of #2 - - // For a correct result, this should be an inverse-transpose matrix - // but that only matters if there are nonuniform scale or skew factors in this matrix. - VectorRotate( inPlane.normal, src, outPlane.normal ); - outPlane.dist = inPlane.dist * DotProduct( outPlane.normal, outPlane.normal ); - outPlane.dist += outPlane.normal.x * src[0][3] + outPlane.normal.y * src[1][3] + outPlane.normal.z * src[2][3]; -} - -inline void MatrixITransformPlane( const matrix3x4_t &src, const cplane_t &inPlane, cplane_t &outPlane ) -{ - // The trick here is that Tn = translational component of transform, - // but for an inverse transform, Tn = - R^-1 * T - Vector vecTranslation; - MatrixGetColumn( src, 3, vecTranslation ); - - Vector vecInvTranslation; - VectorIRotate( vecTranslation, src, vecInvTranslation ); - - VectorIRotate( inPlane.normal, src, outPlane.normal ); - outPlane.dist = inPlane.dist * DotProduct( outPlane.normal, outPlane.normal ); - outPlane.dist -= outPlane.normal.x * vecInvTranslation[0] + outPlane.normal.y * vecInvTranslation[1] + outPlane.normal.z * vecInvTranslation[2]; -} - -int CeilPow2( int in ); -int FloorPow2( int in ); - -FORCEINLINE float * UnpackNormal_HEND3N( const unsigned int *pPackedNormal, float *pNormal ) -{ - int temp[3]; - temp[0] = ((*pPackedNormal >> 0L) & 0x7ff); - if ( temp[0] & 0x400 ) - { - temp[0] = 2048 - temp[0]; - } - temp[1] = ((*pPackedNormal >> 11L) & 0x7ff); - if ( temp[1] & 0x400 ) - { - temp[1] = 2048 - temp[1]; - } - temp[2] = ((*pPackedNormal >> 22L) & 0x3ff); - if ( temp[2] & 0x200 ) - { - temp[2] = 1024 - temp[2]; - } - pNormal[0] = (float)temp[0] * 1.0f/1023.0f; - pNormal[1] = (float)temp[1] * 1.0f/1023.0f; - pNormal[2] = (float)temp[2] * 1.0f/511.0f; - return pNormal; -} - -FORCEINLINE unsigned int * PackNormal_HEND3N( const float *pNormal, unsigned int *pPackedNormal ) -{ - int temp[3]; - - temp[0] = Float2Int( pNormal[0] * 1023.0f ); - temp[1] = Float2Int( pNormal[1] * 1023.0f ); - temp[2] = Float2Int( pNormal[2] * 511.0f ); - - // the normal is out of bounds, determine the source and fix - // clamping would be even more of a slowdown here - Assert( temp[0] >= -1023 && temp[0] <= 1023 ); - Assert( temp[1] >= -1023 && temp[1] <= 1023 ); - Assert( temp[2] >= -511 && temp[2] <= 511 ); - - *pPackedNormal = ( ( temp[2] & 0x3ff ) << 22L ) | - ( ( temp[1] & 0x7ff ) << 11L ) | - ( ( temp[0] & 0x7ff ) << 0L ); - return pPackedNormal; -} - -FORCEINLINE unsigned int * PackNormal_HEND3N( float nx, float ny, float nz, unsigned int *pPackedNormal ) -{ - int temp[3]; - - temp[0] = Float2Int( nx * 1023.0f ); - temp[1] = Float2Int( ny * 1023.0f ); - temp[2] = Float2Int( nz * 511.0f ); - - // the normal is out of bounds, determine the source and fix - // clamping would be even more of a slowdown here - Assert( temp[0] >= -1023 && temp[0] <= 1023 ); - Assert( temp[1] >= -1023 && temp[1] <= 1023 ); - Assert( temp[2] >= -511 && temp[2] <= 511 ); - - *pPackedNormal = ( ( temp[2] & 0x3ff ) << 22L ) | - ( ( temp[1] & 0x7ff ) << 11L ) | - ( ( temp[0] & 0x7ff ) << 0L ); - return pPackedNormal; -} - -FORCEINLINE float * UnpackNormal_SHORT2( const unsigned int *pPackedNormal, float *pNormal, bool bIsTangent = FALSE ) -{ - // Unpacks from Jason's 2-short format (fills in a 4th binormal-sign (+1/-1) value, if this is a tangent vector) - - // FIXME: short math is slow on 360 - use ints here instead (bit-twiddle to deal w/ the sign bits) - short iX = (*pPackedNormal & 0x0000FFFF); - short iY = (*pPackedNormal & 0xFFFF0000) >> 16; - - float zSign = +1; - if ( iX < 0 ) - { - zSign = -1; - iX = -iX; - } - float tSign = +1; - if ( iY < 0 ) - { - tSign = -1; - iY = -iY; - } - - pNormal[0] = ( iX - 16384.0f ) / 16384.0f; - pNormal[1] = ( iY - 16384.0f ) / 16384.0f; - pNormal[2] = zSign*sqrtf( 1.0f - ( pNormal[0]*pNormal[0] + pNormal[1]*pNormal[1] ) ); - if ( bIsTangent ) - { - pNormal[3] = tSign; - } - - return pNormal; -} - -FORCEINLINE unsigned int * PackNormal_SHORT2( float nx, float ny, float nz, unsigned int *pPackedNormal, float binormalSign = +1.0f ) -{ - // Pack a vector (ASSUMED TO BE NORMALIZED) into Jason's 4-byte (SHORT2) format. - // This simply reconstructs Z from X & Y. It uses the sign bits of the X & Y coords - // to reconstruct the sign of Z and, if this is a tangent vector, the sign of the - // binormal (this is needed because tangent/binormal vectors are supposed to follow - // UV gradients, but shaders reconstruct the binormal from the tangent and normal - // assuming that they form a right-handed basis). - - nx += 1; // [-1,+1] -> [0,2] - ny += 1; - nx *= 16384.0f; // [ 0, 2] -> [0,32768] - ny *= 16384.0f; - - // '0' and '32768' values are invalid encodings - nx = max( nx, 1.0f ); // Make sure there are no zero values - ny = max( ny, 1.0f ); - nx = min( nx, 32767.0f ); // Make sure there are no 32768 values - ny = min( ny, 32767.0f ); - - if ( nz < 0.0f ) - nx = -nx; // Set the sign bit for z - - ny *= binormalSign; // Set the sign bit for the binormal (use when encoding a tangent vector) - - // FIXME: short math is slow on 360 - use ints here instead (bit-twiddle to deal w/ the sign bits), also use Float2Int() - short sX = (short)nx; // signed short [1,32767] - short sY = (short)ny; - - *pPackedNormal = ( sX & 0x0000FFFF ) | ( sY << 16 ); // NOTE: The mask is necessary (if sX is negative and cast to an int...) - - return pPackedNormal; -} - -FORCEINLINE unsigned int * PackNormal_SHORT2( const float *pNormal, unsigned int *pPackedNormal, float binormalSign = +1.0f ) -{ - return PackNormal_SHORT2( pNormal[0], pNormal[1], pNormal[2], pPackedNormal, binormalSign ); -} - -// Unpacks a UBYTE4 normal (for a tangent, the result's fourth component receives the binormal 'sign') -FORCEINLINE float * UnpackNormal_UBYTE4( const unsigned int *pPackedNormal, float *pNormal, bool bIsTangent = FALSE ) -{ - unsigned char cX, cY; - if ( bIsTangent ) - { - cX = *pPackedNormal >> 16; // Unpack Z - cY = *pPackedNormal >> 24; // Unpack W - } - else - { - cX = *pPackedNormal >> 0; // Unpack X - cY = *pPackedNormal >> 8; // Unpack Y - } - - float x = cX - 128.0f; - float y = cY - 128.0f; - float z; - - float zSignBit = x < 0 ? 1.0f : 0.0f; // z and t negative bits (like slt asm instruction) - float tSignBit = y < 0 ? 1.0f : 0.0f; - float zSign = -( 2*zSignBit - 1 ); // z and t signs - float tSign = -( 2*tSignBit - 1 ); - - x = x*zSign - zSignBit; // 0..127 - y = y*tSign - tSignBit; - x = x - 64; // -64..63 - y = y - 64; - - float xSignBit = x < 0 ? 1.0f : 0.0f; // x and y negative bits (like slt asm instruction) - float ySignBit = y < 0 ? 1.0f : 0.0f; - float xSign = -( 2*xSignBit - 1 ); // x and y signs - float ySign = -( 2*ySignBit - 1 ); - - x = ( x*xSign - xSignBit ) / 63.0f; // 0..1 range - y = ( y*ySign - ySignBit ) / 63.0f; - z = 1.0f - x - y; - - float oolen = 1.0f / sqrt( x*x + y*y + z*z ); // Normalize and - x *= oolen * xSign; // Recover signs - y *= oolen * ySign; - z *= oolen * zSign; - - pNormal[0] = x; - pNormal[1] = y; - pNormal[2] = z; - if ( bIsTangent ) - { - pNormal[3] = tSign; - } - - return pNormal; -} - -////////////////////////////////////////////////////////////////////////////// -// See: http://www.oroboro.com/rafael/docserv.php/index/programming/article/unitv2 -// -// UBYTE4 encoding, using per-octant projection onto x+y+z=1 -// Assume input vector is already unit length -// -// binormalSign specifies 'sign' of binormal, stored in t sign bit of tangent -// (lets the shader know whether norm/tan/bin form a right-handed basis) -// -// bIsTangent is used to specify which WORD of the output to store the data -// The expected usage is to call once with the normal and once with -// the tangent and binormal sign flag, bitwise OR'ing the returned DWORDs -FORCEINLINE unsigned int * PackNormal_UBYTE4( float nx, float ny, float nz, unsigned int *pPackedNormal, bool bIsTangent = false, float binormalSign = +1.0f ) -{ - float xSign = nx < 0.0f ? -1.0f : 1.0f; // -1 or 1 sign - float ySign = ny < 0.0f ? -1.0f : 1.0f; - float zSign = nz < 0.0f ? -1.0f : 1.0f; - float tSign = binormalSign; - Assert( ( binormalSign == +1.0f ) || ( binormalSign == -1.0f ) ); - - float xSignBit = 0.5f*( 1 - xSign ); // [-1,+1] -> [1,0] - float ySignBit = 0.5f*( 1 - ySign ); // 1 is negative bit (like slt instruction) - float zSignBit = 0.5f*( 1 - zSign ); - float tSignBit = 0.5f*( 1 - binormalSign ); - - float absX = xSign*nx; // 0..1 range (abs) - float absY = ySign*ny; - float absZ = zSign*nz; - - float xbits = absX / ( absX + absY + absZ ); // Project onto x+y+z=1 plane - float ybits = absY / ( absX + absY + absZ ); - - xbits *= 63; // 0..63 - ybits *= 63; - - xbits = xbits * xSign - xSignBit; // -64..63 range - ybits = ybits * ySign - ySignBit; - xbits += 64.0f; // 0..127 range - ybits += 64.0f; - - xbits = xbits * zSign - zSignBit; // Negate based on z and t - ybits = ybits * tSign - tSignBit; // -128..127 range - - xbits += 128.0f; // 0..255 range - ybits += 128.0f; - - unsigned char cX = (unsigned char) xbits; - unsigned char cY = (unsigned char) ybits; - - if ( !bIsTangent ) - *pPackedNormal = (cX << 0) | (cY << 8); // xy for normal - else - *pPackedNormal = (cX << 16) | (cY << 24); // zw for tangent - - return pPackedNormal; -} - -FORCEINLINE unsigned int * PackNormal_UBYTE4( const float *pNormal, unsigned int *pPackedNormal, bool bIsTangent = false, float binormalSign = +1.0f ) -{ - return PackNormal_UBYTE4( pNormal[0], pNormal[1], pNormal[2], pPackedNormal, bIsTangent, binormalSign ); -} - - -//----------------------------------------------------------------------------- -// Convert RGB to HSV -//----------------------------------------------------------------------------- -void RGBtoHSV( const Vector &rgb, Vector &hsv ); - - -//----------------------------------------------------------------------------- -// Convert HSV to RGB -//----------------------------------------------------------------------------- -void HSVtoRGB( const Vector &hsv, Vector &rgb ); - - - -#endif // MATH_BASE_H - diff --git a/Resources/NetHook/mathlib/noise.h b/Resources/NetHook/mathlib/noise.h deleted file mode 100644 index 4acb75a5..00000000 --- a/Resources/NetHook/mathlib/noise.h +++ /dev/null @@ -1,35 +0,0 @@ -//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=====================================================================================// - -#ifndef NOISE_H -#define NOISE_H - -#include -#include "basetypes.h" -#include "mathlib/vector.h" -#include "tier0/dbg.h" - - -// The following code is the c-ification of Ken Perlin's new noise algorithm -// "JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN" -// as available here: http://mrl.nyu.edu/~perlin/noise/ -// it generates a single octave of noise in the -1..1 range -// this should at some point probably replace SparseConvolutionNoise - jd -float ImprovedPerlinNoise( Vector const &pnt ); - -// get the noise value at a point. Output range is 0..1. -float SparseConvolutionNoise( Vector const &pnt ); - -// get the noise value at a point, passing a custom noise shaping function. The noise shaping -// function should map the domain 0..1 to 0..1. -float SparseConvolutionNoise(Vector const &pnt, float (*pNoiseShapeFunction)(float) ); - -// returns a 1/f noise. more octaves take longer -float FractalNoise( Vector const &pnt, int n_octaves ); - -// returns a abs(f)*1/f noise i.e. turbulence -float Turbulence( Vector const &pnt, int n_octaves ); -#endif // NOISE_H diff --git a/Resources/NetHook/mathlib/polyhedron.h b/Resources/NetHook/mathlib/polyhedron.h deleted file mode 100644 index 81687cdd..00000000 --- a/Resources/NetHook/mathlib/polyhedron.h +++ /dev/null @@ -1,73 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef POLYHEDRON_H_ -#define POLYHEDRON_H_ - -#ifdef _WIN32 -#pragma once -#endif - -#include "mathlib/mathlib.h" - - - -struct Polyhedron_IndexedLine_t -{ - unsigned short iPointIndices[2]; -}; - -struct Polyhedron_IndexedLineReference_t -{ - unsigned short iLineIndex; - unsigned char iEndPointIndex; //since two polygons reference any one line, one needs to traverse the line backwards, this flags that behavior -}; - -struct Polyhedron_IndexedPolygon_t -{ - unsigned short iFirstIndex; - unsigned short iIndexCount; - Vector polyNormal; -}; - -class CPolyhedron //made into a class because it's going virtual to support distinctions between temp and permanent versions -{ -public: - Vector *pVertices; - Polyhedron_IndexedLine_t *pLines; - Polyhedron_IndexedLineReference_t *pIndices; - Polyhedron_IndexedPolygon_t *pPolygons; - - unsigned short iVertexCount; - unsigned short iLineCount; - unsigned short iIndexCount; - unsigned short iPolygonCount; - - virtual ~CPolyhedron( void ) {}; - virtual void Release( void ) = 0; - Vector Center( void ); -}; - -class CPolyhedron_AllocByNew : public CPolyhedron -{ -public: - virtual void Release( void ); - static CPolyhedron_AllocByNew *Allocate( unsigned short iVertices, unsigned short iLines, unsigned short iIndices, unsigned short iPolygons ); //creates the polyhedron along with enough memory to hold all it's data in a single allocation - -private: - CPolyhedron_AllocByNew( void ) { }; //CPolyhedron_AllocByNew::Allocate() is the only way to create one of these. -}; - -CPolyhedron *GeneratePolyhedronFromPlanes( const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory = false ); //be sure to polyhedron->Release() -CPolyhedron *ClipPolyhedron( const CPolyhedron *pExistingPolyhedron, const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory = false ); //this does NOT modify/delete the existing polyhedron - -CPolyhedron *GetTempPolyhedron( unsigned short iVertices, unsigned short iLines, unsigned short iIndices, unsigned short iPolygons ); //grab the temporary polyhedron. Avoids new/delete for quick work. Can only be in use by one chunk of code at a time - - -#endif //#ifndef POLYHEDRON_H_ - diff --git a/Resources/NetHook/mathlib/quantize.h b/Resources/NetHook/mathlib/quantize.h deleted file mode 100644 index 11c08b2b..00000000 --- a/Resources/NetHook/mathlib/quantize.h +++ /dev/null @@ -1,141 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef QUANTIZE_H -#define QUANTIZE_H - -#ifndef STRING_H -#include -#endif - -#define MAXDIMS 768 -#define MAXQUANT 16000 - - -#include - -struct Sample; - -struct QuantizedValue { - double MinError; // minimum possible error. used - // for neighbor searches. - struct QuantizedValue *Children[2]; // splits - int32 value; // only exists for leaf nodes - struct Sample *Samples; // every sample quantized into this - // entry - int32 NSamples; // how many were quantized to this. - int32 TotSamples; - double *ErrorMeasure; // variance measure for each dimension - double TotalError; // sum of errors - uint8 *Mean; // average value of each dimension - uint8 *Mins; // min box for children and this - uint8 *Maxs; // max box for children and this - int NQuant; // the number of samples which were - // quantzied to this node since the - // last time OptimizeQuantizer() - // was called. - int *Sums; // sum used by OptimizeQuantizer - int sortdim; // dimension currently sorted along. -}; - -struct Sample { - int32 ID; // identifier of this sample. can - // be used for any purpose. - int32 Count; // number of samples this sample - // represents - int32 QNum; // what value this sample ended up quantized - // to. - struct QuantizedValue *qptr; // ptr to what this was quantized to. - uint8 Value[1]; // array of values for multi-dimensional - // variables. -}; - -void FreeQuantization(struct QuantizedValue *t); - -struct QuantizedValue *Quantize(struct Sample *s, int nsamples, int ndims, - int nvalues, uint8 *weights, int value0=0); - -int CompressSamples(struct Sample *s, int nsamples, int ndims); - -struct QuantizedValue *FindMatch(uint8 const *sample, - int ndims,uint8 *weights, - struct QuantizedValue *QTable); -void PrintSamples(struct Sample const *s, int nsamples, int ndims); - -struct QuantizedValue *FindQNode(struct QuantizedValue const *q, int32 code); - -inline struct Sample *NthSample(struct Sample *s, int i, int nd) -{ - uint8 *r=(uint8 *) s; - r+=i*(sizeof(*s)+(nd-1)); - return (struct Sample *) r; -} - -inline struct Sample *AllocSamples(int ns, int nd) -{ - size_t size5=(sizeof(struct Sample)+(nd-1))*ns; - void *ret=new uint8[size5]; - memset(ret,0,size5); - for(int i=0;iCount=1; - return (struct Sample *) ret; -} - - -// MinimumError: what is the min error which will occur if quantizing -// a sample to the given qnode? This is just the error if the qnode -// is a leaf. -double MinimumError(struct QuantizedValue const *q, uint8 const *sample, - int ndims, uint8 const *weights); -double MaximumError(struct QuantizedValue const *q, uint8 const *sample, - int ndims, uint8 const *weights); - -void PrintQTree(struct QuantizedValue const *p,int idlevel=0); -void OptimizeQuantizer(struct QuantizedValue *q, int ndims); - -// RecalculateVelues: update the means in a sample tree, based upon -// the samples. can be used to reoptimize when samples are deleted, -// for instance. - -void RecalculateValues(struct QuantizedValue *q, int ndims); - -extern double SquaredError; // may be reset and examined. updated by - // FindMatch() - - - - -// the routines below can be used for uniform quantization via dart-throwing. -typedef void (*GENERATOR)(void *); // generate a random sample -typedef double (*COMPARER)(void const *a, void const *b); - -void *DartThrow(int NResults, int NTries, size_t itemsize, GENERATOR gen, - COMPARER cmp); -void *FindClosestDart(void *items,int NResults, size_t itemsize, - COMPARER cmp, void *lookfor, int *idx); - - - - -// color quantization of 24 bit images -#define QUANTFLAGS_NODITHER 1 // don't do Floyd-steinberg dither - -extern void ColorQuantize( -uint8 const *pImage, // 4 byte pixels ARGB -int nWidth, -int nHeight, -int nFlags, // QUANTFLAGS_xxx -int nColors, // # of colors to fill in in palette -uint8 *pOutPixels, // where to store resulting 8 bit pixels -uint8 *pOutPalette, // where to store resulting 768-byte palette -int nFirstColor); // first color to use in mapping - - - - - -#endif diff --git a/Resources/NetHook/mathlib/simdvectormatrix.h b/Resources/NetHook/mathlib/simdvectormatrix.h deleted file mode 100644 index e8a3667c..00000000 --- a/Resources/NetHook/mathlib/simdvectormatrix.h +++ /dev/null @@ -1,142 +0,0 @@ -//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======// -// -// Purpose: Provide a class (SSE/SIMD only) holding a 2d matrix of class FourVectors, -// for high speed processing in tools. -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef SIMDVECTORMATRIX_H -#define SIMDVECTORMATRIX_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier1/utlsoacontainer.h" -#include "mathlib/ssemath.h" - -class CSIMDVectorMatrix -{ -public: - int m_nWidth; // in actual vectors - int m_nHeight; - - int m_nPaddedWidth; // # of 4x wide elements - - FourVectors *m_pData; - -protected: - void Init( void ) - { - m_pData = NULL; - m_nWidth = 0; - m_nHeight = 0; - m_nPaddedWidth = 0; - } - - int NVectors( void ) const - { - return m_nHeight * m_nPaddedWidth; - } - -public: - // constructors and destructors - CSIMDVectorMatrix( void ) - { - Init(); - } - - ~CSIMDVectorMatrix( void ) - { - if ( m_pData ) - delete[] m_pData; - } - - // set up storage and fields for m x n matrix. destroys old data - void SetSize( int width, int height ) - { - if ( ( ! m_pData ) || ( width != m_nWidth ) || ( height != m_nHeight ) ) - { - if ( m_pData ) - delete[] m_pData; - - m_nWidth = width; - m_nHeight = height; - - m_nPaddedWidth = ( m_nWidth + 3) >> 2; - m_pData = NULL; - if ( width && height ) - m_pData = new FourVectors[ m_nPaddedWidth * m_nHeight ]; - } - } - - CSIMDVectorMatrix( int width, int height ) - { - Init(); - SetSize( width, height ); - } - - CSIMDVectorMatrix &operator=( CSIMDVectorMatrix const &src ) - { - SetSize( src.m_nWidth, src.m_nHeight ); - if ( m_pData ) - memcpy( m_pData, src.m_pData, m_nHeight*m_nPaddedWidth*sizeof(m_pData[0]) ); - return *this; - } - - CSIMDVectorMatrix &operator+=( CSIMDVectorMatrix const &src ); - - CSIMDVectorMatrix &operator*=( Vector const &src ); - - // create from an RGBA float bitmap. alpha ignored. - void CreateFromRGBA_FloatImageData(int srcwidth, int srcheight, float const *srcdata ); - - // create from 3 fields in a csoa - void CreateFromCSOAAttributes( CSOAContainer const *pSrc, - int nAttrIdx0, int nAttrIdx1, int nAttrIdx2 ); - - // Element access. If you are calling this a lot, you don't want to use this class, because - // you're not getting the sse advantage - Vector Element(int x, int y) const - { - Assert( m_pData ); - Assert( x < m_nWidth ); - Assert( y < m_nHeight ); - Vector ret; - FourVectors const *pData=m_pData+y*m_nPaddedWidth+(x >> 2); - - int xo=(x & 3); - ret.x=pData->X( xo ); - ret.y=pData->Y( xo ); - ret.z=pData->Z( xo ); - return ret; - } - - //addressing the individual fourvectors elements - FourVectors &CompoundElement(int x, int y) - { - Assert( m_pData ); - Assert( y < m_nHeight ); - Assert( x < m_nPaddedWidth ); - return m_pData[x + m_nPaddedWidth*y ]; - } - - // math operations on the whole image - void Clear( void ) - { - Assert( m_pData ); - memset( m_pData, 0, m_nHeight*m_nPaddedWidth*sizeof(m_pData[0]) ); - } - - void RaiseToPower( float power ); -}; - - - -#endif diff --git a/Resources/NetHook/mathlib/spherical_geometry.h b/Resources/NetHook/mathlib/spherical_geometry.h deleted file mode 100644 index f8c5862e..00000000 --- a/Resources/NetHook/mathlib/spherical_geometry.h +++ /dev/null @@ -1,73 +0,0 @@ -//====== Copyright © 2007-2007, Valve Corporation, All rights reserved. =======// -// -// Purpose: Functions for spherical geometry. -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef SPHERICAL_GEOMETRY_H -#define SPHERICAL_GEOMETRY_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include - -// see http://mathworld.wolfram.com/SphericalTrigonometry.html - -// return the spherical distance, in radians, between 2 points on the unit sphere. -FORCEINLINE float UnitSphereLineSegmentLength( Vector const &a, Vector const &b ) -{ - // check unit length - Assert( fabs( VectorLength( a ) - 1.0 ) < 1.0e-3 ); - Assert( fabs( VectorLength( b ) - 1.0 ) < 1.0e-3 ); - return acos( DotProduct( a, b ) ); -} - - -// given 3 points on the unit sphere, return the spherical area (in radians) of the triangle they form. -// valid for "small" triangles. -FORCEINLINE float UnitSphereTriangleArea( Vector const &a, Vector const &b , Vector const &c ) -{ - float flLengthA = UnitSphereLineSegmentLength( b, c ); - float flLengthB = UnitSphereLineSegmentLength( c, a ); - float flLengthC = UnitSphereLineSegmentLength( a, b ); - - if ( ( flLengthA == 0. ) || ( flLengthB == 0. ) || ( flLengthC == 0. ) ) - return 0.; // zero area triangle - - // now, find the 3 incribed angles for the triangle - float flHalfSumLens = 0.5 * ( flLengthA + flLengthB + flLengthC ); - float flSinSums = sin( flHalfSumLens ); - float flSinSMinusA= sin( flHalfSumLens - flLengthA ); - float flSinSMinusB= sin( flHalfSumLens - flLengthB ); - float flSinSMinusC= sin( flHalfSumLens - flLengthC ); - - float flTanAOver2 = sqrt ( ( flSinSMinusB * flSinSMinusC ) / ( flSinSums * flSinSMinusA ) ); - float flTanBOver2 = sqrt ( ( flSinSMinusA * flSinSMinusC ) / ( flSinSums * flSinSMinusB ) ); - float flTanCOver2 = sqrt ( ( flSinSMinusA * flSinSMinusB ) / ( flSinSums * flSinSMinusC ) ); - - // Girards formula : area = sum of angles - pi. - return 2.0 * ( atan( flTanAOver2 ) + atan( flTanBOver2 ) + atan( flTanCOver2 ) ) - M_PI; -} - -// spherical harmonics-related functions. Best explanation at http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf - -// Evaluate associated legendre polynomial P( l, m ) at flX, using recurrence relation -float AssociatedLegendrePolynomial( int nL, int nM, float flX ); - -// Evaluate order N spherical harmonic with spherical coordinates -// nL = band, 0..N -// nM = -nL .. nL -// theta = 0..M_PI -// phi = 0.. 2 * M_PHI -float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi ); - -// evaluate spherical harmonic with normalized vector direction -float SphericalHarmonic( int nL, int nM, Vector const &vecDirection ); - - -#endif // SPHERICAL_GEOMETRY_H diff --git a/Resources/NetHook/mathlib/ssemath.h b/Resources/NetHook/mathlib/ssemath.h deleted file mode 100644 index a6d15820..00000000 --- a/Resources/NetHook/mathlib/ssemath.h +++ /dev/null @@ -1,3098 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: - defines SIMD "structure of arrays" classes and functions. -// -//===========================================================================// -#ifndef SSEMATH_H -#define SSEMATH_H - -#if defined( _X360 ) -#include -#else -#include -#endif - -#include -#include - -#if defined(_LINUX) -#define USE_STDC_FOR_SIMD 0 -#else -#define USE_STDC_FOR_SIMD 0 -#endif - -#if (!defined(_X360) && (USE_STDC_FOR_SIMD == 0)) -#define _SSE1 1 -#endif - -// I thought about defining a class/union for the SIMD packed floats instead of using fltx4, -// but decided against it because (a) the nature of SIMD code which includes comparisons is to blur -// the relationship between packed floats and packed integer types and (b) not sure that the -// compiler would handle generating good code for the intrinsics. - -#if USE_STDC_FOR_SIMD - -typedef union -{ - float m128_f32[4]; - uint32 m128_u32[4]; -} fltx4; - -typedef fltx4 i32x4; -typedef fltx4 u32x4; - -#elif ( defined( _X360 ) ) - -typedef union -{ - // This union allows float/int access (which generally shouldn't be done in inner loops) - __vector4 vmx; - float m128_f32[4]; - uint32 m128_u32[4]; -} fltx4_union; - -typedef __vector4 fltx4; -typedef __vector4 i32x4; // a VMX register; just a way of making it explicit that we're doing integer ops. -typedef __vector4 u32x4; // a VMX register; just a way of making it explicit that we're doing unsigned integer ops. - -#else - -typedef __m128 fltx4; -typedef __m128 i32x4; -typedef __m128 u32x4; - -#endif - -// The FLTX4 type is a fltx4 used as a parameter to a function. -// On the 360, the best way to do this is pass-by-copy on the registers. -// On the PC, the best way is to pass by const reference. -// The compiler will sometimes, but not always, replace a pass-by-const-ref -// with a pass-in-reg on the 360; to avoid this confusion, you can -// explicitly use a FLTX4 as the parameter type. -#ifdef _X360 -typedef __vector4 FLTX4; -#else -typedef const fltx4 & FLTX4; -#endif - -// A 16-byte aligned int32 datastructure -// (for use when writing out fltx4's as SIGNED -// ints). -struct ALIGN16 intx4 -{ - int32 m_i32[4]; - - inline int & operator[](int which) - { - return m_i32[which]; - } - - inline const int & operator[](int which) const - { - return m_i32[which]; - } - - inline int32 *Base() { - return m_i32; - } - - inline const int32 *Base() const - { - return m_i32; - } - - inline const bool operator==(const intx4 &other) const - { - return m_i32[0] == other.m_i32[0] && - m_i32[1] == other.m_i32[1] && - m_i32[2] == other.m_i32[2] && - m_i32[3] == other.m_i32[3] ; - } -}; - - -#if defined( _DEBUG ) && defined( _X360 ) -FORCEINLINE void TestVPUFlags() -{ - // Check that the VPU is in the appropriate (Java-compliant) mode (see 3.2.1 in altivec_pem.pdf on xds.xbox.com) - __vector4 a; - __asm - { - mfvscr a; - } - unsigned int * flags = (unsigned int *)&a; - unsigned int controlWord = flags[3]; - Assert(controlWord == 0); -} -#else // _DEBUG -FORCEINLINE void TestVPUFlags() {} -#endif // _DEBUG - - -// useful constants in SIMD packed float format: -// (note: some of these aren't stored on the 360, -// but are manufactured directly in one or two -// instructions, saving a load and possible L2 -// miss.) -#ifndef _X360 -extern const fltx4 Four_Zeros; // 0 0 0 0 -extern const fltx4 Four_Ones; // 1 1 1 1 -extern const fltx4 Four_Twos; // 2 2 2 2 -extern const fltx4 Four_Threes; // 3 3 3 3 -extern const fltx4 Four_Fours; // guess. -extern const fltx4 Four_Point225s; // .225 .225 .225 .225 -extern const fltx4 Four_PointFives; // .5 .5 .5 .5 -extern const fltx4 Four_Epsilons; // FLT_EPSILON FLT_EPSILON FLT_EPSILON FLT_EPSILON -extern const fltx4 Four_2ToThe21s; // (1<<21).. -extern const fltx4 Four_2ToThe22s; // (1<<22).. -extern const fltx4 Four_2ToThe23s; // (1<<23).. -extern const fltx4 Four_2ToThe24s; // (1<<24).. -extern const fltx4 Four_Origin; // 0 0 0 1 (origin point, like vr0 on the PS2) -extern const fltx4 Four_NegativeOnes; // -1 -1 -1 -1 -#else -#define Four_Zeros XMVectorZero() // 0 0 0 0 -#define Four_Ones XMVectorSplatOne() // 1 1 1 1 -extern const fltx4 Four_Twos; // 2 2 2 2 -extern const fltx4 Four_Threes; // 3 3 3 3 -extern const fltx4 Four_Fours; // guess. -extern const fltx4 Four_Point225s; // .225 .225 .225 .225 -extern const fltx4 Four_PointFives; // .5 .5 .5 .5 -extern const fltx4 Four_Epsilons; // FLT_EPSILON FLT_EPSILON FLT_EPSILON FLT_EPSILON -extern const fltx4 Four_2ToThe21s; // (1<<21).. -extern const fltx4 Four_2ToThe22s; // (1<<22).. -extern const fltx4 Four_2ToThe23s; // (1<<23).. -extern const fltx4 Four_2ToThe24s; // (1<<24).. -extern const fltx4 Four_Origin; // 0 0 0 1 (origin point, like vr0 on the PS2) -extern const fltx4 Four_NegativeOnes; // -1 -1 -1 -1 -#endif -extern const fltx4 Four_FLT_MAX; // FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX -extern const fltx4 Four_Negative_FLT_MAX; // -FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX -extern const fltx4 g_SIMD_0123; // 0 1 2 3 as float - -// external aligned integer constants -extern const ALIGN16 int32 g_SIMD_clear_signmask[]; // 0x7fffffff x 4 -extern const ALIGN16 int32 g_SIMD_signmask[]; // 0x80000000 x 4 -extern const ALIGN16 int32 g_SIMD_lsbmask[]; // 0xfffffffe x 4 -extern const ALIGN16 int32 g_SIMD_clear_wmask[]; // -1 -1 -1 0 -extern const ALIGN16 int32 g_SIMD_ComponentMask[4][4]; // [0xFFFFFFFF 0 0 0], [0 0xFFFFFFFF 0 0], [0 0 0xFFFFFFFF 0], [0 0 0 0xFFFFFFFF] -extern const ALIGN16 int32 g_SIMD_AllOnesMask[]; // ~0,~0,~0,~0 -extern const ALIGN16 int32 g_SIMD_Low16BitsMask[]; // 0xffff x 4 - -// this mask is used for skipping the tail of things. If you have N elements in an array, and wish -// to mask out the tail, g_SIMD_SkipTailMask[N & 3] what you want to use for the last iteration. -extern const int32 ALIGN16 g_SIMD_SkipTailMask[4][4]; - -// Define prefetch macros. -// The characteristics of cache and prefetch are completely -// different between the different platforms, so you DO NOT -// want to just define one macro that maps to every platform -// intrinsic under the hood -- you need to prefetch at different -// intervals between x86 and PPC, for example, and that is -// a higher level code change. -// On the other hand, I'm tired of typing #ifdef _X360 -// all over the place, so this is just a nop on Intel, PS3. -#ifdef _X360 -#define PREFETCH360(address, offset) __dcbt(offset,address) -#else -#define PREFETCH360(x,y) // nothing -#endif - -#if USE_STDC_FOR_SIMD - -//--------------------------------------------------------------------- -// Standard C (fallback/Linux) implementation (only there for compat - slow) -//--------------------------------------------------------------------- - -FORCEINLINE float SubFloat( const fltx4 & a, int idx ) -{ - return a.m128_f32[ idx ]; -} - -FORCEINLINE float & SubFloat( fltx4 & a, int idx ) -{ - return a.m128_f32[idx]; -} - -FORCEINLINE uint32 SubInt( const fltx4 & a, int idx ) -{ - return a.m128_u32[idx]; -} - -FORCEINLINE uint32 & SubInt( fltx4 & a, int idx ) -{ - return a.m128_u32[idx]; -} - -// Return one in the fastest way -- on the x360, faster even than loading. -FORCEINLINE fltx4 LoadZeroSIMD( void ) -{ - return Four_Zeros; -} - -// Return one in the fastest way -- on the x360, faster even than loading. -FORCEINLINE fltx4 LoadOneSIMD( void ) -{ - return Four_Ones; -} - -FORCEINLINE fltx4 SplatXSIMD( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 0 ); - SubFloat( retVal, 1 ) = SubFloat( a, 0 ); - SubFloat( retVal, 2 ) = SubFloat( a, 0 ); - SubFloat( retVal, 3 ) = SubFloat( a, 0 ); - return retVal; -} - -FORCEINLINE fltx4 SplatYSIMD( fltx4 a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 1 ); - SubFloat( retVal, 1 ) = SubFloat( a, 1 ); - SubFloat( retVal, 2 ) = SubFloat( a, 1 ); - SubFloat( retVal, 3 ) = SubFloat( a, 1 ); - return retVal; -} - -FORCEINLINE fltx4 SplatZSIMD( fltx4 a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 2 ); - SubFloat( retVal, 1 ) = SubFloat( a, 2 ); - SubFloat( retVal, 2 ) = SubFloat( a, 2 ); - SubFloat( retVal, 3 ) = SubFloat( a, 2 ); - return retVal; -} - -FORCEINLINE fltx4 SplatWSIMD( fltx4 a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 3 ); - SubFloat( retVal, 1 ) = SubFloat( a, 3 ); - SubFloat( retVal, 2 ) = SubFloat( a, 3 ); - SubFloat( retVal, 3 ) = SubFloat( a, 3 ); - return retVal; -} - -FORCEINLINE fltx4 SetXSIMD( const fltx4& a, const fltx4& x ) -{ - fltx4 result = a; - SubFloat( result, 0 ) = SubFloat( x, 0 ); - return result; -} - -FORCEINLINE fltx4 SetYSIMD( const fltx4& a, const fltx4& y ) -{ - fltx4 result = a; - SubFloat( result, 1 ) = SubFloat( y, 1 ); - return result; -} - -FORCEINLINE fltx4 SetZSIMD( const fltx4& a, const fltx4& z ) -{ - fltx4 result = a; - SubFloat( result, 2 ) = SubFloat( z, 2 ); - return result; -} - -FORCEINLINE fltx4 SetWSIMD( const fltx4& a, const fltx4& w ) -{ - fltx4 result = a; - SubFloat( result, 3 ) = SubFloat( w, 3 ); - return result; -} - -FORCEINLINE fltx4 SetComponentSIMD( const fltx4& a, int nComponent, float flValue ) -{ - fltx4 result = a; - SubFloat( result, nComponent ) = flValue; - return result; -} - -// a b c d -> b c d a -FORCEINLINE fltx4 RotateLeft( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 1 ); - SubFloat( retVal, 1 ) = SubFloat( a, 2 ); - SubFloat( retVal, 2 ) = SubFloat( a, 3 ); - SubFloat( retVal, 3 ) = SubFloat( a, 0 ); - return retVal; -} - -// a b c d -> c d a b -FORCEINLINE fltx4 RotateLeft2( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = SubFloat( a, 2 ); - SubFloat( retVal, 1 ) = SubFloat( a, 3 ); - SubFloat( retVal, 2 ) = SubFloat( a, 0 ); - SubFloat( retVal, 3 ) = SubFloat( a, 1 ); - return retVal; -} - -#define BINOP(op) \ - fltx4 retVal; \ - SubFloat( retVal, 0 ) = ( SubFloat( a, 0 ) op SubFloat( b, 0 ) ); \ - SubFloat( retVal, 1 ) = ( SubFloat( a, 1 ) op SubFloat( b, 1 ) ); \ - SubFloat( retVal, 2 ) = ( SubFloat( a, 2 ) op SubFloat( b, 2 ) ); \ - SubFloat( retVal, 3 ) = ( SubFloat( a, 3 ) op SubFloat( b, 3 ) ); \ - return retVal; - -#define IBINOP(op) \ - fltx4 retVal; \ - SubInt( retVal, 0 ) = ( SubInt( a, 0 ) op SubInt ( b, 0 ) ); \ - SubInt( retVal, 1 ) = ( SubInt( a, 1 ) op SubInt ( b, 1 ) ); \ - SubInt( retVal, 2 ) = ( SubInt( a, 2 ) op SubInt ( b, 2 ) ); \ - SubInt( retVal, 3 ) = ( SubInt( a, 3 ) op SubInt ( b, 3 ) ); \ - return retVal; - -FORCEINLINE fltx4 AddSIMD( const fltx4 & a, const fltx4 & b ) -{ - BINOP(+); -} - -FORCEINLINE fltx4 SubSIMD( const fltx4 & a, const fltx4 & b ) // a-b -{ - BINOP(-); -}; - -FORCEINLINE fltx4 MulSIMD( const fltx4 & a, const fltx4 & b ) // a*b -{ - BINOP(*); -} - -FORCEINLINE fltx4 DivSIMD( const fltx4 & a, const fltx4 & b ) // a/b -{ - BINOP(/); -} - - -FORCEINLINE fltx4 MaddSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // a*b + c -{ - return AddSIMD( MulSIMD(a,b), c ); -} - -FORCEINLINE fltx4 MsubSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // c - a*b -{ - return SubSIMD( c, MulSIMD(a,b) ); -}; - - -FORCEINLINE fltx4 SinSIMD( const fltx4 &radians ) -{ - fltx4 result; - SubFloat( result, 0 ) = sin( SubFloat( radians, 0 ) ); - SubFloat( result, 1 ) = sin( SubFloat( radians, 1 ) ); - SubFloat( result, 2 ) = sin( SubFloat( radians, 2 ) ); - SubFloat( result, 3 ) = sin( SubFloat( radians, 3 ) ); - return result; -} - -FORCEINLINE void SinCos3SIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) -{ - SinCos( SubFloat( radians, 0 ), &SubFloat( sine, 0 ), &SubFloat( cosine, 0 ) ); - SinCos( SubFloat( radians, 1 ), &SubFloat( sine, 1 ), &SubFloat( cosine, 1 ) ); - SinCos( SubFloat( radians, 2 ), &SubFloat( sine, 2 ), &SubFloat( cosine, 2 ) ); -} - -FORCEINLINE void SinCosSIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) -{ - SinCos( SubFloat( radians, 0 ), &SubFloat( sine, 0 ), &SubFloat( cosine, 0 ) ); - SinCos( SubFloat( radians, 1 ), &SubFloat( sine, 1 ), &SubFloat( cosine, 1 ) ); - SinCos( SubFloat( radians, 2 ), &SubFloat( sine, 2 ), &SubFloat( cosine, 2 ) ); - SinCos( SubFloat( radians, 3 ), &SubFloat( sine, 3 ), &SubFloat( cosine, 3 ) ); -} - -FORCEINLINE fltx4 ArcSinSIMD( const fltx4 &sine ) -{ - fltx4 result; - SubFloat( result, 0 ) = asin( SubFloat( sine, 0 ) ); - SubFloat( result, 1 ) = asin( SubFloat( sine, 1 ) ); - SubFloat( result, 2 ) = asin( SubFloat( sine, 2 ) ); - SubFloat( result, 3 ) = asin( SubFloat( sine, 3 ) ); - return result; -} - -FORCEINLINE fltx4 ArcCosSIMD( const fltx4 &cs ) -{ - fltx4 result; - SubFloat( result, 0 ) = acos( SubFloat( cs, 0 ) ); - SubFloat( result, 1 ) = acos( SubFloat( cs, 1 ) ); - SubFloat( result, 2 ) = acos( SubFloat( cs, 2 ) ); - SubFloat( result, 3 ) = acos( SubFloat( cs, 3 ) ); - return result; -} - -// tan^1(a/b) .. ie, pass sin in as a and cos in as b -FORCEINLINE fltx4 ArcTan2SIMD( const fltx4 &a, const fltx4 &b ) -{ - fltx4 result; - SubFloat( result, 0 ) = atan2( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( result, 1 ) = atan2( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( result, 2 ) = atan2( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( result, 3 ) = atan2( SubFloat( a, 3 ), SubFloat( b, 3 ) ); - return result; -} - -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = max( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( retVal, 1 ) = max( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( retVal, 2 ) = max( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( retVal, 3 ) = max( SubFloat( a, 3 ), SubFloat( b, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = min( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( retVal, 1 ) = min( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( retVal, 2 ) = min( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( retVal, 3 ) = min( SubFloat( a, 3 ), SubFloat( b, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 AndSIMD( const fltx4 & a, const fltx4 & b ) // a & b -{ - IBINOP(&); -} - -FORCEINLINE fltx4 AndNotSIMD( const fltx4 & a, const fltx4 & b ) // ~a & b -{ - fltx4 retVal; - SubInt( retVal, 0 ) = ~SubInt( a, 0 ) & SubInt( b, 0 ); - SubInt( retVal, 1 ) = ~SubInt( a, 1 ) & SubInt( b, 1 ); - SubInt( retVal, 2 ) = ~SubInt( a, 2 ) & SubInt( b, 2 ); - SubInt( retVal, 3 ) = ~SubInt( a, 3 ) & SubInt( b, 3 ); - return retVal; -} - -FORCEINLINE fltx4 XorSIMD( const fltx4 & a, const fltx4 & b ) // a ^ b -{ - IBINOP(^); -} - -FORCEINLINE fltx4 OrSIMD( const fltx4 & a, const fltx4 & b ) // a | b -{ - IBINOP(|); -} - -FORCEINLINE fltx4 NegSIMD(const fltx4 &a) // negate: -a -{ - fltx4 retval; - SubFloat( retval, 0 ) = -SubFloat( a, 0 ); - SubFloat( retval, 1 ) = -SubFloat( a, 1 ); - SubFloat( retval, 2 ) = -SubFloat( a, 2 ); - SubFloat( retval, 3 ) = -SubFloat( a, 3 ); - - return retval; -} - -FORCEINLINE bool IsAllZeros( const fltx4 & a ) // all floats of a zero? -{ - return ( SubFloat( a, 0 ) == 0.0 ) && - ( SubFloat( a, 1 ) == 0.0 ) && - ( SubFloat( a, 2 ) == 0.0 ) && - ( SubFloat( a, 3 ) == 0.0 ) ; -} - - -// for branching when a.xyzw > b.xyzw -FORCEINLINE bool IsAllGreaterThan( const fltx4 &a, const fltx4 &b ) -{ - return SubFloat(a,0) > SubFloat(b,0) && - SubFloat(a,1) > SubFloat(b,1) && - SubFloat(a,2) > SubFloat(b,2) && - SubFloat(a,3) > SubFloat(b,3); -} - -// for branching when a.xyzw >= b.xyzw -FORCEINLINE bool IsAllGreaterThanOrEq( const fltx4 &a, const fltx4 &b ) -{ - return SubFloat(a,0) >= SubFloat(b,0) && - SubFloat(a,1) >= SubFloat(b,1) && - SubFloat(a,2) >= SubFloat(b,2) && - SubFloat(a,3) >= SubFloat(b,3); -} - -// For branching if all a.xyzw == b.xyzw -FORCEINLINE bool IsAllEqual( const fltx4 & a, const fltx4 & b ) -{ - return SubFloat(a,0) == SubFloat(b,0) && - SubFloat(a,1) == SubFloat(b,1) && - SubFloat(a,2) == SubFloat(b,2) && - SubFloat(a,3) == SubFloat(b,3); -} - -FORCEINLINE int TestSignSIMD( const fltx4 & a ) // mask of which floats have the high bit set -{ - int nRet = 0; - - nRet |= ( SubInt( a, 0 ) & 0x80000000 ) >> 31; // sign(x) -> bit 0 - nRet |= ( SubInt( a, 1 ) & 0x80000000 ) >> 30; // sign(y) -> bit 1 - nRet |= ( SubInt( a, 2 ) & 0x80000000 ) >> 29; // sign(z) -> bit 2 - nRet |= ( SubInt( a, 3 ) & 0x80000000 ) >> 28; // sign(w) -> bit 3 - - return nRet; -} - -FORCEINLINE bool IsAnyNegative( const fltx4 & a ) // (a.x < 0) || (a.y < 0) || (a.z < 0) || (a.w < 0) -{ - return (0 != TestSignSIMD( a )); -} - -FORCEINLINE fltx4 CmpEqSIMD( const fltx4 & a, const fltx4 & b ) // (a==b) ? ~0:0 -{ - fltx4 retVal; - SubInt( retVal, 0 ) = ( SubFloat( a, 0 ) == SubFloat( b, 0 )) ? ~0 : 0; - SubInt( retVal, 1 ) = ( SubFloat( a, 1 ) == SubFloat( b, 1 )) ? ~0 : 0; - SubInt( retVal, 2 ) = ( SubFloat( a, 2 ) == SubFloat( b, 2 )) ? ~0 : 0; - SubInt( retVal, 3 ) = ( SubFloat( a, 3 ) == SubFloat( b, 3 )) ? ~0 : 0; - return retVal; -} - -FORCEINLINE fltx4 CmpGtSIMD( const fltx4 & a, const fltx4 & b ) // (a>b) ? ~0:0 -{ - fltx4 retVal; - SubInt( retVal, 0 ) = ( SubFloat( a, 0 ) > SubFloat( b, 0 )) ? ~0 : 0; - SubInt( retVal, 1 ) = ( SubFloat( a, 1 ) > SubFloat( b, 1 )) ? ~0 : 0; - SubInt( retVal, 2 ) = ( SubFloat( a, 2 ) > SubFloat( b, 2 )) ? ~0 : 0; - SubInt( retVal, 3 ) = ( SubFloat( a, 3 ) > SubFloat( b, 3 )) ? ~0 : 0; - return retVal; -} - -FORCEINLINE fltx4 CmpGeSIMD( const fltx4 & a, const fltx4 & b ) // (a>=b) ? ~0:0 -{ - fltx4 retVal; - SubInt( retVal, 0 ) = ( SubFloat( a, 0 ) >= SubFloat( b, 0 )) ? ~0 : 0; - SubInt( retVal, 1 ) = ( SubFloat( a, 1 ) >= SubFloat( b, 1 )) ? ~0 : 0; - SubInt( retVal, 2 ) = ( SubFloat( a, 2 ) >= SubFloat( b, 2 )) ? ~0 : 0; - SubInt( retVal, 3 ) = ( SubFloat( a, 3 ) >= SubFloat( b, 3 )) ? ~0 : 0; - return retVal; -} - -FORCEINLINE fltx4 CmpLtSIMD( const fltx4 & a, const fltx4 & b ) // (a= -b) ? ~0 : 0 -{ - fltx4 retVal; - SubInt( retVal, 0 ) = ( SubFloat( a, 0 ) <= SubFloat( b, 0 ) && SubFloat( a, 0 ) >= -SubFloat( b, 0 ) ) ? ~0 : 0; - SubInt( retVal, 1 ) = ( SubFloat( a, 1 ) <= SubFloat( b, 1 ) && SubFloat( a, 1 ) >= -SubFloat( b, 1 ) ) ? ~0 : 0; - SubInt( retVal, 2 ) = ( SubFloat( a, 2 ) <= SubFloat( b, 2 ) && SubFloat( a, 2 ) >= -SubFloat( b, 2 ) ) ? ~0 : 0; - SubInt( retVal, 3 ) = ( SubFloat( a, 3 ) <= SubFloat( b, 3 ) && SubFloat( a, 3 ) >= -SubFloat( b, 3 ) ) ? ~0 : 0; - return retVal; -} - - -FORCEINLINE fltx4 MaskedAssign( const fltx4 & ReplacementMask, const fltx4 & NewValue, const fltx4 & OldValue ) -{ - return OrSIMD( - AndSIMD( ReplacementMask, NewValue ), - AndNotSIMD( ReplacementMask, OldValue ) ); -} - -FORCEINLINE fltx4 ReplicateX4( float flValue ) // a,a,a,a -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = flValue; - SubFloat( retVal, 1 ) = flValue; - SubFloat( retVal, 2 ) = flValue; - SubFloat( retVal, 3 ) = flValue; - return retVal; -} - -/// replicate a single 32 bit integer value to all 4 components of an m128 -FORCEINLINE fltx4 ReplicateIX4( int nValue ) -{ - fltx4 retVal; - SubInt( retVal, 0 ) = nValue; - SubInt( retVal, 1 ) = nValue; - SubInt( retVal, 2 ) = nValue; - SubInt( retVal, 3 ) = nValue; - return retVal; - -} - -// Round towards positive infinity -FORCEINLINE fltx4 CeilSIMD( const fltx4 &a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = ceil( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = ceil( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = ceil( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = ceil( SubFloat( a, 3 ) ); - return retVal; - -} - -// Round towards negative infinity -FORCEINLINE fltx4 FloorSIMD( const fltx4 &a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = floor( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = floor( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = floor( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = floor( SubFloat( a, 3 ) ); - return retVal; - -} - -FORCEINLINE fltx4 SqrtEstSIMD( const fltx4 & a ) // sqrt(a), more or less -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = sqrt( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = sqrt( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = sqrt( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = sqrt( SubFloat( a, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 SqrtSIMD( const fltx4 & a ) // sqrt(a) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = sqrt( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = sqrt( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = sqrt( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = sqrt( SubFloat( a, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSIMD( const fltx4 & a ) // 1/sqrt(a), more or less -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / sqrt( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = 1.0 / sqrt( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = 1.0 / sqrt( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = 1.0 / sqrt( SubFloat( a, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / sqrt( SubFloat( a, 0 ) != 0.0f ? SubFloat( a, 0 ) : FLT_EPSILON ); - SubFloat( retVal, 1 ) = 1.0 / sqrt( SubFloat( a, 1 ) != 0.0f ? SubFloat( a, 1 ) : FLT_EPSILON ); - SubFloat( retVal, 2 ) = 1.0 / sqrt( SubFloat( a, 2 ) != 0.0f ? SubFloat( a, 2 ) : FLT_EPSILON ); - SubFloat( retVal, 3 ) = 1.0 / sqrt( SubFloat( a, 3 ) != 0.0f ? SubFloat( a, 3 ) : FLT_EPSILON ); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalSqrtSIMD( const fltx4 & a ) // 1/sqrt(a) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / sqrt( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = 1.0 / sqrt( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = 1.0 / sqrt( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = 1.0 / sqrt( SubFloat( a, 3 ) ); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalEstSIMD( const fltx4 & a ) // 1/a, more or less -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / SubFloat( a, 0 ); - SubFloat( retVal, 1 ) = 1.0 / SubFloat( a, 1 ); - SubFloat( retVal, 2 ) = 1.0 / SubFloat( a, 2 ); - SubFloat( retVal, 3 ) = 1.0 / SubFloat( a, 3 ); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalSIMD( const fltx4 & a ) // 1/a -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / SubFloat( a, 0 ); - SubFloat( retVal, 1 ) = 1.0 / SubFloat( a, 1 ); - SubFloat( retVal, 2 ) = 1.0 / SubFloat( a, 2 ); - SubFloat( retVal, 3 ) = 1.0 / SubFloat( a, 3 ); - return retVal; -} - -/// 1/x for all 4 values. -/// 1/0 will result in a big but NOT infinite result -FORCEINLINE fltx4 ReciprocalEstSaturateSIMD( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / (SubFloat( a, 0 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 0 )); - SubFloat( retVal, 1 ) = 1.0 / (SubFloat( a, 1 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 1 )); - SubFloat( retVal, 2 ) = 1.0 / (SubFloat( a, 2 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 2 )); - SubFloat( retVal, 3 ) = 1.0 / (SubFloat( a, 3 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 3 )); - return retVal; -} - -FORCEINLINE fltx4 ReciprocalSaturateSIMD( const fltx4 & a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = 1.0 / (SubFloat( a, 0 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 0 )); - SubFloat( retVal, 1 ) = 1.0 / (SubFloat( a, 1 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 1 )); - SubFloat( retVal, 2 ) = 1.0 / (SubFloat( a, 2 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 2 )); - SubFloat( retVal, 3 ) = 1.0 / (SubFloat( a, 3 ) == 0.0f ? FLT_EPSILON : SubFloat( a, 3 )); - return retVal; -} - -// 2^x for all values (the antilog) -FORCEINLINE fltx4 ExpSIMD( const fltx4 &toPower ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = powf( 2, SubFloat(toPower, 0) ); - SubFloat( retVal, 1 ) = powf( 2, SubFloat(toPower, 1) ); - SubFloat( retVal, 2 ) = powf( 2, SubFloat(toPower, 2) ); - SubFloat( retVal, 3 ) = powf( 2, SubFloat(toPower, 3) ); - - return retVal; -} - -FORCEINLINE fltx4 Dot3SIMD( const fltx4 &a, const fltx4 &b ) -{ - float flDot = SubFloat( a, 0 ) * SubFloat( b, 0 ) + - SubFloat( a, 1 ) * SubFloat( b, 1 ) + - SubFloat( a, 2 ) * SubFloat( b, 2 ); - return ReplicateX4( flDot ); -} - -FORCEINLINE fltx4 Dot4SIMD( const fltx4 &a, const fltx4 &b ) -{ - float flDot = SubFloat( a, 0 ) * SubFloat( b, 0 ) + - SubFloat( a, 1 ) * SubFloat( b, 1 ) + - SubFloat( a, 2 ) * SubFloat( b, 2 ) + - SubFloat( a, 3 ) * SubFloat( b, 3 ); - return ReplicateX4( flDot ); -} - -// Clamps the components of a vector to a specified minimum and maximum range. -FORCEINLINE fltx4 ClampVectorSIMD( FLTX4 in, FLTX4 min, FLTX4 max) -{ - return MaxSIMD( min, MinSIMD( max, in ) ); -} - -// Squelch the w component of a vector to +0.0. -// Most efficient when you say a = SetWToZeroSIMD(a) (avoids a copy) -FORCEINLINE fltx4 SetWToZeroSIMD( const fltx4 & a ) -{ - fltx4 retval; - retval = a; - SubFloat( retval, 0 ) = 0; - return retval; -} - -FORCEINLINE fltx4 LoadUnalignedSIMD( const void *pSIMD ) -{ - return *( reinterpret_cast< const fltx4 *> ( pSIMD ) ); -} - -FORCEINLINE fltx4 LoadUnaligned3SIMD( const void *pSIMD ) -{ - return *( reinterpret_cast< const fltx4 *> ( pSIMD ) ); -} - -FORCEINLINE fltx4 LoadAlignedSIMD( const void *pSIMD ) -{ - return *( reinterpret_cast< const fltx4 *> ( pSIMD ) ); -} - -// for the transitional class -- load a 3-by VectorAligned and squash its w component -FORCEINLINE fltx4 LoadAlignedSIMD( const VectorAligned & pSIMD ) -{ - fltx4 retval = LoadAlignedSIMD(pSIMD.Base()); - // squelch w - SubInt( retval, 3 ) = 0; - return retval; -} - -FORCEINLINE void StoreAlignedSIMD( float *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< fltx4 *> ( pSIMD ) ) = a; -} - -FORCEINLINE void StoreUnalignedSIMD( float *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< fltx4 *> ( pSIMD ) ) = a; -} - -FORCEINLINE void StoreUnaligned3SIMD( float *pSIMD, const fltx4 & a ) -{ - *pSIMD = SubFloat(a, 0); - *(pSIMD+1) = SubFloat(a, 1); - *(pSIMD+2) = SubFloat(a, 2); -} - -// strongly typed -- syntactic castor oil used for typechecking as we transition to SIMD -FORCEINLINE void StoreAligned3SIMD( VectorAligned * RESTRICT pSIMD, const fltx4 & a ) -{ - StoreAlignedSIMD(pSIMD->Base(),a); -} - -FORCEINLINE void TransposeSIMD( fltx4 & x, fltx4 & y, fltx4 & z, fltx4 & w ) -{ -#define SWAP_FLOATS( _a_, _ia_, _b_, _ib_ ) { float tmp = SubFloat( _a_, _ia_ ); SubFloat( _a_, _ia_ ) = SubFloat( _b_, _ib_ ); SubFloat( _b_, _ib_ ) = tmp; } - SWAP_FLOATS( x, 1, y, 0 ); - SWAP_FLOATS( x, 2, z, 0 ); - SWAP_FLOATS( x, 3, w, 0 ); - SWAP_FLOATS( y, 2, z, 1 ); - SWAP_FLOATS( y, 3, w, 1 ); - SWAP_FLOATS( z, 3, w, 2 ); -} - -// find the lowest component of a.x, a.y, a.z, -// and replicate it to the whole return value. -FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 & a ) -{ - float lowest = min( min( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); - return ReplicateX4(lowest); -} - -// find the highest component of a.x, a.y, a.z, -// and replicate it to the whole return value. -FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 & a ) -{ - float highest = max( max( SubFloat(a, 0), SubFloat(a, 1) ), SubFloat(a, 2)); - return ReplicateX4(highest); -} - -// Fixed-point conversion and save as SIGNED INTS. -// pDest->x = Int (vSrc.x) -// note: some architectures have means of doing -// fixed point conversion when the fix depth is -// specified as an immediate.. but there is no way -// to guarantee an immediate as a parameter to function -// like this. -FORCEINLINE void ConvertStoreAsIntsSIMD(intx4 * RESTRICT pDest, const fltx4 &vSrc) -{ - (*pDest)[0] = SubFloat(vSrc, 0); - (*pDest)[1] = SubFloat(vSrc, 1); - (*pDest)[2] = SubFloat(vSrc, 2); - (*pDest)[3] = SubFloat(vSrc, 3); -} - -// ------------------------------------ -// INTEGER SIMD OPERATIONS. -// ------------------------------------ -// splat all components of a vector to a signed immediate int number. -FORCEINLINE fltx4 IntSetImmediateSIMD( int nValue ) -{ - fltx4 retval; - SubInt( retval, 0 ) = SubInt( retval, 1 ) = SubInt( retval, 2 ) = SubInt( retval, 3) = nValue; - return retval; -} - -// Load 4 aligned words into a SIMD register -FORCEINLINE i32x4 LoadAlignedIntSIMD(const void * RESTRICT pSIMD) -{ - return *( reinterpret_cast< const i32x4 *> ( pSIMD ) ); -} - -// Load 4 unaligned words into a SIMD register -FORCEINLINE i32x4 LoadUnalignedIntSIMD( const void * RESTRICT pSIMD) -{ - return *( reinterpret_cast< const i32x4 *> ( pSIMD ) ); -} - -// save into four words, 16-byte aligned -FORCEINLINE void StoreAlignedIntSIMD( int32 *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< i32x4 *> ( pSIMD ) ) = a; -} - -FORCEINLINE void StoreAlignedIntSIMD( intx4 &pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< i32x4 *> ( pSIMD.Base() ) ) = a; -} - -FORCEINLINE void StoreUnalignedIntSIMD( int32 *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< i32x4 *> ( pSIMD ) ) = a; -} - -// Take a fltx4 containing fixed-point uints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD( const u32x4 &vSrcA ) -{ - Assert(0); /* pc has no such operation */ - fltx4 retval; - SubFloat( retval, 0 ) = ( (float) SubInt( retval, 0 ) ); - SubFloat( retval, 1 ) = ( (float) SubInt( retval, 1 ) ); - SubFloat( retval, 2 ) = ( (float) SubInt( retval, 2 ) ); - SubFloat( retval, 3 ) = ( (float) SubInt( retval, 3 ) ); - return retval; -} - - -#if 0 /* pc has no such op */ -// Take a fltx4 containing fixed-point sints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 SignedIntConvertToFltSIMD( const i32x4 &vSrcA ) -{ - fltx4 retval; - SubFloat( retval, 0 ) = ( (float) (reinterpret_cast(&vSrcA.m128_s32[0])) ); - SubFloat( retval, 1 ) = ( (float) (reinterpret_cast(&vSrcA.m128_s32[1])) ); - SubFloat( retval, 2 ) = ( (float) (reinterpret_cast(&vSrcA.m128_s32[2])) ); - SubFloat( retval, 3 ) = ( (float) (reinterpret_cast(&vSrcA.m128_s32[3])) ); - return retval; -} - - -/* - works on fltx4's as if they are four uints. - the first parameter contains the words to be shifted, - the second contains the amount to shift by AS INTS - - for i = 0 to 3 - shift = vSrcB_i*32:(i*32)+4 - vReturned_i*32:(i*32)+31 = vSrcA_i*32:(i*32)+31 << shift -*/ -FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4 &vSrcA, const i32x4 &vSrcB) -{ - i32x4 retval; - SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); - SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); - SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); - SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); - - - return retval; -} -#endif - -#elif ( defined( _X360 ) ) - -//--------------------------------------------------------------------- -// X360 implementation -//--------------------------------------------------------------------- - -FORCEINLINE float & FloatSIMD( fltx4 & a, int idx ) -{ - fltx4_union & a_union = (fltx4_union &)a; - return a_union.m128_f32[idx]; -} - -FORCEINLINE unsigned int & UIntSIMD( fltx4 & a, int idx ) -{ - fltx4_union & a_union = (fltx4_union &)a; - return a_union.m128_u32[idx]; -} - -FORCEINLINE fltx4 AddSIMD( const fltx4 & a, const fltx4 & b ) -{ - return __vaddfp( a, b ); -} - -FORCEINLINE fltx4 SubSIMD( const fltx4 & a, const fltx4 & b ) // a-b -{ - return __vsubfp( a, b ); -} - -FORCEINLINE fltx4 MulSIMD( const fltx4 & a, const fltx4 & b ) // a*b -{ - return __vmulfp( a, b ); -} - -FORCEINLINE fltx4 MaddSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // a*b + c -{ - return __vmaddfp( a, b, c ); -} - -FORCEINLINE fltx4 MsubSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // c - a*b -{ - return __vnmsubfp( a, b, c ); -}; - -FORCEINLINE fltx4 Dot3SIMD( const fltx4 &a, const fltx4 &b ) -{ - return __vmsum3fp( a, b ); -} - -FORCEINLINE fltx4 Dot4SIMD( const fltx4 &a, const fltx4 &b ) -{ - return __vmsum4fp( a, b ); -} - -FORCEINLINE fltx4 SinSIMD( const fltx4 &radians ) -{ - return XMVectorSin( radians ); -} - -FORCEINLINE void SinCos3SIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) -{ - XMVectorSinCos( &sine, &cosine, radians ); -} - -FORCEINLINE void SinCosSIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) -{ - XMVectorSinCos( &sine, &cosine, radians ); -} - -FORCEINLINE void CosSIMD( fltx4 &cosine, const fltx4 &radians ) -{ - cosine = XMVectorCos( radians ); -} - -FORCEINLINE fltx4 ArcSinSIMD( const fltx4 &sine ) -{ - return XMVectorASin( sine ); -} - -FORCEINLINE fltx4 ArcCosSIMD( const fltx4 &cs ) -{ - return XMVectorACos( cs ); -} - -// tan^1(a/b) .. ie, pass sin in as a and cos in as b -FORCEINLINE fltx4 ArcTan2SIMD( const fltx4 &a, const fltx4 &b ) -{ - return XMVectorATan2( a, b ); -} - -// DivSIMD defined further down, since it uses ReciprocalSIMD - -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) -{ - return __vmaxfp( a, b ); -} - -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) -{ - return __vminfp( a, b ); -} - -FORCEINLINE fltx4 AndSIMD( const fltx4 & a, const fltx4 & b ) // a & b -{ - return __vand( a, b ); -} - -FORCEINLINE fltx4 AndNotSIMD( const fltx4 & a, const fltx4 & b ) // ~a & b -{ - // NOTE: a and b are swapped in the call: SSE complements the first argument, VMX the second - return __vandc( b, a ); -} - -FORCEINLINE fltx4 XorSIMD( const fltx4 & a, const fltx4 & b ) // a ^ b -{ - return __vxor( a, b ); -} - -FORCEINLINE fltx4 OrSIMD( const fltx4 & a, const fltx4 & b ) // a | b -{ - return __vor( a, b ); -} - -FORCEINLINE fltx4 NegSIMD(const fltx4 &a) // negate: -a -{ - return XMVectorNegate(a); -} - -FORCEINLINE bool IsAllZeros( const fltx4 & a ) // all floats of a zero? -{ - unsigned int equalFlags = 0; - __vcmpeqfpR( a, Four_Zeros, &equalFlags ); - return XMComparisonAllTrue( equalFlags ); -} - -FORCEINLINE bool IsAnyZeros( const fltx4 & a ) // any floats are zero? -{ - unsigned int conditionregister; - XMVectorEqualR(&conditionregister, a, XMVectorZero()); - return XMComparisonAnyTrue(conditionregister); -} - -FORCEINLINE bool IsAnyXYZZero( const fltx4 &a ) // are any of x,y,z zero? -{ - // copy a's x component into w, in case w was zero. - fltx4 temp = __vrlimi(a, a, 1, 1); - unsigned int conditionregister; - XMVectorEqualR(&conditionregister, temp, XMVectorZero()); - return XMComparisonAnyTrue(conditionregister); -} - -// for branching when a.xyzw > b.xyzw -FORCEINLINE bool IsAllGreaterThan( const fltx4 &a, const fltx4 &b ) -{ - unsigned int cr; - XMVectorGreaterR(&cr,a,b); - return XMComparisonAllTrue(cr); -} - -// for branching when a.xyzw >= b.xyzw -FORCEINLINE bool IsAllGreaterThanOrEq( const fltx4 &a, const fltx4 &b ) -{ - unsigned int cr; - XMVectorGreaterOrEqualR(&cr,a,b); - return XMComparisonAllTrue(cr); -} - -// For branching if all a.xyzw == b.xyzw -FORCEINLINE bool IsAllEqual( const fltx4 & a, const fltx4 & b ) -{ - unsigned int cr; - XMVectorEqualR(&cr,a,b); - return XMComparisonAllTrue(cr); -} - - -FORCEINLINE int TestSignSIMD( const fltx4 & a ) // mask of which floats have the high bit set -{ - // NOTE: this maps to SSE way better than it does to VMX (most code uses IsAnyNegative(), though) - int nRet = 0; - - const fltx4_union & a_union = (const fltx4_union &)a; - nRet |= ( a_union.m128_u32[0] & 0x80000000 ) >> 31; // sign(x) -> bit 0 - nRet |= ( a_union.m128_u32[1] & 0x80000000 ) >> 30; // sign(y) -> bit 1 - nRet |= ( a_union.m128_u32[2] & 0x80000000 ) >> 29; // sign(z) -> bit 2 - nRet |= ( a_union.m128_u32[3] & 0x80000000 ) >> 28; // sign(w) -> bit 3 - - return nRet; -} - -// Squelch the w component of a vector to +0.0. -// Most efficient when you say a = SetWToZeroSIMD(a) (avoids a copy) -FORCEINLINE fltx4 SetWToZeroSIMD( const fltx4 & a ) -{ - return __vrlimi( a, __vzero(), 1, 0 ); -} - -FORCEINLINE bool IsAnyNegative( const fltx4 & a ) // (a.x < 0) || (a.y < 0) || (a.z < 0) || (a.w < 0) -{ - // NOTE: this tests the top bits of each vector element using integer math - // (so it ignores NaNs - it will return true for "-NaN") - unsigned int equalFlags = 0; - fltx4 signMask = __vspltisw( -1 ); // 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF (low order 5 bits of each element = 31) - signMask = __vslw( signMask, signMask ); // 0x80000000 0x80000000 0x80000000 0x80000000 - __vcmpequwR( Four_Zeros, __vand( signMask, a ), &equalFlags ); - return !XMComparisonAllTrue( equalFlags ); -} - -FORCEINLINE fltx4 CmpEqSIMD( const fltx4 & a, const fltx4 & b ) // (a==b) ? ~0:0 -{ - return __vcmpeqfp( a, b ); -} - - -FORCEINLINE fltx4 CmpGtSIMD( const fltx4 & a, const fltx4 & b ) // (a>b) ? ~0:0 -{ - return __vcmpgtfp( a, b ); -} - -FORCEINLINE fltx4 CmpGeSIMD( const fltx4 & a, const fltx4 & b ) // (a>=b) ? ~0:0 -{ - return __vcmpgefp( a, b ); -} - -FORCEINLINE fltx4 CmpLtSIMD( const fltx4 & a, const fltx4 & b ) // (a= -b) ? ~0 : 0 -{ - return XMVectorInBounds( a, b ); -} - -// returned[i] = ReplacementMask[i] == 0 ? OldValue : NewValue -FORCEINLINE fltx4 MaskedAssign( const fltx4 & ReplacementMask, const fltx4 & NewValue, const fltx4 & OldValue ) -{ - return __vsel( OldValue, NewValue, ReplacementMask ); -} - -// AKA "Broadcast", "Splat" -FORCEINLINE fltx4 ReplicateX4( float flValue ) // a,a,a,a -{ - // NOTE: if flValue comes from a register, this causes a Load-Hit-Store stall (don't mix fpu/vpu math!) - float * pValue = &flValue; - Assert( pValue ); - Assert( ((unsigned int)pValue & 3) == 0); - return __vspltw( __lvlx( pValue, 0 ), 0 ); -} - -FORCEINLINE fltx4 ReplicateX4( const float *pValue ) // a,a,a,a -{ - Assert( pValue ); - return __vspltw( __lvlx( pValue, 0 ), 0 ); -} - -/// replicate a single 32 bit integer value to all 4 components of an m128 -FORCEINLINE fltx4 ReplicateIX4( int nValue ) -{ - // NOTE: if nValue comes from a register, this causes a Load-Hit-Store stall (should not mix ints with fltx4s!) - int * pValue = &nValue; - Assert( pValue ); - Assert( ((unsigned int)pValue & 3) == 0); - return __vspltw( __lvlx( pValue, 0 ), 0 ); -} - -// Round towards positive infinity -FORCEINLINE fltx4 CeilSIMD( const fltx4 &a ) -{ - return __vrfip(a); -} - -// Round towards nearest integer -FORCEINLINE fltx4 RoundSIMD( const fltx4 &a ) -{ - return __vrfin(a); -} - -// Round towards negative infinity -FORCEINLINE fltx4 FloorSIMD( const fltx4 &a ) -{ - return __vrfim(a); -} - -FORCEINLINE fltx4 SqrtEstSIMD( const fltx4 & a ) // sqrt(a), more or less -{ - // This is emulated from rsqrt - return XMVectorSqrtEst( a ); -} - -FORCEINLINE fltx4 SqrtSIMD( const fltx4 & a ) // sqrt(a) -{ - // This is emulated from rsqrt - return XMVectorSqrt( a ); -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSIMD( const fltx4 & a ) // 1/sqrt(a), more or less -{ - return __vrsqrtefp( a ); -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD( const fltx4 & a ) -{ - // Convert zeros to epsilons - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 a_safe = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - return ReciprocalSqrtEstSIMD( a_safe ); -} - -FORCEINLINE fltx4 ReciprocalSqrtSIMD( const fltx4 & a ) // 1/sqrt(a) -{ - // This uses Newton-Raphson to improve the HW result - return XMVectorReciprocalSqrt( a ); -} - -FORCEINLINE fltx4 ReciprocalEstSIMD( const fltx4 & a ) // 1/a, more or less -{ - return __vrefp( a ); -} - -/// 1/x for all 4 values. uses reciprocal approximation instruction plus newton iteration. -/// No error checking! -FORCEINLINE fltx4 ReciprocalSIMD( const fltx4 & a ) // 1/a -{ - // This uses Newton-Raphson to improve the HW result - return XMVectorReciprocal( a ); -} - -// FIXME: on 360, this is very slow, since it uses ReciprocalSIMD (do we need DivEstSIMD?) -FORCEINLINE fltx4 DivSIMD( const fltx4 & a, const fltx4 & b ) // a/b -{ - return MulSIMD( ReciprocalSIMD( b ), a ); -} - -/// 1/x for all 4 values. -/// 1/0 will result in a big but NOT infinite result -FORCEINLINE fltx4 ReciprocalEstSaturateSIMD( const fltx4 & a ) -{ - // Convert zeros to epsilons - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 a_safe = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - return ReciprocalEstSIMD( a_safe ); -} - -FORCEINLINE fltx4 ReciprocalSaturateSIMD( const fltx4 & a ) -{ - // Convert zeros to epsilons - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 a_safe = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - return ReciprocalSIMD( a_safe ); - - // FIXME: This could be faster (BUT: it doesn't preserve the sign of -0.0, whereas the above does) - // fltx4 zeroMask = CmpEqSIMD( Four_Zeros, a ); - // fltx4 a_safe = XMVectorSelect( a, Four_Epsilons, zeroMask ); - // return ReciprocalSIMD( a_safe ); -} - -// CHRISG: is it worth doing integer bitfiddling for this? -// 2^x for all values (the antilog) -FORCEINLINE fltx4 ExpSIMD( const fltx4 &toPower ) -{ - return XMVectorExp(toPower); -} - -// Clamps the components of a vector to a specified minimum and maximum range. -FORCEINLINE fltx4 ClampVectorSIMD( FLTX4 in, FLTX4 min, FLTX4 max) -{ - return XMVectorClamp(in, min, max); -} - -FORCEINLINE fltx4 LoadUnalignedSIMD( const void *pSIMD ) -{ - return XMLoadVector4( pSIMD ); -} - -// load a 3-vector (as opposed to LoadUnalignedSIMD, which loads a 4-vec). -FORCEINLINE fltx4 LoadUnaligned3SIMD( const void *pSIMD ) -{ - return XMLoadVector3( pSIMD ); -} - -FORCEINLINE fltx4 LoadAlignedSIMD( const void *pSIMD ) -{ - return *( reinterpret_cast< const fltx4 *> ( pSIMD ) ); -} - -// for the transitional class -- load a 3-by VectorAligned and squash its w component -FORCEINLINE fltx4 LoadAlignedSIMD( const VectorAligned & pSIMD ) -{ - fltx4 out = XMLoadVector3A(pSIMD.Base()); - // squelch w - return __vrlimi( out, __vzero(), 1, 0 ); -} - -// for the transitional class -- load a 3-by VectorAligned and squash its w component -FORCEINLINE fltx4 LoadAlignedSIMD( const VectorAligned * RESTRICT pSIMD ) -{ - fltx4 out = XMLoadVector3A(pSIMD); - // squelch w - return __vrlimi( out, __vzero(), 1, 0 ); -} - -FORCEINLINE void StoreAlignedSIMD( float *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< fltx4 *> ( pSIMD ) ) = a; -} - -FORCEINLINE void StoreUnalignedSIMD( float *pSIMD, const fltx4 & a ) -{ - XMStoreVector4( pSIMD, a ); -} - -FORCEINLINE void StoreUnaligned3SIMD( float *pSIMD, const fltx4 & a ) -{ - XMStoreVector3( pSIMD, a ); -} - - -// strongly typed -- for typechecking as we transition to SIMD -FORCEINLINE void StoreAligned3SIMD( VectorAligned * RESTRICT pSIMD, const fltx4 & a ) -{ - XMStoreVector3A(pSIMD->Base(),a); -} - - -// Fixed-point conversion and save as SIGNED INTS. -// pDest->x = Int (vSrc.x) -// note: some architectures have means of doing -// fixed point conversion when the fix depth is -// specified as an immediate.. but there is no way -// to guarantee an immediate as a parameter to function -// like this. -FORCEINLINE void ConvertStoreAsIntsSIMD(intx4 * RESTRICT pDest, const fltx4 &vSrc) -{ - fltx4 asInt = __vctsxs( vSrc, 0 ); - XMStoreVector4A(pDest->Base(), asInt); -} - -FORCEINLINE void TransposeSIMD( fltx4 & x, fltx4 & y, fltx4 & z, fltx4 & w ) -{ - XMMATRIX xyzwMatrix = _XMMATRIX( x, y, z, w ); - xyzwMatrix = XMMatrixTranspose( xyzwMatrix ); - x = xyzwMatrix.r[0]; - y = xyzwMatrix.r[1]; - z = xyzwMatrix.r[2]; - w = xyzwMatrix.r[3]; -} - -// Return one in the fastest way -- faster even than loading. -FORCEINLINE fltx4 LoadZeroSIMD( void ) -{ - return XMVectorZero(); -} - -// Return one in the fastest way -- faster even than loading. -FORCEINLINE fltx4 LoadOneSIMD( void ) -{ - return XMVectorSplatOne(); -} - -FORCEINLINE fltx4 SplatXSIMD( fltx4 a ) -{ - return XMVectorSplatX( a ); -} - -FORCEINLINE fltx4 SplatYSIMD( fltx4 a ) -{ - return XMVectorSplatY( a ); -} - -FORCEINLINE fltx4 SplatZSIMD( fltx4 a ) -{ - return XMVectorSplatZ( a ); -} - -FORCEINLINE fltx4 SplatWSIMD( fltx4 a ) -{ - return XMVectorSplatW( a ); -} - -FORCEINLINE fltx4 SetXSIMD( const fltx4& a, const fltx4& x ) -{ - fltx4 result = __vrlimi(a, x, 8, 0); - return result; -} - -FORCEINLINE fltx4 SetYSIMD( const fltx4& a, const fltx4& y ) -{ - fltx4 result = __vrlimi(a, y, 4, 0); - return result; -} - -FORCEINLINE fltx4 SetZSIMD( const fltx4& a, const fltx4& z ) -{ - fltx4 result = __vrlimi(a, z, 2, 0); - return result; -} - -FORCEINLINE fltx4 SetWSIMD( const fltx4& a, const fltx4& w ) -{ - fltx4 result = __vrlimi(a, w, 1, 0); - return result; -} - -FORCEINLINE fltx4 SetComponentSIMD( const fltx4& a, int nComponent, float flValue ) -{ - static int s_nVrlimiMask[4] = { 8, 4, 2, 1 }; - fltx4 val = ReplicateX4( flValue ); - fltx4 result = __vrlimi(a, val, s_nVrlimiMask[nComponent], 0); - return result; -} - -FORCEINLINE fltx4 RotateLeft( const fltx4 & a ) -{ - fltx4 compareOne = a; - return __vrlimi( compareOne, a, 8 | 4 | 2 | 1, 1 ); -} - -FORCEINLINE fltx4 RotateLeft2( const fltx4 & a ) -{ - fltx4 compareOne = a; - return __vrlimi( compareOne, a, 8 | 4 | 2 | 1, 2 ); -} - - - -// find the lowest component of a.x, a.y, a.z, -// and replicate it to the whole return value. -// ignores a.w. -// Though this is only five instructions long, -// they are all dependent, making this stall city. -// Forcing this inline should hopefully help with scheduling. -FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 & a ) -{ - // a is [x,y,z,G] (where G is garbage) - // rotate left by one - fltx4 compareOne = a ; - compareOne = __vrlimi( compareOne, a, 8 | 4 , 1 ); - // compareOne is [y,z,G,G] - fltx4 retval = MinSIMD( a, compareOne ); - // retVal is [min(x,y), min(y,z), G, G] - compareOne = __vrlimi( compareOne, a, 8 , 2); - // compareOne is [z, G, G, G] - retval = MinSIMD( retval, compareOne ); - // retVal = [ min(min(x,y),z), G, G, G ] - - // splat the x component out to the whole vector and return - return SplatXSIMD( retval ); -} - -// find the highest component of a.x, a.y, a.z, -// and replicate it to the whole return value. -// ignores a.w. -// Though this is only five instructions long, -// they are all dependent, making this stall city. -// Forcing this inline should hopefully help with scheduling. -FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 & a ) -{ - // a is [x,y,z,G] (where G is garbage) - // rotate left by one - fltx4 compareOne = a ; - compareOne = __vrlimi( compareOne, a, 8 | 4 , 1 ); - // compareOne is [y,z,G,G] - fltx4 retval = MaxSIMD( a, compareOne ); - // retVal is [max(x,y), max(y,z), G, G] - compareOne = __vrlimi( compareOne, a, 8 , 2); - // compareOne is [z, G, G, G] - retval = MaxSIMD( retval, compareOne ); - // retVal = [ max(max(x,y),z), G, G, G ] - - // splat the x component out to the whole vector and return - return SplatXSIMD( retval ); -} - - -// Transform many (horizontal) points in-place by a 3x4 matrix, -// here already loaded onto three fltx4 registers. -// The points must be stored as 16-byte aligned. They are points -// and not vectors because we assume the w-component to be 1. -// To spare yourself the annoyance of loading the matrix yourself, -// use one of the overloads below. -void TransformManyPointsBy(VectorAligned * RESTRICT pVectors, unsigned int numVectors, FLTX4 mRow1, FLTX4 mRow2, FLTX4 mRow3); - -// Transform many (horizontal) points in-place by a 3x4 matrix. -// The points must be stored as 16-byte aligned. They are points -// and not vectors because we assume the w-component to be 1. -// In this function, the matrix need not be aligned. -FORCEINLINE void TransformManyPointsBy(VectorAligned * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t &pMatrix) -{ - return TransformManyPointsBy(pVectors, numVectors, - LoadUnalignedSIMD( pMatrix[0] ), LoadUnalignedSIMD( pMatrix[1] ), LoadUnalignedSIMD( pMatrix[2] ) ); -} - -// Transform many (horizontal) points in-place by a 3x4 matrix. -// The points must be stored as 16-byte aligned. They are points -// and not vectors because we assume the w-component to be 1. -// In this function, the matrix must itself be aligned on a 16-byte -// boundary. -FORCEINLINE void TransformManyPointsByA(VectorAligned * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t &pMatrix) -{ - return TransformManyPointsBy(pVectors, numVectors, - LoadAlignedSIMD( pMatrix[0] ), LoadAlignedSIMD( pMatrix[1] ), LoadAlignedSIMD( pMatrix[2] ) ); -} - -// ------------------------------------ -// INTEGER SIMD OPERATIONS. -// ------------------------------------ - -// Load 4 aligned words into a SIMD register -FORCEINLINE i32x4 LoadAlignedIntSIMD( const void * RESTRICT pSIMD) -{ - return XMLoadVector4A(pSIMD); -} - -// Load 4 unaligned words into a SIMD register -FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void * RESTRICT pSIMD) -{ - return XMLoadVector4( pSIMD ); -} - -// save into four words, 16-byte aligned -FORCEINLINE void StoreAlignedIntSIMD( int32 *pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< i32x4 *> ( pSIMD ) ) = a; -} - -FORCEINLINE void StoreAlignedIntSIMD( intx4 &pSIMD, const fltx4 & a ) -{ - *( reinterpret_cast< i32x4 *> ( pSIMD.Base() ) ) = a; -} - -FORCEINLINE void StoreUnalignedIntSIMD( int32 *pSIMD, const fltx4 & a ) -{ - XMStoreVector4(pSIMD, a); -} - - -// Take a fltx4 containing fixed-point uints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD( const i32x4 &vSrcA ) -{ - return __vcfux( vSrcA, 0 ); -} - - -// Take a fltx4 containing fixed-point sints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 SignedIntConvertToFltSIMD( const i32x4 &vSrcA ) -{ - return __vcfsx( vSrcA, 0 ); -} - -// Take a fltx4 containing fixed-point uints and -// return them as single precision floats. Each uint -// will be divided by 2^immed after conversion -// (eg, this is fixed point math). -/* as if: - FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD( const i32x4 &vSrcA, unsigned int uImmed ) - { - return __vcfux( vSrcA, uImmed ); - } -*/ -#define UnsignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfux( (vSrcA), (uImmed) )) - -// Take a fltx4 containing fixed-point sints and -// return them as single precision floats. Each int -// will be divided by 2^immed (eg, this is fixed point -// math). -/* as if: - FORCEINLINE fltx4 SignedIntConvertToFltSIMD( const i32x4 &vSrcA, unsigned int uImmed ) - { - return __vcfsx( vSrcA, uImmed ); - } -*/ -#define SignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfsx( (vSrcA), (uImmed) )) - -// set all components of a vector to a signed immediate int number. -/* as if: - FORCEINLINE fltx4 IntSetImmediateSIMD(int toImmediate) - { - return __vspltisw( toImmediate ); - } -*/ -#define IntSetImmediateSIMD(x) (__vspltisw(x)) - -/* - works on fltx4's as if they are four uints. - the first parameter contains the words to be shifted, - the second contains the amount to shift by AS INTS - - for i = 0 to 3 - shift = vSrcB_i*32:(i*32)+4 - vReturned_i*32:(i*32)+31 = vSrcA_i*32:(i*32)+31 << shift -*/ -FORCEINLINE fltx4 IntShiftLeftWordSIMD(fltx4 vSrcA, fltx4 vSrcB) -{ - return __vslw(vSrcA, vSrcB); -} - -FORCEINLINE float SubFloat( const fltx4 & a, int idx ) -{ - // NOTE: if the output goes into a register, this causes a Load-Hit-Store stall (don't mix fpu/vpu math!) - const fltx4_union & a_union = (const fltx4_union &)a; - return a_union.m128_f32[ idx ]; -} - -FORCEINLINE float & SubFloat( fltx4 & a, int idx ) -{ - fltx4_union & a_union = (fltx4_union &)a; - return a_union.m128_f32[idx]; -} - -FORCEINLINE uint32 SubFloatConvertToInt( const fltx4 & a, int idx ) -{ - fltx4 t = __vctuxs( a, 0 ); - const fltx4_union & a_union = (const fltx4_union &)t; - return a_union.m128_u32[idx]; -} - - -FORCEINLINE uint32 SubInt( const fltx4 & a, int idx ) -{ - const fltx4_union & a_union = (const fltx4_union &)a; - return a_union.m128_u32[idx]; -} - -FORCEINLINE uint32 & SubInt( fltx4 & a, int idx ) -{ - fltx4_union & a_union = (fltx4_union &)a; - return a_union.m128_u32[idx]; -} - -#else - -//--------------------------------------------------------------------- -// Intel/SSE implementation -//--------------------------------------------------------------------- - -FORCEINLINE void StoreAlignedSIMD( float * RESTRICT pSIMD, const fltx4 & a ) -{ - _mm_store_ps( pSIMD, a ); -} - -FORCEINLINE void StoreUnalignedSIMD( float * RESTRICT pSIMD, const fltx4 & a ) -{ - _mm_storeu_ps( pSIMD, a ); -} - - -FORCEINLINE fltx4 RotateLeft( const fltx4 & a ); -FORCEINLINE fltx4 RotateLeft2( const fltx4 & a ); - -FORCEINLINE void StoreUnaligned3SIMD( float *pSIMD, const fltx4 & a ) -{ - _mm_store_ss(pSIMD, a); - _mm_store_ss(pSIMD+1, RotateLeft(a)); - _mm_store_ss(pSIMD+2, RotateLeft2(a)); -} - -// strongly typed -- syntactic castor oil used for typechecking as we transition to SIMD -FORCEINLINE void StoreAligned3SIMD( VectorAligned * RESTRICT pSIMD, const fltx4 & a ) -{ - StoreAlignedSIMD( pSIMD->Base(),a ); -} - -FORCEINLINE fltx4 LoadAlignedSIMD( const void *pSIMD ) -{ - return _mm_load_ps( reinterpret_cast< const float *> ( pSIMD ) ); -} - -FORCEINLINE fltx4 AndSIMD( const fltx4 & a, const fltx4 & b ) // a & b -{ - return _mm_and_ps( a, b ); -} - -FORCEINLINE fltx4 AndNotSIMD( const fltx4 & a, const fltx4 & b ) // a & ~b -{ - return _mm_andnot_ps( a, b ); -} - -FORCEINLINE fltx4 XorSIMD( const fltx4 & a, const fltx4 & b ) // a ^ b -{ - return _mm_xor_ps( a, b ); -} - -FORCEINLINE fltx4 OrSIMD( const fltx4 & a, const fltx4 & b ) // a | b -{ - return _mm_or_ps( a, b ); -} - -// Squelch the w component of a vector to +0.0. -// Most efficient when you say a = SetWToZeroSIMD(a) (avoids a copy) -FORCEINLINE fltx4 SetWToZeroSIMD( const fltx4 & a ) -{ - return AndSIMD( a, LoadAlignedSIMD( g_SIMD_clear_wmask ) ); -} - -// for the transitional class -- load a 3-by VectorAligned and squash its w component -FORCEINLINE fltx4 LoadAlignedSIMD( const VectorAligned & pSIMD ) -{ - return SetWToZeroSIMD( LoadAlignedSIMD(pSIMD.Base()) ); -} - -FORCEINLINE fltx4 LoadUnalignedSIMD( const void *pSIMD ) -{ - return _mm_loadu_ps( reinterpret_cast( pSIMD ) ); -} - -FORCEINLINE fltx4 LoadUnaligned3SIMD( const void *pSIMD ) -{ - return _mm_loadu_ps( reinterpret_cast( pSIMD ) ); -} - -/// replicate a single 32 bit integer value to all 4 components of an m128 -FORCEINLINE fltx4 ReplicateIX4( int i ) -{ - fltx4 value = _mm_set_ss( * ( ( float *) &i ) );; - return _mm_shuffle_ps( value, value, 0); -} - - -FORCEINLINE fltx4 ReplicateX4( float flValue ) -{ - __m128 value = _mm_set_ss( flValue ); - return _mm_shuffle_ps( value, value, 0 ); -} - - -FORCEINLINE float SubFloat( const fltx4 & a, int idx ) -{ - // NOTE: if the output goes into a register, this causes a Load-Hit-Store stall (don't mix fpu/vpu math!) -#ifndef _LINUX - return a.m128_f32[ idx ]; -#else - return (reinterpret_cast(&a))[idx]; -#endif -} - -FORCEINLINE float & SubFloat( fltx4 & a, int idx ) -{ -#ifndef _LINUX - return a.m128_f32[ idx ]; -#else - return (reinterpret_cast(&a))[idx]; -#endif -} - -FORCEINLINE uint32 SubFloatConvertToInt( const fltx4 & a, int idx ) -{ - return (uint32)SubFloat(a,idx); -} - -FORCEINLINE uint32 SubInt( const fltx4 & a, int idx ) -{ -#ifndef _LINUX - return a.m128_u32[idx]; -#else - return (reinterpret_cast(&a))[idx]; -#endif -} - -FORCEINLINE uint32 & SubInt( fltx4 & a, int idx ) -{ -#ifndef _LINUX - return a.m128_u32[idx]; -#else - return (reinterpret_cast(&a))[idx]; -#endif -} - -// Return one in the fastest way -- on the x360, faster even than loading. -FORCEINLINE fltx4 LoadZeroSIMD( void ) -{ - return Four_Zeros; -} - -// Return one in the fastest way -- on the x360, faster even than loading. -FORCEINLINE fltx4 LoadOneSIMD( void ) -{ - return Four_Ones; -} - -FORCEINLINE fltx4 MaskedAssign( const fltx4 & ReplacementMask, const fltx4 & NewValue, const fltx4 & OldValue ) -{ - return OrSIMD( - AndSIMD( ReplacementMask, NewValue ), - AndNotSIMD( ReplacementMask, OldValue ) ); -} - -// remember, the SSE numbers its words 3 2 1 0 -// The way we want to specify shuffles is backwards from the default -// MM_SHUFFLE_REV is in array index order (default is reversed) -#define MM_SHUFFLE_REV(a,b,c,d) _MM_SHUFFLE(d,c,b,a) - -FORCEINLINE fltx4 SplatXSIMD( fltx4 const & a ) -{ - return _mm_shuffle_ps( a, a, MM_SHUFFLE_REV( 0, 0, 0, 0 ) ); -} - -FORCEINLINE fltx4 SplatYSIMD( fltx4 const &a ) -{ - return _mm_shuffle_ps( a, a, MM_SHUFFLE_REV( 1, 1, 1, 1 ) ); -} - -FORCEINLINE fltx4 SplatZSIMD( fltx4 const &a ) -{ - return _mm_shuffle_ps( a, a, MM_SHUFFLE_REV( 2, 2, 2, 2 ) ); -} - -FORCEINLINE fltx4 SplatWSIMD( fltx4 const &a ) -{ - return _mm_shuffle_ps( a, a, _MM_SHUFFLE( 3, 3, 3, 3 ) ); -} - -FORCEINLINE fltx4 SetXSIMD( const fltx4& a, const fltx4& x ) -{ - fltx4 result = MaskedAssign( LoadAlignedSIMD( g_SIMD_ComponentMask[0] ), x, a ); - return result; -} - -FORCEINLINE fltx4 SetYSIMD( const fltx4& a, const fltx4& y ) -{ - fltx4 result = MaskedAssign( LoadAlignedSIMD( g_SIMD_ComponentMask[1] ), y, a ); - return result; -} - -FORCEINLINE fltx4 SetZSIMD( const fltx4& a, const fltx4& z ) -{ - fltx4 result = MaskedAssign( LoadAlignedSIMD( g_SIMD_ComponentMask[2] ), z, a ); - return result; -} - -FORCEINLINE fltx4 SetWSIMD( const fltx4& a, const fltx4& w ) -{ - fltx4 result = MaskedAssign( LoadAlignedSIMD( g_SIMD_ComponentMask[3] ), w, a ); - return result; -} - -FORCEINLINE fltx4 SetComponentSIMD( const fltx4& a, int nComponent, float flValue ) -{ - fltx4 val = ReplicateX4( flValue ); - fltx4 result = MaskedAssign( LoadAlignedSIMD( g_SIMD_ComponentMask[nComponent] ), val, a ); - return result; -} - -// a b c d -> b c d a -FORCEINLINE fltx4 RotateLeft( const fltx4 & a ) -{ - return _mm_shuffle_ps( a, a, MM_SHUFFLE_REV( 1, 2, 3, 0 ) ); -} - -// a b c d -> c d a b -FORCEINLINE fltx4 RotateLeft2( const fltx4 & a ) -{ - return _mm_shuffle_ps( a, a, MM_SHUFFLE_REV( 2, 3, 0, 1 ) ); -} - -// a b c d -> d a b c -FORCEINLINE fltx4 RotateRight( const fltx4 & a ) -{ - return _mm_shuffle_ps( a, a, _MM_SHUFFLE( 0, 3, 2, 1) ); -} - -// a b c d -> c d a b -FORCEINLINE fltx4 RotateRight2( const fltx4 & a ) -{ - return _mm_shuffle_ps( a, a, _MM_SHUFFLE( 1, 0, 3, 2 ) ); -} - - -FORCEINLINE fltx4 AddSIMD( const fltx4 & a, const fltx4 & b ) // a+b -{ - return _mm_add_ps( a, b ); -}; - -FORCEINLINE fltx4 SubSIMD( const fltx4 & a, const fltx4 & b ) // a-b -{ - return _mm_sub_ps( a, b ); -}; - -FORCEINLINE fltx4 MulSIMD( const fltx4 & a, const fltx4 & b ) // a*b -{ - return _mm_mul_ps( a, b ); -}; - -FORCEINLINE fltx4 DivSIMD( const fltx4 & a, const fltx4 & b ) // a/b -{ - return _mm_div_ps( a, b ); -}; - -FORCEINLINE fltx4 MaddSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // a*b + c -{ - return AddSIMD( MulSIMD(a,b), c ); -} - -FORCEINLINE fltx4 MsubSIMD( const fltx4 & a, const fltx4 & b, const fltx4 & c ) // c - a*b -{ - return SubSIMD( c, MulSIMD(a,b) ); -}; - -FORCEINLINE fltx4 Dot3SIMD( const fltx4 &a, const fltx4 &b ) -{ - fltx4 m = MulSIMD( a, b ); - float flDot = SubFloat( m, 0 ) + SubFloat( m, 1 ) + SubFloat( m, 2 ); - return ReplicateX4( flDot ); -} - -FORCEINLINE fltx4 Dot4SIMD( const fltx4 &a, const fltx4 &b ) -{ - fltx4 m = MulSIMD( a, b ); - float flDot = SubFloat( m, 0 ) + SubFloat( m, 1 ) + SubFloat( m, 2 ) + SubFloat( m, 3 ); - return ReplicateX4( flDot ); -} - -//TODO: implement as four-way Taylor series (see xbox implementation) -FORCEINLINE fltx4 SinSIMD( const fltx4 &radians ) -{ - fltx4 result; - SubFloat( result, 0 ) = sin( SubFloat( radians, 0 ) ); - SubFloat( result, 1 ) = sin( SubFloat( radians, 1 ) ); - SubFloat( result, 2 ) = sin( SubFloat( radians, 2 ) ); - SubFloat( result, 3 ) = sin( SubFloat( radians, 3 ) ); - return result; -} - -FORCEINLINE void SinCos3SIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) -{ - // FIXME: Make a fast SSE version - SinCos( SubFloat( radians, 0 ), &SubFloat( sine, 0 ), &SubFloat( cosine, 0 ) ); - SinCos( SubFloat( radians, 1 ), &SubFloat( sine, 1 ), &SubFloat( cosine, 1 ) ); - SinCos( SubFloat( radians, 2 ), &SubFloat( sine, 2 ), &SubFloat( cosine, 2 ) ); -} - -FORCEINLINE void SinCosSIMD( fltx4 &sine, fltx4 &cosine, const fltx4 &radians ) // a*b + c -{ - // FIXME: Make a fast SSE version - SinCos( SubFloat( radians, 0 ), &SubFloat( sine, 0 ), &SubFloat( cosine, 0 ) ); - SinCos( SubFloat( radians, 1 ), &SubFloat( sine, 1 ), &SubFloat( cosine, 1 ) ); - SinCos( SubFloat( radians, 2 ), &SubFloat( sine, 2 ), &SubFloat( cosine, 2 ) ); - SinCos( SubFloat( radians, 3 ), &SubFloat( sine, 3 ), &SubFloat( cosine, 3 ) ); -} - -//TODO: implement as four-way Taylor series (see xbox implementation) -FORCEINLINE fltx4 ArcSinSIMD( const fltx4 &sine ) -{ - // FIXME: Make a fast SSE version - fltx4 result; - SubFloat( result, 0 ) = asin( SubFloat( sine, 0 ) ); - SubFloat( result, 1 ) = asin( SubFloat( sine, 1 ) ); - SubFloat( result, 2 ) = asin( SubFloat( sine, 2 ) ); - SubFloat( result, 3 ) = asin( SubFloat( sine, 3 ) ); - return result; -} - -FORCEINLINE fltx4 ArcCosSIMD( const fltx4 &cs ) -{ - fltx4 result; - SubFloat( result, 0 ) = acos( SubFloat( cs, 0 ) ); - SubFloat( result, 1 ) = acos( SubFloat( cs, 1 ) ); - SubFloat( result, 2 ) = acos( SubFloat( cs, 2 ) ); - SubFloat( result, 3 ) = acos( SubFloat( cs, 3 ) ); - return result; -} - -// tan^1(a/b) .. ie, pass sin in as a and cos in as b -FORCEINLINE fltx4 ArcTan2SIMD( const fltx4 &a, const fltx4 &b ) -{ - fltx4 result; - SubFloat( result, 0 ) = atan2( SubFloat( a, 0 ), SubFloat( b, 0 ) ); - SubFloat( result, 1 ) = atan2( SubFloat( a, 1 ), SubFloat( b, 1 ) ); - SubFloat( result, 2 ) = atan2( SubFloat( a, 2 ), SubFloat( b, 2 ) ); - SubFloat( result, 3 ) = atan2( SubFloat( a, 3 ), SubFloat( b, 3 ) ); - return result; -} - -FORCEINLINE fltx4 NegSIMD(const fltx4 &a) // negate: -a -{ - return SubSIMD(LoadZeroSIMD(),a); -} - -FORCEINLINE int TestSignSIMD( const fltx4 & a ) // mask of which floats have the high bit set -{ - return _mm_movemask_ps( a ); -} - -FORCEINLINE bool IsAnyNegative( const fltx4 & a ) // (a.x < 0) || (a.y < 0) || (a.z < 0) || (a.w < 0) -{ - return (0 != TestSignSIMD( a )); -} - -FORCEINLINE fltx4 CmpEqSIMD( const fltx4 & a, const fltx4 & b ) // (a==b) ? ~0:0 -{ - return _mm_cmpeq_ps( a, b ); -} - -FORCEINLINE fltx4 CmpGtSIMD( const fltx4 & a, const fltx4 & b ) // (a>b) ? ~0:0 -{ - return _mm_cmpgt_ps( a, b ); -} - -FORCEINLINE fltx4 CmpGeSIMD( const fltx4 & a, const fltx4 & b ) // (a>=b) ? ~0:0 -{ - return _mm_cmpge_ps( a, b ); -} - -FORCEINLINE fltx4 CmpLtSIMD( const fltx4 & a, const fltx4 & b ) // (a b.xyzw -FORCEINLINE bool IsAllGreaterThan( const fltx4 &a, const fltx4 &b ) -{ - return TestSignSIMD( CmpLeSIMD( a, b ) ) == 0; -} - -// for branching when a.xyzw >= b.xyzw -FORCEINLINE bool IsAllGreaterThanOrEq( const fltx4 &a, const fltx4 &b ) -{ - return TestSignSIMD( CmpLtSIMD( a, b ) ) == 0; -} - -// For branching if all a.xyzw == b.xyzw -FORCEINLINE bool IsAllEqual( const fltx4 & a, const fltx4 & b ) -{ - return TestSignSIMD( CmpEqSIMD( a, b ) ) == 0xf; -} - -FORCEINLINE fltx4 CmpInBoundsSIMD( const fltx4 & a, const fltx4 & b ) // (a <= b && a >= -b) ? ~0 : 0 -{ - return AndSIMD( CmpLeSIMD(a,b), CmpGeSIMD(a, NegSIMD(b)) ); -} - -FORCEINLINE fltx4 MinSIMD( const fltx4 & a, const fltx4 & b ) // min(a,b) -{ - return _mm_min_ps( a, b ); -} - -FORCEINLINE fltx4 MaxSIMD( const fltx4 & a, const fltx4 & b ) // max(a,b) -{ - return _mm_max_ps( a, b ); -} - - - -// SSE lacks rounding operations. -// Really. -// You can emulate them by setting the rounding mode for the -// whole processor and then converting to int, and then back again. -// But every time you set the rounding mode, you clear out the -// entire pipeline. So, I can't do them per operation. You -// have to do it once, before the loop that would call these. -// Round towards positive infinity -FORCEINLINE fltx4 CeilSIMD( const fltx4 &a ) -{ - fltx4 retVal; - SubFloat( retVal, 0 ) = ceil( SubFloat( a, 0 ) ); - SubFloat( retVal, 1 ) = ceil( SubFloat( a, 1 ) ); - SubFloat( retVal, 2 ) = ceil( SubFloat( a, 2 ) ); - SubFloat( retVal, 3 ) = ceil( SubFloat( a, 3 ) ); - return retVal; - -} - -fltx4 fabs( const fltx4 & x ); -// Round towards negative infinity -// This is the implementation that was here before; it assumes -// you are in round-to-floor mode, which I guess is usually the -// case for us vis-a-vis SSE. It's totally unnecessary on -// VMX, which has a native floor op. -FORCEINLINE fltx4 FloorSIMD( const fltx4 &val ) -{ - fltx4 fl4Abs = fabs( val ); - fltx4 ival = SubSIMD( AddSIMD( fl4Abs, Four_2ToThe23s ), Four_2ToThe23s ); - ival = MaskedAssign( CmpGtSIMD( ival, fl4Abs ), SubSIMD( ival, Four_Ones ), ival ); - return XorSIMD( ival, XorSIMD( val, fl4Abs ) ); // restore sign bits -} - - - -inline bool IsAllZeros( const fltx4 & var ) -{ - return TestSignSIMD( CmpEqSIMD( var, Four_Zeros ) ) == 0xF; -} - -FORCEINLINE fltx4 SqrtEstSIMD( const fltx4 & a ) // sqrt(a), more or less -{ - return _mm_sqrt_ps( a ); -} - -FORCEINLINE fltx4 SqrtSIMD( const fltx4 & a ) // sqrt(a) -{ - return _mm_sqrt_ps( a ); -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSIMD( const fltx4 & a ) // 1/sqrt(a), more or less -{ - return _mm_rsqrt_ps( a ); -} - -FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD( const fltx4 & a ) -{ - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 ret = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - ret = ReciprocalSqrtEstSIMD( ret ); - return ret; -} - -/// uses newton iteration for higher precision results than ReciprocalSqrtEstSIMD -FORCEINLINE fltx4 ReciprocalSqrtSIMD( const fltx4 & a ) // 1/sqrt(a) -{ - fltx4 guess = ReciprocalSqrtEstSIMD( a ); - // newton iteration for 1/sqrt(a) : y(n+1) = 1/2 (y(n)*(3-a*y(n)^2)); - guess = MulSIMD( guess, SubSIMD( Four_Threes, MulSIMD( a, MulSIMD( guess, guess )))); - guess = MulSIMD( Four_PointFives, guess); - return guess; -} - -FORCEINLINE fltx4 ReciprocalEstSIMD( const fltx4 & a ) // 1/a, more or less -{ - return _mm_rcp_ps( a ); -} - -/// 1/x for all 4 values, more or less -/// 1/0 will result in a big but NOT infinite result -FORCEINLINE fltx4 ReciprocalEstSaturateSIMD( const fltx4 & a ) -{ - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 ret = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - ret = ReciprocalEstSIMD( ret ); - return ret; -} - -/// 1/x for all 4 values. uses reciprocal approximation instruction plus newton iteration. -/// No error checking! -FORCEINLINE fltx4 ReciprocalSIMD( const fltx4 & a ) // 1/a -{ - fltx4 ret = ReciprocalEstSIMD( a ); - // newton iteration is: Y(n+1) = 2*Y(n)-a*Y(n)^2 - ret = SubSIMD( AddSIMD( ret, ret ), MulSIMD( a, MulSIMD( ret, ret ) ) ); - return ret; -} - -/// 1/x for all 4 values. -/// 1/0 will result in a big but NOT infinite result -FORCEINLINE fltx4 ReciprocalSaturateSIMD( const fltx4 & a ) -{ - fltx4 zero_mask = CmpEqSIMD( a, Four_Zeros ); - fltx4 ret = OrSIMD( a, AndSIMD( Four_Epsilons, zero_mask ) ); - ret = ReciprocalSIMD( ret ); - return ret; -} - -// CHRISG: is it worth doing integer bitfiddling for this? -// 2^x for all values (the antilog) -FORCEINLINE fltx4 ExpSIMD( const fltx4 &toPower ) -{ - fltx4 retval; - SubFloat( retval, 0 ) = powf( 2, SubFloat(toPower, 0) ); - SubFloat( retval, 1 ) = powf( 2, SubFloat(toPower, 1) ); - SubFloat( retval, 2 ) = powf( 2, SubFloat(toPower, 2) ); - SubFloat( retval, 3 ) = powf( 2, SubFloat(toPower, 3) ); - - return retval; -} - -// Clamps the components of a vector to a specified minimum and maximum range. -FORCEINLINE fltx4 ClampVectorSIMD( FLTX4 in, FLTX4 min, FLTX4 max) -{ - return MaxSIMD( min, MinSIMD( max, in ) ); -} - -FORCEINLINE void TransposeSIMD( fltx4 & x, fltx4 & y, fltx4 & z, fltx4 & w) -{ - _MM_TRANSPOSE4_PS( x, y, z, w ); -} - -FORCEINLINE fltx4 FindLowestSIMD3( const fltx4 &a ) -{ - // a is [x,y,z,G] (where G is garbage) - // rotate left by one - fltx4 compareOne = RotateLeft( a ); - // compareOne is [y,z,G,x] - fltx4 retval = MinSIMD( a, compareOne ); - // retVal is [min(x,y), ... ] - compareOne = RotateLeft2( a ); - // compareOne is [z, G, x, y] - retval = MinSIMD( retval, compareOne ); - // retVal = [ min(min(x,y),z)..] - // splat the x component out to the whole vector and return - return SplatXSIMD( retval ); - -} - -FORCEINLINE fltx4 FindHighestSIMD3( const fltx4 &a ) -{ - // a is [x,y,z,G] (where G is garbage) - // rotate left by one - fltx4 compareOne = RotateLeft( a ); - // compareOne is [y,z,G,x] - fltx4 retval = MaxSIMD( a, compareOne ); - // retVal is [max(x,y), ... ] - compareOne = RotateLeft2( a ); - // compareOne is [z, G, x, y] - retval = MaxSIMD( retval, compareOne ); - // retVal = [ max(max(x,y),z)..] - // splat the x component out to the whole vector and return - return SplatXSIMD( retval ); - -} - -// ------------------------------------ -// INTEGER SIMD OPERATIONS. -// ------------------------------------ - - -#if 0 /* pc does not have these ops */ -// splat all components of a vector to a signed immediate int number. -FORCEINLINE fltx4 IntSetImmediateSIMD(int to) -{ - //CHRISG: SSE2 has this, but not SSE1. What to do? - fltx4 retval; - SubInt( retval, 0 ) = to; - SubInt( retval, 1 ) = to; - SubInt( retval, 2 ) = to; - SubInt( retval, 3 ) = to; - return retval; -} -#endif - -// Load 4 aligned words into a SIMD register -FORCEINLINE i32x4 LoadAlignedIntSIMD( const void * RESTRICT pSIMD) -{ - return _mm_load_ps( reinterpret_cast(pSIMD) ); -} - -// Load 4 unaligned words into a SIMD register -FORCEINLINE i32x4 LoadUnalignedIntSIMD( const void * RESTRICT pSIMD) -{ - return _mm_loadu_ps( reinterpret_cast(pSIMD) ); -} - -// save into four words, 16-byte aligned -FORCEINLINE void StoreAlignedIntSIMD( int32 * RESTRICT pSIMD, const fltx4 & a ) -{ - _mm_store_ps( reinterpret_cast(pSIMD), a ); -} - -FORCEINLINE void StoreAlignedIntSIMD( intx4 &pSIMD, const fltx4 & a ) -{ - _mm_store_ps( reinterpret_cast(pSIMD.Base()), a ); -} - -FORCEINLINE void StoreUnalignedIntSIMD( int32 * RESTRICT pSIMD, const fltx4 & a ) -{ - _mm_storeu_ps( reinterpret_cast(pSIMD), a ); -} - - -// CHRISG: the conversion functions all seem to operate on m64's only... -// how do we make them work here? - -// Take a fltx4 containing fixed-point uints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD( const u32x4 &vSrcA ) -{ - fltx4 retval; - SubFloat( retval, 0 ) = ( (float) SubInt( retval, 0 ) ); - SubFloat( retval, 1 ) = ( (float) SubInt( retval, 1 ) ); - SubFloat( retval, 2 ) = ( (float) SubInt( retval, 2 ) ); - SubFloat( retval, 3 ) = ( (float) SubInt( retval, 3 ) ); - return retval; -} - - -// Take a fltx4 containing fixed-point sints and -// return them as single precision floats. No -// fixed point conversion is done. -FORCEINLINE fltx4 SignedIntConvertToFltSIMD( const i32x4 &vSrcA ) -{ - fltx4 retval; - SubFloat( retval, 0 ) = ( (float) (reinterpret_cast(&vSrcA)[0])); - SubFloat( retval, 1 ) = ( (float) (reinterpret_cast(&vSrcA)[1])); - SubFloat( retval, 2 ) = ( (float) (reinterpret_cast(&vSrcA)[2])); - SubFloat( retval, 3 ) = ( (float) (reinterpret_cast(&vSrcA)[3])); - return retval; -} - -/* - works on fltx4's as if they are four uints. - the first parameter contains the words to be shifted, - the second contains the amount to shift by AS INTS - - for i = 0 to 3 - shift = vSrcB_i*32:(i*32)+4 - vReturned_i*32:(i*32)+31 = vSrcA_i*32:(i*32)+31 << shift -*/ -FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4 &vSrcA, const i32x4 &vSrcB) -{ - i32x4 retval; - SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); - SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); - SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); - SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); - - - return retval; -} - - -// Fixed-point conversion and save as SIGNED INTS. -// pDest->x = Int (vSrc.x) -// note: some architectures have means of doing -// fixed point conversion when the fix depth is -// specified as an immediate.. but there is no way -// to guarantee an immediate as a parameter to function -// like this. -FORCEINLINE void ConvertStoreAsIntsSIMD(intx4 * RESTRICT pDest, const fltx4 &vSrc) -{ - __m64 bottom = _mm_cvttps_pi32( vSrc ); - __m64 top = _mm_cvttps_pi32( _mm_movehl_ps(vSrc,vSrc) ); - - *reinterpret_cast<__m64 *>(&(*pDest)[0]) = bottom; - *reinterpret_cast<__m64 *>(&(*pDest)[2]) = top; - - _mm_empty(); -} - - - -#endif - - - -/// class FourVectors stores 4 independent vectors for use in SIMD processing. These vectors are -/// stored in the format x x x x y y y y z z z z so that they can be efficiently SIMD-accelerated. -class ALIGN16 FourVectors -{ -public: - fltx4 x, y, z; - - FORCEINLINE void DuplicateVector(Vector const &v) //< set all 4 vectors to the same vector value - { - x=ReplicateX4(v.x); - y=ReplicateX4(v.y); - z=ReplicateX4(v.z); - } - - FORCEINLINE fltx4 const & operator[](int idx) const - { - return *((&x)+idx); - } - - FORCEINLINE fltx4 & operator[](int idx) - { - return *((&x)+idx); - } - - FORCEINLINE void operator+=(FourVectors const &b) //< add 4 vectors to another 4 vectors - { - x=AddSIMD(x,b.x); - y=AddSIMD(y,b.y); - z=AddSIMD(z,b.z); - } - - FORCEINLINE void operator-=(FourVectors const &b) //< subtract 4 vectors from another 4 - { - x=SubSIMD(x,b.x); - y=SubSIMD(y,b.y); - z=SubSIMD(z,b.z); - } - - FORCEINLINE void operator*=(FourVectors const &b) //< scale all four vectors per component scale - { - x=MulSIMD(x,b.x); - y=MulSIMD(y,b.y); - z=MulSIMD(z,b.z); - } - - FORCEINLINE void operator*=(const fltx4 & scale) //< scale - { - x=MulSIMD(x,scale); - y=MulSIMD(y,scale); - z=MulSIMD(z,scale); - } - - FORCEINLINE void operator*=(float scale) //< uniformly scale all 4 vectors - { - fltx4 scalepacked = ReplicateX4(scale); - *this *= scalepacked; - } - - FORCEINLINE fltx4 operator*(FourVectors const &b) const //< 4 dot products - { - fltx4 dot=MulSIMD(x,b.x); - dot=MaddSIMD(y,b.y,dot); - dot=MaddSIMD(z,b.z,dot); - return dot; - } - - FORCEINLINE fltx4 operator*(Vector const &b) const //< dot product all 4 vectors with 1 vector - { - fltx4 dot=MulSIMD(x,ReplicateX4(b.x)); - dot=MaddSIMD(y,ReplicateX4(b.y), dot); - dot=MaddSIMD(z,ReplicateX4(b.z), dot); - return dot; - } - - FORCEINLINE void VProduct(FourVectors const &b) //< component by component mul - { - x=MulSIMD(x,b.x); - y=MulSIMD(y,b.y); - z=MulSIMD(z,b.z); - } - FORCEINLINE void MakeReciprocal(void) //< (x,y,z)=(1/x,1/y,1/z) - { - x=ReciprocalSIMD(x); - y=ReciprocalSIMD(y); - z=ReciprocalSIMD(z); - } - - FORCEINLINE void MakeReciprocalSaturate(void) //< (x,y,z)=(1/x,1/y,1/z), 1/0=1.0e23 - { - x=ReciprocalSaturateSIMD(x); - y=ReciprocalSaturateSIMD(y); - z=ReciprocalSaturateSIMD(z); - } - - // Assume the given matrix is a rotation, and rotate these vectors by it. - // If you have a long list of FourVectors structures that you all want - // to rotate by the same matrix, use FourVectors::RotateManyBy() instead. - inline void RotateBy(const matrix3x4_t& matrix); - - /// You can use this to rotate a long array of FourVectors all by the same - /// matrix. The first parameter is the head of the array. The second is the - /// number of vectors to rotate. The third is the matrix. - static void RotateManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix ); - - /// Assume the vectors are points, and transform them in place by the matrix. - inline void TransformBy(const matrix3x4_t& matrix); - - /// You can use this to Transform a long array of FourVectors all by the same - /// matrix. The first parameter is the head of the array. The second is the - /// number of vectors to rotate. The third is the matrix. The fourth is the - /// output buffer, which must not overlap the pVectors buffer. This is not - /// an in-place transformation. - static void TransformManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors * RESTRICT pOut ); - - /// You can use this to Transform a long array of FourVectors all by the same - /// matrix. The first parameter is the head of the array. The second is the - /// number of vectors to rotate. The third is the matrix. The fourth is the - /// output buffer, which must not overlap the pVectors buffer. - /// This is an in-place transformation. - static void TransformManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix ); - - // X(),Y(),Z() - get at the desired component of the i'th (0..3) vector. - FORCEINLINE const float & X(int idx) const - { - // NOTE: if the output goes into a register, this causes a Load-Hit-Store stall (don't mix fpu/vpu math!) - return SubFloat( (fltx4 &)x, idx ); - } - - FORCEINLINE const float & Y(int idx) const - { - return SubFloat( (fltx4 &)y, idx ); - } - - FORCEINLINE const float & Z(int idx) const - { - return SubFloat( (fltx4 &)z, idx ); - } - - FORCEINLINE float & X(int idx) - { - return SubFloat( x, idx ); - } - - FORCEINLINE float & Y(int idx) - { - return SubFloat( y, idx ); - } - - FORCEINLINE float & Z(int idx) - { - return SubFloat( z, idx ); - } - - FORCEINLINE Vector Vec(int idx) const //< unpack one of the vectors - { - return Vector( X(idx), Y(idx), Z(idx) ); - } - - FourVectors(void) - { - } - - FourVectors( FourVectors const &src ) - { - x=src.x; - y=src.y; - z=src.z; - } - - FORCEINLINE void operator=( FourVectors const &src ) - { - x=src.x; - y=src.y; - z=src.z; - } - - /// LoadAndSwizzle - load 4 Vectors into a FourVectors, performing transpose op - FORCEINLINE void LoadAndSwizzle(Vector const &a, Vector const &b, Vector const &c, Vector const &d) - { - // TransposeSIMD has large sub-expressions that the compiler can't eliminate on x360 - // use an unfolded implementation here -#if _X360 - fltx4 tx = LoadUnalignedSIMD( &a.x ); - fltx4 ty = LoadUnalignedSIMD( &b.x ); - fltx4 tz = LoadUnalignedSIMD( &c.x ); - fltx4 tw = LoadUnalignedSIMD( &d.x ); - fltx4 r0 = __vmrghw(tx, tz); - fltx4 r1 = __vmrghw(ty, tw); - fltx4 r2 = __vmrglw(tx, tz); - fltx4 r3 = __vmrglw(ty, tw); - - x = __vmrghw(r0, r1); - y = __vmrglw(r0, r1); - z = __vmrghw(r2, r3); -#else - x = LoadUnalignedSIMD( &( a.x )); - y = LoadUnalignedSIMD( &( b.x )); - z = LoadUnalignedSIMD( &( c.x )); - fltx4 w = LoadUnalignedSIMD( &( d.x )); - // now, matrix is: - // x y z ? - // x y z ? - // x y z ? - // x y z ? - TransposeSIMD(x, y, z, w); -#endif - } - - /// LoadAndSwizzleAligned - load 4 Vectors into a FourVectors, performing transpose op. - /// all 4 vectors must be 128 bit boundary - FORCEINLINE void LoadAndSwizzleAligned(const float *RESTRICT a, const float *RESTRICT b, const float *RESTRICT c, const float *RESTRICT d) - { -#if _X360 - fltx4 tx = LoadAlignedSIMD(a); - fltx4 ty = LoadAlignedSIMD(b); - fltx4 tz = LoadAlignedSIMD(c); - fltx4 tw = LoadAlignedSIMD(d); - fltx4 r0 = __vmrghw(tx, tz); - fltx4 r1 = __vmrghw(ty, tw); - fltx4 r2 = __vmrglw(tx, tz); - fltx4 r3 = __vmrglw(ty, tw); - - x = __vmrghw(r0, r1); - y = __vmrglw(r0, r1); - z = __vmrghw(r2, r3); -#else - x = LoadAlignedSIMD( a ); - y = LoadAlignedSIMD( b ); - z = LoadAlignedSIMD( c ); - fltx4 w = LoadAlignedSIMD( d ); - // now, matrix is: - // x y z ? - // x y z ? - // x y z ? - // x y z ? - TransposeSIMD( x, y, z, w ); -#endif - } - - FORCEINLINE void LoadAndSwizzleAligned(Vector const &a, Vector const &b, Vector const &c, Vector const &d) - { - LoadAndSwizzleAligned( &a.x, &b.x, &c.x, &d.x ); - } - - /// return the squared length of all 4 vectors - FORCEINLINE fltx4 length2(void) const - { - return (*this)*(*this); - } - - /// return the approximate length of all 4 vectors. uses the sqrt approximation instruction - FORCEINLINE fltx4 length(void) const - { - return SqrtEstSIMD(length2()); - } - - /// normalize all 4 vectors in place. not mega-accurate (uses reciprocal approximation instruction) - FORCEINLINE void VectorNormalizeFast(void) - { - fltx4 mag_sq=(*this)*(*this); // length^2 - (*this) *= ReciprocalSqrtEstSIMD(mag_sq); // *(1.0/sqrt(length^2)) - } - - /// normalize all 4 vectors in place. - FORCEINLINE void VectorNormalize(void) - { - fltx4 mag_sq=(*this)*(*this); // length^2 - (*this) *= ReciprocalSqrtSIMD(mag_sq); // *(1.0/sqrt(length^2)) - } - - /// construct a FourVectors from 4 separate Vectors - FORCEINLINE FourVectors(Vector const &a, Vector const &b, Vector const &c, Vector const &d) - { - LoadAndSwizzle(a,b,c,d); - } - - /// construct a FourVectors from 4 separate Vectors - FORCEINLINE FourVectors(VectorAligned const &a, VectorAligned const &b, VectorAligned const &c, VectorAligned const &d) - { - LoadAndSwizzleAligned(a,b,c,d); - } - - FORCEINLINE fltx4 DistToSqr( FourVectors const &pnt ) - { - fltx4 fl4dX = SubSIMD( pnt.x, x ); - fltx4 fl4dY = SubSIMD( pnt.y, y ); - fltx4 fl4dZ = SubSIMD( pnt.z, z ); - return AddSIMD( MulSIMD( fl4dX, fl4dX), AddSIMD( MulSIMD( fl4dY, fl4dY ), MulSIMD( fl4dZ, fl4dZ ) ) ); - - } - - FORCEINLINE fltx4 TValueOfClosestPointOnLine( FourVectors const &p0, FourVectors const &p1 ) const - { - FourVectors lineDelta = p1; - lineDelta -= p0; - fltx4 OOlineDirDotlineDir = ReciprocalSIMD( p1 * p1 ); - FourVectors v4OurPnt = *this; - v4OurPnt -= p0; - return MulSIMD( OOlineDirDotlineDir, v4OurPnt * lineDelta ); - } - - FORCEINLINE fltx4 DistSqrToLineSegment( FourVectors const &p0, FourVectors const &p1 ) const - { - FourVectors lineDelta = p1; - FourVectors v4OurPnt = *this; - v4OurPnt -= p0; - lineDelta -= p0; - - fltx4 OOlineDirDotlineDir = ReciprocalSIMD( lineDelta * lineDelta ); - - fltx4 fl4T = MulSIMD( OOlineDirDotlineDir, v4OurPnt * lineDelta ); - - fl4T = MinSIMD( fl4T, Four_Ones ); - fl4T = MaxSIMD( fl4T, Four_Zeros ); - lineDelta *= fl4T; - return v4OurPnt.DistToSqr( lineDelta ); - } - -}; - -/// form 4 cross products -inline FourVectors operator ^(const FourVectors &a, const FourVectors &b) -{ - FourVectors ret; - ret.x=SubSIMD(MulSIMD(a.y,b.z),MulSIMD(a.z,b.y)); - ret.y=SubSIMD(MulSIMD(a.z,b.x),MulSIMD(a.x,b.z)); - ret.z=SubSIMD(MulSIMD(a.x,b.y),MulSIMD(a.y,b.x)); - return ret; -} - -/// component-by-componentwise MAX operator -inline FourVectors maximum(const FourVectors &a, const FourVectors &b) -{ - FourVectors ret; - ret.x=MaxSIMD(a.x,b.x); - ret.y=MaxSIMD(a.y,b.y); - ret.z=MaxSIMD(a.z,b.z); - return ret; -} - -/// component-by-componentwise MIN operator -inline FourVectors minimum(const FourVectors &a, const FourVectors &b) -{ - FourVectors ret; - ret.x=MinSIMD(a.x,b.x); - ret.y=MinSIMD(a.y,b.y); - ret.z=MinSIMD(a.z,b.z); - return ret; -} - -/// calculate reflection vector. incident and normal dir assumed normalized -FORCEINLINE FourVectors VectorReflect( const FourVectors &incident, const FourVectors &normal ) -{ - FourVectors ret = incident; - fltx4 iDotNx2 = incident * normal; - iDotNx2 = AddSIMD( iDotNx2, iDotNx2 ); - FourVectors nPart = normal; - nPart *= iDotNx2; - ret -= nPart; // i-2(n*i)n - return ret; -} - -/// calculate slide vector. removes all components of a vector which are perpendicular to a normal vector. -FORCEINLINE FourVectors VectorSlide( const FourVectors &incident, const FourVectors &normal ) -{ - FourVectors ret = incident; - fltx4 iDotN = incident * normal; - FourVectors nPart = normal; - nPart *= iDotN; - ret -= nPart; // i-(n*i)n - return ret; -} - - -// Assume the given matrix is a rotation, and rotate these vectors by it. -// If you have a long list of FourVectors structures that you all want -// to rotate by the same matrix, use FourVectors::RotateManyBy() instead. -void FourVectors::RotateBy(const matrix3x4_t& matrix) -{ - // Splat out each of the entries in the matrix to a fltx4. Do this - // in the order that we will need them, to hide latency. I'm - // avoiding making an array of them, so that they'll remain in - // registers. - fltx4 matSplat00, matSplat01, matSplat02, - matSplat10, matSplat11, matSplat12, - matSplat20, matSplat21, matSplat22; - - { - // Load the matrix into local vectors. Sadly, matrix3x4_ts are - // often unaligned. The w components will be the tranpose row of - // the matrix, but we don't really care about that. - fltx4 matCol0 = LoadUnalignedSIMD( matrix[0] ); - fltx4 matCol1 = LoadUnalignedSIMD( matrix[1] ); - fltx4 matCol2 = LoadUnalignedSIMD( matrix[2] ); - - matSplat00 = SplatXSIMD( matCol0 ); - matSplat01 = SplatYSIMD( matCol0 ); - matSplat02 = SplatZSIMD( matCol0 ); - - matSplat10 = SplatXSIMD( matCol1 ); - matSplat11 = SplatYSIMD( matCol1 ); - matSplat12 = SplatZSIMD( matCol1 ); - - matSplat20 = SplatXSIMD( matCol2 ); - matSplat21 = SplatYSIMD( matCol2 ); - matSplat22 = SplatZSIMD( matCol2 ); - } - - // Trust in the compiler to schedule these operations correctly: - fltx4 outX, outY, outZ; - outX = AddSIMD( AddSIMD( MulSIMD( x, matSplat00 ), MulSIMD( y, matSplat01 ) ), MulSIMD( z, matSplat02 ) ); - outY = AddSIMD( AddSIMD( MulSIMD( x, matSplat10 ), MulSIMD( y, matSplat11 ) ), MulSIMD( z, matSplat12 ) ); - outZ = AddSIMD( AddSIMD( MulSIMD( x, matSplat20 ), MulSIMD( y, matSplat21 ) ), MulSIMD( z, matSplat22 ) ); - - x = outX; - y = outY; - z = outZ; -} - -// Assume the given matrix is a rotation, and rotate these vectors by it. -// If you have a long list of FourVectors structures that you all want -// to rotate by the same matrix, use FourVectors::RotateManyBy() instead. -void FourVectors::TransformBy(const matrix3x4_t& matrix) -{ - // Splat out each of the entries in the matrix to a fltx4. Do this - // in the order that we will need them, to hide latency. I'm - // avoiding making an array of them, so that they'll remain in - // registers. - fltx4 matSplat00, matSplat01, matSplat02, - matSplat10, matSplat11, matSplat12, - matSplat20, matSplat21, matSplat22; - - { - // Load the matrix into local vectors. Sadly, matrix3x4_ts are - // often unaligned. The w components will be the tranpose row of - // the matrix, but we don't really care about that. - fltx4 matCol0 = LoadUnalignedSIMD( matrix[0] ); - fltx4 matCol1 = LoadUnalignedSIMD( matrix[1] ); - fltx4 matCol2 = LoadUnalignedSIMD( matrix[2] ); - - matSplat00 = SplatXSIMD( matCol0 ); - matSplat01 = SplatYSIMD( matCol0 ); - matSplat02 = SplatZSIMD( matCol0 ); - - matSplat10 = SplatXSIMD( matCol1 ); - matSplat11 = SplatYSIMD( matCol1 ); - matSplat12 = SplatZSIMD( matCol1 ); - - matSplat20 = SplatXSIMD( matCol2 ); - matSplat21 = SplatYSIMD( matCol2 ); - matSplat22 = SplatZSIMD( matCol2 ); - } - - // Trust in the compiler to schedule these operations correctly: - fltx4 outX, outY, outZ; - - outX = MaddSIMD( z, matSplat02, AddSIMD( MulSIMD( x, matSplat00 ), MulSIMD( y, matSplat01 ) ) ); - outY = MaddSIMD( z, matSplat12, AddSIMD( MulSIMD( x, matSplat10 ), MulSIMD( y, matSplat11 ) ) ); - outZ = MaddSIMD( z, matSplat22, AddSIMD( MulSIMD( x, matSplat20 ), MulSIMD( y, matSplat21 ) ) ); - - x = AddSIMD( outX, ReplicateX4( matrix[0][3] )); - y = AddSIMD( outY, ReplicateX4( matrix[1][3] )); - z = AddSIMD( outZ, ReplicateX4( matrix[2][3] )); -} - - - -/// quick, low quality perlin-style noise() function suitable for real time use. -/// return value is -1..1. Only reliable around +/- 1 million or so. -fltx4 NoiseSIMD( const fltx4 & x, const fltx4 & y, const fltx4 & z ); -fltx4 NoiseSIMD( FourVectors const &v ); - -// vector valued noise direction -FourVectors DNoiseSIMD( FourVectors const &v ); - -// vector value "curl" noise function. see http://hyperphysics.phy-astr.gsu.edu/hbase/curl.html -FourVectors CurlNoiseSIMD( FourVectors const &v ); - - -/// calculate the absolute value of a packed single -inline fltx4 fabs( const fltx4 & x ) -{ - return AndSIMD( x, LoadAlignedSIMD( g_SIMD_clear_signmask ) ); -} - -/// negate all four components of a SIMD packed single -inline fltx4 fnegate( const fltx4 & x ) -{ - return XorSIMD( x, LoadAlignedSIMD( g_SIMD_signmask ) ); -} - - -fltx4 Pow_FixedPoint_Exponent_SIMD( const fltx4 & x, int exponent); - -// PowSIMD - raise a SIMD register to a power. This is analogous to the C pow() function, with some -// restictions: fractional exponents are only handled with 2 bits of precision. Basically, -// fractions of 0,.25,.5, and .75 are handled. PowSIMD(x,.30) will be the same as PowSIMD(x,.25). -// negative and fractional powers are handled by the SIMD reciprocal and square root approximation -// instructions and so are not especially accurate ----Note that this routine does not raise -// numeric exceptions because it uses SIMD--- This routine is O(log2(exponent)). -inline fltx4 PowSIMD( const fltx4 & x, float exponent ) -{ - return Pow_FixedPoint_Exponent_SIMD(x,(int) (4.0*exponent)); -} - - - -// random number generation - generate 4 random numbers quickly. - -void SeedRandSIMD(uint32 seed); // seed the random # generator -fltx4 RandSIMD( int nContext = 0 ); // return 4 numbers in the 0..1 range - -// for multithreaded, you need to use these and use the argument form of RandSIMD: -int GetSIMDRandContext( void ); -void ReleaseSIMDRandContext( int nContext ); - -FORCEINLINE fltx4 RandSignedSIMD( void ) // -1..1 -{ - return SubSIMD( MulSIMD( Four_Twos, RandSIMD() ), Four_Ones ); -} - - -// SIMD versions of mathlib simplespline functions -// hermite basis function for smooth interpolation -// Similar to Gain() above, but very cheap to call -// value should be between 0 & 1 inclusive -inline fltx4 SimpleSpline( const fltx4 & value ) -{ - // Arranged to avoid a data dependency between these two MULs: - fltx4 valueDoubled = MulSIMD( value, Four_Twos ); - fltx4 valueSquared = MulSIMD( value, value ); - - // Nice little ease-in, ease-out spline-like curve - return SubSIMD( - MulSIMD( Four_Threes, valueSquared ), - MulSIMD( valueDoubled, valueSquared ) ); -} - -// remaps a value in [startInterval, startInterval+rangeInterval] from linear to -// spline using SimpleSpline -inline fltx4 SimpleSplineRemapValWithDeltas( const fltx4 & val, - const fltx4 & A, const fltx4 & BMinusA, - const fltx4 & OneOverBMinusA, const fltx4 & C, - const fltx4 & DMinusC ) -{ -// if ( A == B ) -// return val >= B ? D : C; - fltx4 cVal = MulSIMD( SubSIMD( val, A), OneOverBMinusA ); - return AddSIMD( C, MulSIMD( DMinusC, SimpleSpline( cVal ) ) ); -} - -inline fltx4 SimpleSplineRemapValWithDeltasClamped( const fltx4 & val, - const fltx4 & A, const fltx4 & BMinusA, - const fltx4 & OneOverBMinusA, const fltx4 & C, - const fltx4 & DMinusC ) -{ -// if ( A == B ) -// return val >= B ? D : C; - fltx4 cVal = MulSIMD( SubSIMD( val, A), OneOverBMinusA ); - cVal = MinSIMD( Four_Ones, MaxSIMD( Four_Zeros, cVal ) ); - return AddSIMD( C, MulSIMD( DMinusC, SimpleSpline( cVal ) ) ); -} - -FORCEINLINE fltx4 FracSIMD( const fltx4 &val ) -{ - fltx4 fl4Abs = fabs( val ); - fltx4 ival = SubSIMD( AddSIMD( fl4Abs, Four_2ToThe23s ), Four_2ToThe23s ); - ival = MaskedAssign( CmpGtSIMD( ival, fl4Abs ), SubSIMD( ival, Four_Ones ), ival ); - return XorSIMD( SubSIMD( fl4Abs, ival ), XorSIMD( val, fl4Abs ) ); // restore sign bits -} - -FORCEINLINE fltx4 Mod2SIMD( const fltx4 &val ) -{ - fltx4 fl4Abs = fabs( val ); - fltx4 ival = SubSIMD( AndSIMD( LoadAlignedSIMD( (float *) g_SIMD_lsbmask ), AddSIMD( fl4Abs, Four_2ToThe23s ) ), Four_2ToThe23s ); - ival = MaskedAssign( CmpGtSIMD( ival, fl4Abs ), SubSIMD( ival, Four_Twos ), ival ); - return XorSIMD( SubSIMD( fl4Abs, ival ), XorSIMD( val, fl4Abs ) ); // restore sign bits -} - -FORCEINLINE fltx4 Mod2SIMDPositiveInput( const fltx4 &val ) -{ - fltx4 ival = SubSIMD( AndSIMD( LoadAlignedSIMD( g_SIMD_lsbmask ), AddSIMD( val, Four_2ToThe23s ) ), Four_2ToThe23s ); - ival = MaskedAssign( CmpGtSIMD( ival, val ), SubSIMD( ival, Four_Twos ), ival ); - return SubSIMD( val, ival ); -} - - -// approximate sin of an angle, with -1..1 representing the whole sin wave period instead of -pi..pi. -// no range reduction is done - for values outside of 0..1 you won't like the results -FORCEINLINE fltx4 _SinEst01SIMD( const fltx4 &val ) -{ - // really rough approximation - x*(4-x*4) - a parabola. s(0) = 0, s(.5) = 1, s(1)=0, smooth in-between. - // sufficient for simple oscillation. - return MulSIMD( val, SubSIMD( Four_Fours, MulSIMD( val, Four_Fours ) ) ); -} - -FORCEINLINE fltx4 _Sin01SIMD( const fltx4 &val ) -{ - // not a bad approximation : parabola always over-estimates. Squared parabola always - // underestimates. So lets blend between them: goodsin = badsin + .225*( badsin^2-badsin) - fltx4 fl4BadEst = MulSIMD( val, SubSIMD( Four_Fours, MulSIMD( val, Four_Fours ) ) ); - return AddSIMD( MulSIMD( Four_Point225s, SubSIMD( MulSIMD( fl4BadEst, fl4BadEst ), fl4BadEst ) ), fl4BadEst ); -} - -// full range useable implementations -FORCEINLINE fltx4 SinEst01SIMD( const fltx4 &val ) -{ - fltx4 fl4Abs = fabs( val ); - fltx4 fl4Reduced2 = Mod2SIMDPositiveInput( fl4Abs ); - fltx4 fl4OddMask = CmpGeSIMD( fl4Reduced2, Four_Ones ); - fltx4 fl4val = SubSIMD( fl4Reduced2, AndSIMD( Four_Ones, fl4OddMask ) ); - fltx4 fl4Sin = _SinEst01SIMD( fl4val ); - fl4Sin = XorSIMD( fl4Sin, AndSIMD( LoadAlignedSIMD( g_SIMD_signmask ), XorSIMD( val, fl4OddMask ) ) ); - return fl4Sin; - -} - -FORCEINLINE fltx4 Sin01SIMD( const fltx4 &val ) -{ - fltx4 fl4Abs = fabs( val ); - fltx4 fl4Reduced2 = Mod2SIMDPositiveInput( fl4Abs ); - fltx4 fl4OddMask = CmpGeSIMD( fl4Reduced2, Four_Ones ); - fltx4 fl4val = SubSIMD( fl4Reduced2, AndSIMD( Four_Ones, fl4OddMask ) ); - fltx4 fl4Sin = _Sin01SIMD( fl4val ); - fl4Sin = XorSIMD( fl4Sin, AndSIMD( LoadAlignedSIMD( g_SIMD_signmask ), XorSIMD( val, fl4OddMask ) ) ); - return fl4Sin; - -} - -// Schlick style Bias approximation see graphics gems 4 : bias(t,a)= t/( (1/a-2)*(1-t)+1) - -FORCEINLINE fltx4 PreCalcBiasParameter( const fltx4 &bias_parameter ) -{ - // convert perlin-style-bias parameter to the value right for the approximation - return SubSIMD( ReciprocalSIMD( bias_parameter ), Four_Twos ); -} - -FORCEINLINE fltx4 BiasSIMD( const fltx4 &val, const fltx4 &precalc_param ) -{ - // similar to bias function except pass precalced bias value from calling PreCalcBiasParameter. - - //!!speed!! use reciprocal est? - //!!speed!! could save one op by precalcing _2_ values - return DivSIMD( val, AddSIMD( MulSIMD( precalc_param, SubSIMD( Four_Ones, val ) ), Four_Ones ) ); -} - -//----------------------------------------------------------------------------- -// Box/plane test -// NOTE: The w component of emins + emaxs must be 1 for this to work -//----------------------------------------------------------------------------- -FORCEINLINE int BoxOnPlaneSideSIMD( const fltx4& emins, const fltx4& emaxs, const cplane_t *p, float tolerance = 0.f ) -{ - fltx4 corners[2]; - fltx4 normal = LoadUnalignedSIMD( p->normal.Base() ); - fltx4 dist = ReplicateX4( -p->dist ); - normal = SetWSIMD( normal, dist ); - fltx4 t4 = ReplicateX4( tolerance ); - fltx4 negt4 = ReplicateX4( -tolerance ); - fltx4 cmp = CmpGeSIMD( normal, Four_Zeros ); - corners[0] = MaskedAssign( cmp, emaxs, emins ); - corners[1] = MaskedAssign( cmp, emins, emaxs ); - fltx4 dot1 = Dot4SIMD( normal, corners[0] ); - fltx4 dot2 = Dot4SIMD( normal, corners[1] ); - cmp = CmpGeSIMD( dot1, t4 ); - fltx4 cmp2 = CmpGtSIMD( negt4, dot2 ); - fltx4 result = MaskedAssign( cmp, Four_Ones, Four_Zeros ); - fltx4 result2 = MaskedAssign( cmp2, Four_Twos, Four_Zeros ); - result = AddSIMD( result, result2 ); - intx4 sides; - ConvertStoreAsIntsSIMD( &sides, result ); - return sides[0]; -} - -#endif // _ssemath_h diff --git a/Resources/NetHook/mathlib/ssequaternion.h b/Resources/NetHook/mathlib/ssequaternion.h deleted file mode 100644 index d38c3c09..00000000 --- a/Resources/NetHook/mathlib/ssequaternion.h +++ /dev/null @@ -1,367 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: - defines SIMD "structure of arrays" classes and functions. -// -//===========================================================================// -#ifndef SSEQUATMATH_H -#define SSEQUATMATH_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include "mathlib/ssemath.h" - -// Use this #define to allow SSE versions of Quaternion math -// to exist on PC. -// On PC, certain horizontal vector operations are not supported. -// This causes the SSE implementation of quaternion math to mix the -// vector and scalar floating point units, which is extremely -// performance negative if you don't compile to native SSE2 (which -// we don't as of Sept 1, 2007). So, it's best not to allow these -// functions to exist at all. It's not good enough to simply replace -// the contents of the functions with scalar math, because each call -// to LoadAligned and StoreAligned will result in an unnecssary copy -// of the quaternion, and several moves to and from the XMM registers. -// -// Basically, the problem you run into is that for efficient SIMD code, -// you need to load the quaternions and vectors into SIMD registers and -// keep them there as long as possible while doing only SIMD math, -// whereas for efficient scalar code, each time you copy onto or ever -// use a fltx4, it hoses your pipeline. So the difference has to be -// in the management of temporary variables in the calling function, -// not inside the math functions. -// -// If you compile assuming the presence of SSE2, the MSVC will abandon -// the traditional x87 FPU operations altogether and make everything use -// the SSE2 registers, which lessens this problem a little. - -// permitted only on 360, as we've done careful tuning on its Altivec math: -#ifdef _X360 -#define ALLOW_SIMD_QUATERNION_MATH 1 // not on PC! -#endif - - - -//--------------------------------------------------------------------- -// Load/store quaternions -//--------------------------------------------------------------------- -#ifndef _X360 -#if ALLOW_SIMD_QUATERNION_MATH -// Using STDC or SSE -FORCEINLINE fltx4 LoadAlignedSIMD( const QuaternionAligned & pSIMD ) -{ - fltx4 retval = LoadAlignedSIMD( pSIMD.Base() ); - return retval; -} - -FORCEINLINE fltx4 LoadAlignedSIMD( const QuaternionAligned * RESTRICT pSIMD ) -{ - fltx4 retval = LoadAlignedSIMD( pSIMD ); - return retval; -} - -FORCEINLINE void StoreAlignedSIMD( QuaternionAligned * RESTRICT pSIMD, const fltx4 & a ) -{ - StoreAlignedSIMD( pSIMD->Base(), a ); -} -#endif -#else - -// for the transitional class -- load a QuaternionAligned -FORCEINLINE fltx4 LoadAlignedSIMD( const QuaternionAligned & pSIMD ) -{ - fltx4 retval = XMLoadVector4A( pSIMD.Base() ); - return retval; -} - -FORCEINLINE fltx4 LoadAlignedSIMD( const QuaternionAligned * RESTRICT pSIMD ) -{ - fltx4 retval = XMLoadVector4A( pSIMD ); - return retval; -} - -FORCEINLINE void StoreAlignedSIMD( QuaternionAligned * RESTRICT pSIMD, const fltx4 & a ) -{ - XMStoreVector4A( pSIMD->Base(), a ); -} - -#endif - - -#if ALLOW_SIMD_QUATERNION_MATH -//--------------------------------------------------------------------- -// Make sure quaternions are within 180 degrees of one another, if not, reverse q -//--------------------------------------------------------------------- -FORCEINLINE fltx4 QuaternionAlignSIMD( const fltx4 &p, const fltx4 &q ) -{ - // decide if one of the quaternions is backwards - fltx4 a = SubSIMD( p, q ); - fltx4 b = AddSIMD( p, q ); - a = Dot4SIMD( a, a ); - b = Dot4SIMD( b, b ); - fltx4 cmp = CmpGtSIMD( a, b ); - fltx4 result = MaskedAssign( cmp, NegSIMD(q), q ); - return result; -} - -//--------------------------------------------------------------------- -// Normalize Quaternion -//--------------------------------------------------------------------- -#if USE_STDC_FOR_SIMD - -FORCEINLINE fltx4 QuaternionNormalizeSIMD( const fltx4 &q ) -{ - fltx4 radius, result; - radius = Dot4SIMD( q, q ); - - if ( SubFloat( radius, 0 ) ) // > FLT_EPSILON && ((radius < 1.0f - 4*FLT_EPSILON) || (radius > 1.0f + 4*FLT_EPSILON)) - { - float iradius = 1.0f / sqrt( SubFloat( radius, 0 ) ); - result = ReplicateX4( iradius ); - result = MulSIMD( result, q ); - return result; - } - return q; -} - -#else - -// SSE + X360 implementation -FORCEINLINE fltx4 QuaternionNormalizeSIMD( const fltx4 &q ) -{ - fltx4 radius, result, mask; - radius = Dot4SIMD( q, q ); - mask = CmpEqSIMD( radius, Four_Zeros ); // all ones iff radius = 0 - result = ReciprocalSqrtSIMD( radius ); - result = MulSIMD( result, q ); - return MaskedAssign( mask, q, result ); // if radius was 0, just return q -} - -#endif - - -//--------------------------------------------------------------------- -// 0.0 returns p, 1.0 return q. -//--------------------------------------------------------------------- -FORCEINLINE fltx4 QuaternionBlendNoAlignSIMD( const fltx4 &p, const fltx4 &q, float t ) -{ - fltx4 sclp, sclq, result; - sclq = ReplicateX4( t ); - sclp = SubSIMD( Four_Ones, sclq ); - result = MulSIMD( sclp, p ); - result = MaddSIMD( sclq, q, result ); - return QuaternionNormalizeSIMD( result ); -} - - -//--------------------------------------------------------------------- -// Blend Quaternions -//--------------------------------------------------------------------- -FORCEINLINE fltx4 QuaternionBlendSIMD( const fltx4 &p, const fltx4 &q, float t ) -{ - // decide if one of the quaternions is backwards - fltx4 q2, result; - q2 = QuaternionAlignSIMD( p, q ); - result = QuaternionBlendNoAlignSIMD( p, q2, t ); - return result; -} - - -//--------------------------------------------------------------------- -// Multiply Quaternions -//--------------------------------------------------------------------- -#ifndef _X360 - -// SSE and STDC -FORCEINLINE fltx4 QuaternionMultSIMD( const fltx4 &p, const fltx4 &q ) -{ - // decide if one of the quaternions is backwards - fltx4 q2, result; - q2 = QuaternionAlignSIMD( p, q ); - SubFloat( result, 0 ) = SubFloat( p, 0 ) * SubFloat( q2, 3 ) + SubFloat( p, 1 ) * SubFloat( q2, 2 ) - SubFloat( p, 2 ) * SubFloat( q2, 1 ) + SubFloat( p, 3 ) * SubFloat( q2, 0 ); - SubFloat( result, 1 ) = -SubFloat( p, 0 ) * SubFloat( q2, 2 ) + SubFloat( p, 1 ) * SubFloat( q2, 3 ) + SubFloat( p, 2 ) * SubFloat( q2, 0 ) + SubFloat( p, 3 ) * SubFloat( q2, 1 ); - SubFloat( result, 2 ) = SubFloat( p, 0 ) * SubFloat( q2, 1 ) - SubFloat( p, 1 ) * SubFloat( q2, 0 ) + SubFloat( p, 2 ) * SubFloat( q2, 3 ) + SubFloat( p, 3 ) * SubFloat( q2, 2 ); - SubFloat( result, 3 ) = -SubFloat( p, 0 ) * SubFloat( q2, 0 ) - SubFloat( p, 1 ) * SubFloat( q2, 1 ) - SubFloat( p, 2 ) * SubFloat( q2, 2 ) + SubFloat( p, 3 ) * SubFloat( q2, 3 ); - return result; -} - -#else - -// X360 -extern const fltx4 g_QuatMultRowSign[4]; -FORCEINLINE fltx4 QuaternionMultSIMD( const fltx4 &p, const fltx4 &q ) -{ - fltx4 q2, row, result; - q2 = QuaternionAlignSIMD( p, q ); - - row = XMVectorSwizzle( q2, 3, 2, 1, 0 ); - row = MulSIMD( row, g_QuatMultRowSign[0] ); - result = Dot4SIMD( row, p ); - - row = XMVectorSwizzle( q2, 2, 3, 0, 1 ); - row = MulSIMD( row, g_QuatMultRowSign[1] ); - row = Dot4SIMD( row, p ); - result = __vrlimi( result, row, 4, 0 ); - - row = XMVectorSwizzle( q2, 1, 0, 3, 2 ); - row = MulSIMD( row, g_QuatMultRowSign[2] ); - row = Dot4SIMD( row, p ); - result = __vrlimi( result, row, 2, 0 ); - - row = MulSIMD( q2, g_QuatMultRowSign[3] ); - row = Dot4SIMD( row, p ); - result = __vrlimi( result, row, 1, 0 ); - return result; -} - -#endif - - -//--------------------------------------------------------------------- -// Quaternion scale -//--------------------------------------------------------------------- -#ifndef _X360 - -// SSE and STDC -FORCEINLINE fltx4 QuaternionScaleSIMD( const fltx4 &p, float t ) -{ - float r; - fltx4 q; - - // FIXME: nick, this isn't overly sensitive to accuracy, and it may be faster to - // use the cos part (w) of the quaternion (sin(omega)*N,cos(omega)) to figure the new scale. - float sinom = sqrt( SubFloat( p, 0 ) * SubFloat( p, 0 ) + SubFloat( p, 1 ) * SubFloat( p, 1 ) + SubFloat( p, 2 ) * SubFloat( p, 2 ) ); - sinom = min( sinom, 1.f ); - - float sinsom = sin( asin( sinom ) * t ); - - t = sinsom / (sinom + FLT_EPSILON); - SubFloat( q, 0 ) = t * SubFloat( p, 0 ); - SubFloat( q, 1 ) = t * SubFloat( p, 1 ); - SubFloat( q, 2 ) = t * SubFloat( p, 2 ); - - // rescale rotation - r = 1.0f - sinsom * sinsom; - - // Assert( r >= 0 ); - if (r < 0.0f) - r = 0.0f; - r = sqrt( r ); - - // keep sign of rotation - SubFloat( q, 3 ) = fsel( SubFloat( p, 3 ), r, -r ); - return q; -} - -#else - -// X360 -FORCEINLINE fltx4 QuaternionScaleSIMD( const fltx4 &p, float t ) -{ - fltx4 sinom = Dot3SIMD( p, p ); - sinom = SqrtSIMD( sinom ); - sinom = MinSIMD( sinom, Four_Ones ); - fltx4 sinsom = ArcSinSIMD( sinom ); - fltx4 t4 = ReplicateX4( t ); - sinsom = MulSIMD( sinsom, t4 ); - sinsom = SinSIMD( sinsom ); - sinom = AddSIMD( sinom, Four_Epsilons ); - sinom = ReciprocalSIMD( sinom ); - t4 = MulSIMD( sinsom, sinom ); - fltx4 result = MulSIMD( p, t4 ); - - // rescale rotation - sinsom = MulSIMD( sinsom, sinsom ); - fltx4 r = SubSIMD( Four_Ones, sinsom ); - r = MaxSIMD( r, Four_Zeros ); - r = SqrtSIMD( r ); - - // keep sign of rotation - fltx4 cmp = CmpGeSIMD( p, Four_Zeros ); - r = MaskedAssign( cmp, r, NegSIMD( r ) ); - - result = __vrlimi(result, r, 1, 0); - return result; -} - -#endif - - -//----------------------------------------------------------------------------- -// Quaternion sphereical linear interpolation -//----------------------------------------------------------------------------- -#ifndef _X360 - -// SSE and STDC -FORCEINLINE fltx4 QuaternionSlerpNoAlignSIMD( const fltx4 &p, const fltx4 &q, float t ) -{ - float omega, cosom, sinom, sclp, sclq; - - fltx4 result; - - // 0.0 returns p, 1.0 return q. - cosom = SubFloat( p, 0 ) * SubFloat( q, 0 ) + SubFloat( p, 1 ) * SubFloat( q, 1 ) + - SubFloat( p, 2 ) * SubFloat( q, 2 ) + SubFloat( p, 3 ) * SubFloat( q, 3 ); - - if ( (1.0f + cosom ) > 0.000001f ) - { - if ( (1.0f - cosom ) > 0.000001f ) - { - omega = acos( cosom ); - sinom = sin( omega ); - sclp = sin( (1.0f - t)*omega) / sinom; - sclq = sin( t*omega ) / sinom; - } - else - { - // TODO: add short circuit for cosom == 1.0f? - sclp = 1.0f - t; - sclq = t; - } - SubFloat( result, 0 ) = sclp * SubFloat( p, 0 ) + sclq * SubFloat( q, 0 ); - SubFloat( result, 1 ) = sclp * SubFloat( p, 1 ) + sclq * SubFloat( q, 1 ); - SubFloat( result, 2 ) = sclp * SubFloat( p, 2 ) + sclq * SubFloat( q, 2 ); - SubFloat( result, 3 ) = sclp * SubFloat( p, 3 ) + sclq * SubFloat( q, 3 ); - } - else - { - SubFloat( result, 0 ) = -SubFloat( q, 1 ); - SubFloat( result, 1 ) = SubFloat( q, 0 ); - SubFloat( result, 2 ) = -SubFloat( q, 3 ); - SubFloat( result, 3 ) = SubFloat( q, 2 ); - sclp = sin( (1.0f - t) * (0.5f * M_PI)); - sclq = sin( t * (0.5f * M_PI)); - SubFloat( result, 0 ) = sclp * SubFloat( p, 0 ) + sclq * SubFloat( result, 0 ); - SubFloat( result, 1 ) = sclp * SubFloat( p, 1 ) + sclq * SubFloat( result, 1 ); - SubFloat( result, 2 ) = sclp * SubFloat( p, 2 ) + sclq * SubFloat( result, 2 ); - } - - return result; -} - -#else - -// X360 -FORCEINLINE fltx4 QuaternionSlerpNoAlignSIMD( const fltx4 &p, const fltx4 &q, float t ) -{ - return XMQuaternionSlerp( p, q, t ); -} - -#endif - - -FORCEINLINE fltx4 QuaternionSlerpSIMD( const fltx4 &p, const fltx4 &q, float t ) -{ - fltx4 q2, result; - q2 = QuaternionAlignSIMD( p, q ); - result = QuaternionSlerpNoAlignSIMD( p, q2, t ); - return result; -} - - -#endif // ALLOW_SIMD_QUATERNION_MATH - -#endif // SSEQUATMATH_H - diff --git a/Resources/NetHook/mathlib/vector.h b/Resources/NetHook/mathlib/vector.h deleted file mode 100644 index 01d079e6..00000000 --- a/Resources/NetHook/mathlib/vector.h +++ /dev/null @@ -1,2226 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef VECTOR_H -#define VECTOR_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include - -// For vec_t, put this somewhere else? -#include "tier0/basetypes.h" - -// For rand(). We really need a library! -#include - -#ifndef _X360 -// For MMX intrinsics -#include -#endif - -#include "tier0/dbg.h" -#include "tier0/threadtools.h" -#include "mathlib/vector2d.h" -#include "mathlib/math_pfns.h" -#include "minmax.h" - -// Uncomment this to add extra Asserts to check for NANs, uninitialized vecs, etc. -//#define VECTOR_PARANOIA 1 - -// Uncomment this to make sure we don't do anything slow with our vectors -//#define VECTOR_NO_SLOW_OPERATIONS 1 - - -// Used to make certain code easier to read. -#define X_INDEX 0 -#define Y_INDEX 1 -#define Z_INDEX 2 - - -#ifdef VECTOR_PARANOIA -#define CHECK_VALID( _v) Assert( (_v).IsValid() ) -#else -#define CHECK_VALID( _v) 0 -#endif - -#define VecToString(v) (static_cast(CFmtStr("(%f, %f, %f)", (v).x, (v).y, (v).z))) // ** Note: this generates a temporary, don't hold reference! - -class VectorByValue; - -//========================================================= -// 3D Vector -//========================================================= -class Vector -{ -public: - // Members - vec_t x, y, z; - - // Construction/destruction: - Vector(void); - Vector(vec_t X, vec_t Y, vec_t Z); - Vector(vec_t XYZ); // TODO (Ilya): is this potentially a bad idea? - - // Initialization - void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f); - // TODO (Ilya): Should there be an init that takes a single float for consistency? - - // Got any nasty NAN's? - bool IsValid() const; - void Invalidate(); - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - // Base address... - vec_t* Base(); - vec_t const* Base() const; - - // Cast to Vector2D... - Vector2D& AsVector2D(); - const Vector2D& AsVector2D() const; - - // Initialization methods - void Random( vec_t minVal, vec_t maxVal ); - inline void Zero(); ///< zero out a vector - - // equality - bool operator==(const Vector& v) const; - bool operator!=(const Vector& v) const; - - // arithmetic operations - FORCEINLINE Vector& operator+=(const Vector &v); - FORCEINLINE Vector& operator-=(const Vector &v); - FORCEINLINE Vector& operator*=(const Vector &v); - FORCEINLINE Vector& operator*=(float s); - FORCEINLINE Vector& operator/=(const Vector &v); - FORCEINLINE Vector& operator/=(float s); - FORCEINLINE Vector& operator+=(float fl) ; ///< broadcast add - FORCEINLINE Vector& operator-=(float fl) ; ///< broadcast sub - -// negate the vector components - void Negate(); - - // Get the vector's magnitude. - inline vec_t Length() const; - - // Get the vector's magnitude squared. - FORCEINLINE vec_t LengthSqr(void) const - { - CHECK_VALID(*this); - return (x*x + y*y + z*z); - } - - // return true if this vector is (0,0,0) within tolerance - bool IsZero( float tolerance = 0.01f ) const - { - return (x > -tolerance && x < tolerance && - y > -tolerance && y < tolerance && - z > -tolerance && z < tolerance); - } - - vec_t NormalizeInPlace(); - bool IsLengthGreaterThan( float val ) const; - bool IsLengthLessThan( float val ) const; - - // check if a vector is within the box defined by two other vectors - FORCEINLINE bool WithinAABox( Vector const &boxmin, Vector const &boxmax); - - // Get the distance from this vector to the other one. - vec_t DistTo(const Vector &vOther) const; - - // Get the distance from this vector to the other one squared. - // NJS: note, VC wasn't inlining it correctly in several deeply nested inlines due to being an 'out of line' inline. - // may be able to tidy this up after switching to VC7 - FORCEINLINE vec_t DistToSqr(const Vector &vOther) const - { - Vector delta; - - delta.x = x - vOther.x; - delta.y = y - vOther.y; - delta.z = z - vOther.z; - - return delta.LengthSqr(); - } - - // Copy - void CopyToArray(float* rgfl) const; - - // Multiply, add, and assign to this (ie: *this = a + b * scalar). This - // is about 12% faster than the actual vector equation (because it's done per-component - // rather than per-vector). - void MulAdd(const Vector& a, const Vector& b, float scalar); - - // Dot product. - vec_t Dot(const Vector& vOther) const; - - // assignment - Vector& operator=(const Vector &vOther); - - // 2d - vec_t Length2D(void) const; - vec_t Length2DSqr(void) const; - - operator VectorByValue &() { return *((VectorByValue *)(this)); } - operator const VectorByValue &() const { return *((const VectorByValue *)(this)); } - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // copy constructors -// Vector(const Vector &vOther); - - // arithmetic operations - Vector operator-(void) const; - - Vector operator+(const Vector& v) const; - Vector operator-(const Vector& v) const; - Vector operator*(const Vector& v) const; - Vector operator/(const Vector& v) const; - Vector operator*(float fl) const; - Vector operator/(float fl) const; - - // Cross product between two vectors. - Vector Cross(const Vector &vOther) const; - - // Returns a vector with the min or max in X, Y, and Z. - Vector Min(const Vector &vOther) const; - Vector Max(const Vector &vOther) const; - -#else - -private: - // No copy constructors allowed if we're in optimal mode - Vector(const Vector& vOther); -#endif -}; - - - -#define USE_M64S ( ( !defined( _X360 ) ) && ( ! defined( _LINUX) ) ) - - - -//========================================================= -// 4D Short Vector (aligned on 8-byte boundary) -//========================================================= -class ALIGN8 ShortVector -{ -public: - - short x, y, z, w; - - // Initialization - void Init(short ix = 0, short iy = 0, short iz = 0, short iw = 0 ); - - -#if USE_M64S - __m64 &AsM64() { return *(__m64*)&x; } - const __m64 &AsM64() const { return *(const __m64*)&x; } -#endif - - // Setter - void Set( const ShortVector& vOther ); - void Set( const short ix, const short iy, const short iz, const short iw ); - - // array access... - short operator[](int i) const; - short& operator[](int i); - - // Base address... - short* Base(); - short const* Base() const; - - // equality - bool operator==(const ShortVector& v) const; - bool operator!=(const ShortVector& v) const; - - // Arithmetic operations - FORCEINLINE ShortVector& operator+=(const ShortVector &v); - FORCEINLINE ShortVector& operator-=(const ShortVector &v); - FORCEINLINE ShortVector& operator*=(const ShortVector &v); - FORCEINLINE ShortVector& operator*=(float s); - FORCEINLINE ShortVector& operator/=(const ShortVector &v); - FORCEINLINE ShortVector& operator/=(float s); - FORCEINLINE ShortVector operator*(float fl) const; - -private: - - // No copy constructors allowed if we're in optimal mode -// ShortVector(ShortVector const& vOther); - - // No assignment operators either... -// ShortVector& operator=( ShortVector const& src ); - -}; - - - - - - -//========================================================= -// 4D Integer Vector -//========================================================= -class IntVector4D -{ -public: - - int x, y, z, w; - - // Initialization - void Init(int ix = 0, int iy = 0, int iz = 0, int iw = 0 ); - -#if USE_M64S - __m64 &AsM64() { return *(__m64*)&x; } - const __m64 &AsM64() const { return *(const __m64*)&x; } -#endif - - // Setter - void Set( const IntVector4D& vOther ); - void Set( const int ix, const int iy, const int iz, const int iw ); - - // array access... - int operator[](int i) const; - int& operator[](int i); - - // Base address... - int* Base(); - int const* Base() const; - - // equality - bool operator==(const IntVector4D& v) const; - bool operator!=(const IntVector4D& v) const; - - // Arithmetic operations - FORCEINLINE IntVector4D& operator+=(const IntVector4D &v); - FORCEINLINE IntVector4D& operator-=(const IntVector4D &v); - FORCEINLINE IntVector4D& operator*=(const IntVector4D &v); - FORCEINLINE IntVector4D& operator*=(float s); - FORCEINLINE IntVector4D& operator/=(const IntVector4D &v); - FORCEINLINE IntVector4D& operator/=(float s); - FORCEINLINE IntVector4D operator*(float fl) const; - -private: - - // No copy constructors allowed if we're in optimal mode - // IntVector4D(IntVector4D const& vOther); - - // No assignment operators either... - // IntVector4D& operator=( IntVector4D const& src ); - -}; - - - -//----------------------------------------------------------------------------- -// Allows us to specifically pass the vector by value when we need to -//----------------------------------------------------------------------------- -class VectorByValue : public Vector -{ -public: - // Construction/destruction: - VectorByValue(void) : Vector() {} - VectorByValue(vec_t X, vec_t Y, vec_t Z) : Vector( X, Y, Z ) {} - VectorByValue(const VectorByValue& vOther) { *this = vOther; } -}; - - -//----------------------------------------------------------------------------- -// Utility to simplify table construction. No constructor means can use -// traditional C-style initialization -//----------------------------------------------------------------------------- -class TableVector -{ -public: - vec_t x, y, z; - - operator Vector &() { return *((Vector *)(this)); } - operator const Vector &() const { return *((const Vector *)(this)); } - - // array access... - inline vec_t& operator[](int i) - { - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; - } - - inline vec_t operator[](int i) const - { - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; - } -}; - - -//----------------------------------------------------------------------------- -// Here's where we add all those lovely SSE optimized routines -//----------------------------------------------------------------------------- - -class ALIGN16 VectorAligned : public Vector -{ -public: - inline VectorAligned(void) {}; - inline VectorAligned(vec_t X, vec_t Y, vec_t Z) - { - Init(X,Y,Z); - } - -#ifdef VECTOR_NO_SLOW_OPERATIONS - -private: - // No copy constructors allowed if we're in optimal mode - VectorAligned(const VectorAligned& vOther); - VectorAligned(const Vector &vOther); - -#else -public: - explicit VectorAligned(const Vector &vOther) - { - Init(vOther.x, vOther.y, vOther.z); - } - - VectorAligned& operator=(const Vector &vOther) - { - Init(vOther.x, vOther.y, vOther.z); - return *this; - } - -#endif - float w; // this space is used anyway -}; - -//----------------------------------------------------------------------------- -// Vector related operations -//----------------------------------------------------------------------------- - -// Vector clear -FORCEINLINE void VectorClear( Vector& a ); - -// Copy -FORCEINLINE void VectorCopy( const Vector& src, Vector& dst ); - -// Vector arithmetic -FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& result ); -FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& result ); -FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& result ); -FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& result ); -FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& result ); -FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& result ); -inline void VectorScale ( const Vector& in, vec_t scale, Vector& result ); -inline void VectorMA( const Vector& start, float scale, const Vector& direction, Vector& dest ); - -// Vector equality with tolerance -bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance = 0.0f ); - -#define VectorExpand(v) (v).x, (v).y, (v).z - - -// Normalization -// FIXME: Can't use quite yet -//vec_t VectorNormalize( Vector& v ); - -// Length -inline vec_t VectorLength( const Vector& v ); - -// Dot Product -FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b); - -// Cross product -void CrossProduct(const Vector& a, const Vector& b, Vector& result ); - -// Store the min or max of each of x, y, and z into the result. -void VectorMin( const Vector &a, const Vector &b, Vector &result ); -void VectorMax( const Vector &a, const Vector &b, Vector &result ); - -// Linearly interpolate between two vectors -void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest ); - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -// Cross product -Vector CrossProduct( const Vector& a, const Vector& b ); - -// Random vector creation -Vector RandomVector( vec_t minVal, vec_t maxVal ); - -#endif - -//----------------------------------------------------------------------------- -// -// Inlined Vector methods -// -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// constructors -//----------------------------------------------------------------------------- -inline Vector::Vector(void) -{ -#ifdef _DEBUG -#ifdef VECTOR_PARANOIA - // Initialize to NAN to catch errors - x = y = z = VEC_T_NAN; -#endif -#endif -} - -inline Vector::Vector(vec_t X, vec_t Y, vec_t Z) -{ - x = X; y = Y; z = Z; - CHECK_VALID(*this); -} - -inline Vector::Vector(vec_t XYZ) -{ - x = y = z = XYZ; - CHECK_VALID(*this); -} - -//inline Vector::Vector(const float *pFloat) -//{ -// Assert( pFloat ); -// x = pFloat[0]; y = pFloat[1]; z = pFloat[2]; -// CHECK_VALID(*this); -//} - -#if 0 -//----------------------------------------------------------------------------- -// copy constructor -//----------------------------------------------------------------------------- - -inline Vector::Vector(const Vector &vOther) -{ - CHECK_VALID(vOther); - x = vOther.x; y = vOther.y; z = vOther.z; -} -#endif - -//----------------------------------------------------------------------------- -// initialization -//----------------------------------------------------------------------------- - -inline void Vector::Init( vec_t ix, vec_t iy, vec_t iz ) -{ - x = ix; y = iy; z = iz; - CHECK_VALID(*this); -} - -inline void Vector::Random( vec_t minVal, vec_t maxVal ) -{ - x = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - y = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - z = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - CHECK_VALID(*this); -} - -// This should really be a single opcode on the PowerPC (move r0 onto the vec reg) -inline void Vector::Zero() -{ - x = y = z = 0.0f; -} - -inline void VectorClear( Vector& a ) -{ - a.x = a.y = a.z = 0.0f; -} - -//----------------------------------------------------------------------------- -// assignment -//----------------------------------------------------------------------------- - -inline Vector& Vector::operator=(const Vector &vOther) -{ - CHECK_VALID(vOther); - x=vOther.x; y=vOther.y; z=vOther.z; - return *this; -} - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline vec_t& Vector::operator[](int i) -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - -inline vec_t Vector::operator[](int i) const -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- -inline vec_t* Vector::Base() -{ - return (vec_t*)this; -} - -inline vec_t const* Vector::Base() const -{ - return (vec_t const*)this; -} - -//----------------------------------------------------------------------------- -// Cast to Vector2D... -//----------------------------------------------------------------------------- - -inline Vector2D& Vector::AsVector2D() -{ - return *(Vector2D*)this; -} - -inline const Vector2D& Vector::AsVector2D() const -{ - return *(const Vector2D*)this; -} - -//----------------------------------------------------------------------------- -// IsValid? -//----------------------------------------------------------------------------- - -inline bool Vector::IsValid() const -{ - return IsFinite(x) && IsFinite(y) && IsFinite(z); -} - -//----------------------------------------------------------------------------- -// Invalidate -//----------------------------------------------------------------------------- - -inline void Vector::Invalidate() -{ -//#ifdef _DEBUG -//#ifdef VECTOR_PARANOIA - x = y = z = VEC_T_NAN; -//#endif -//#endif -} - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- - -inline bool Vector::operator==( const Vector& src ) const -{ - CHECK_VALID(src); - CHECK_VALID(*this); - return (src.x == x) && (src.y == y) && (src.z == z); -} - -inline bool Vector::operator!=( const Vector& src ) const -{ - CHECK_VALID(src); - CHECK_VALID(*this); - return (src.x != x) || (src.y != y) || (src.z != z); -} - - -//----------------------------------------------------------------------------- -// Copy -//----------------------------------------------------------------------------- - -FORCEINLINE void VectorCopy( const Vector& src, Vector& dst ) -{ - CHECK_VALID(src); - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; -} - -inline void Vector::CopyToArray(float* rgfl) const -{ - Assert( rgfl ); - CHECK_VALID(*this); - rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; -} - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- -// #pragma message("TODO: these should be SSE") - -inline void Vector::Negate() -{ - CHECK_VALID(*this); - x = -x; y = -y; z = -z; -} - -FORCEINLINE Vector& Vector::operator+=(const Vector& v) -{ - CHECK_VALID(*this); - CHECK_VALID(v); - x+=v.x; y+=v.y; z += v.z; - return *this; -} - -FORCEINLINE Vector& Vector::operator-=(const Vector& v) -{ - CHECK_VALID(*this); - CHECK_VALID(v); - x-=v.x; y-=v.y; z -= v.z; - return *this; -} - -FORCEINLINE Vector& Vector::operator*=(float fl) -{ - x *= fl; - y *= fl; - z *= fl; - CHECK_VALID(*this); - return *this; -} - -FORCEINLINE Vector& Vector::operator*=(const Vector& v) -{ - CHECK_VALID(v); - x *= v.x; - y *= v.y; - z *= v.z; - CHECK_VALID(*this); - return *this; -} - -// this ought to be an opcode. -FORCEINLINE Vector& Vector::operator+=(float fl) -{ - x += fl; - y += fl; - z += fl; - CHECK_VALID(*this); - return *this; -} - -FORCEINLINE Vector& Vector::operator-=(float fl) -{ - x -= fl; - y -= fl; - z -= fl; - CHECK_VALID(*this); - return *this; -} - - - -FORCEINLINE Vector& Vector::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - z *= oofl; - CHECK_VALID(*this); - return *this; -} - -FORCEINLINE Vector& Vector::operator/=(const Vector& v) -{ - CHECK_VALID(v); - Assert( v.x != 0.0f && v.y != 0.0f && v.z != 0.0f ); - x /= v.x; - y /= v.y; - z /= v.z; - CHECK_VALID(*this); - return *this; -} - - - -//----------------------------------------------------------------------------- -// -// Inlined Short Vector methods -// -//----------------------------------------------------------------------------- - - -inline void ShortVector::Init( short ix, short iy, short iz, short iw ) -{ - x = ix; y = iy; z = iz; w = iw; -} - -FORCEINLINE void ShortVector::Set( const ShortVector& vOther ) -{ - x = vOther.x; - y = vOther.y; - z = vOther.z; - w = vOther.w; -} - -FORCEINLINE void ShortVector::Set( const short ix, const short iy, const short iz, const short iw ) -{ - x = ix; - y = iy; - z = iz; - w = iw; -} - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline short ShortVector::operator[](int i) const -{ - Assert( (i >= 0) && (i < 4) ); - return ((short*)this)[i]; -} - -inline short& ShortVector::operator[](int i) -{ - Assert( (i >= 0) && (i < 4) ); - return ((short*)this)[i]; -} - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- -inline short* ShortVector::Base() -{ - return (short*)this; -} - -inline short const* ShortVector::Base() const -{ - return (short const*)this; -} - - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- - -inline bool ShortVector::operator==( const ShortVector& src ) const -{ - return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w); -} - -inline bool ShortVector::operator!=( const ShortVector& src ) const -{ - return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w); -} - - - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- - -FORCEINLINE ShortVector& ShortVector::operator+=(const ShortVector& v) -{ - x+=v.x; y+=v.y; z += v.z; w += v.w; - return *this; -} - -FORCEINLINE ShortVector& ShortVector::operator-=(const ShortVector& v) -{ - x-=v.x; y-=v.y; z -= v.z; w -= v.w; - return *this; -} - -FORCEINLINE ShortVector& ShortVector::operator*=(float fl) -{ - x *= fl; - y *= fl; - z *= fl; - w *= fl; - return *this; -} - -FORCEINLINE ShortVector& ShortVector::operator*=(const ShortVector& v) -{ - x *= v.x; - y *= v.y; - z *= v.z; - w *= v.w; - return *this; -} - -FORCEINLINE ShortVector& ShortVector::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - z *= oofl; - w *= oofl; - return *this; -} - -FORCEINLINE ShortVector& ShortVector::operator/=(const ShortVector& v) -{ - Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 ); - x /= v.x; - y /= v.y; - z /= v.z; - w /= v.w; - return *this; -} - -FORCEINLINE void ShortVectorMultiply( const ShortVector& src, float fl, ShortVector& res ) -{ - Assert( IsFinite(fl) ); - res.x = src.x * fl; - res.y = src.y * fl; - res.z = src.z * fl; - res.w = src.w * fl; -} - -FORCEINLINE ShortVector ShortVector::operator*(float fl) const -{ - ShortVector res; - ShortVectorMultiply( *this, fl, res ); - return res; -} - - - - - - -//----------------------------------------------------------------------------- -// -// Inlined Integer Vector methods -// -//----------------------------------------------------------------------------- - - -inline void IntVector4D::Init( int ix, int iy, int iz, int iw ) -{ - x = ix; y = iy; z = iz; w = iw; -} - -FORCEINLINE void IntVector4D::Set( const IntVector4D& vOther ) -{ - x = vOther.x; - y = vOther.y; - z = vOther.z; - w = vOther.w; -} - -FORCEINLINE void IntVector4D::Set( const int ix, const int iy, const int iz, const int iw ) -{ - x = ix; - y = iy; - z = iz; - w = iw; -} - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline int IntVector4D::operator[](int i) const -{ - Assert( (i >= 0) && (i < 4) ); - return ((int*)this)[i]; -} - -inline int& IntVector4D::operator[](int i) -{ - Assert( (i >= 0) && (i < 4) ); - return ((int*)this)[i]; -} - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- -inline int* IntVector4D::Base() -{ - return (int*)this; -} - -inline int const* IntVector4D::Base() const -{ - return (int const*)this; -} - - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- - -inline bool IntVector4D::operator==( const IntVector4D& src ) const -{ - return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w); -} - -inline bool IntVector4D::operator!=( const IntVector4D& src ) const -{ - return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w); -} - - - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- - -FORCEINLINE IntVector4D& IntVector4D::operator+=(const IntVector4D& v) -{ - x+=v.x; y+=v.y; z += v.z; w += v.w; - return *this; -} - -FORCEINLINE IntVector4D& IntVector4D::operator-=(const IntVector4D& v) -{ - x-=v.x; y-=v.y; z -= v.z; w -= v.w; - return *this; -} - -FORCEINLINE IntVector4D& IntVector4D::operator*=(float fl) -{ - x *= fl; - y *= fl; - z *= fl; - w *= fl; - return *this; -} - -FORCEINLINE IntVector4D& IntVector4D::operator*=(const IntVector4D& v) -{ - x *= v.x; - y *= v.y; - z *= v.z; - w *= v.w; - return *this; -} - -FORCEINLINE IntVector4D& IntVector4D::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - z *= oofl; - w *= oofl; - return *this; -} - -FORCEINLINE IntVector4D& IntVector4D::operator/=(const IntVector4D& v) -{ - Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 ); - x /= v.x; - y /= v.y; - z /= v.z; - w /= v.w; - return *this; -} - -FORCEINLINE void IntVector4DMultiply( const IntVector4D& src, float fl, IntVector4D& res ) -{ - Assert( IsFinite(fl) ); - res.x = src.x * fl; - res.y = src.y * fl; - res.z = src.z * fl; - res.w = src.w * fl; -} - -FORCEINLINE IntVector4D IntVector4D::operator*(float fl) const -{ - IntVector4D res; - IntVector4DMultiply( *this, fl, res ); - return res; -} - - - -// ======================= - - -FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& c ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - c.x = a.x + b.x; - c.y = a.y + b.y; - c.z = a.z + b.z; -} - -FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& c ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - c.x = a.x - b.x; - c.y = a.y - b.y; - c.z = a.z - b.z; -} - -FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& c ) -{ - CHECK_VALID(a); - Assert( IsFinite(b) ); - c.x = a.x * b; - c.y = a.y * b; - c.z = a.z * b; -} - -FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& c ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - c.x = a.x * b.x; - c.y = a.y * b.y; - c.z = a.z * b.z; -} - -// for backwards compatability -inline void VectorScale ( const Vector& in, vec_t scale, Vector& result ) -{ - VectorMultiply( in, scale, result ); -} - - -FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& c ) -{ - CHECK_VALID(a); - Assert( b != 0.0f ); - vec_t oob = 1.0f / b; - c.x = a.x * oob; - c.y = a.y * oob; - c.z = a.z * oob; -} - -FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& c ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - Assert( (b.x != 0.0f) && (b.y != 0.0f) && (b.z != 0.0f) ); - c.x = a.x / b.x; - c.y = a.y / b.y; - c.z = a.z / b.z; -} - -// FIXME: Remove -// For backwards compatability -inline void Vector::MulAdd(const Vector& a, const Vector& b, float scalar) -{ - CHECK_VALID(a); - CHECK_VALID(b); - x = a.x + b.x * scalar; - y = a.y + b.y * scalar; - z = a.z + b.z * scalar; -} - -inline void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest ) -{ - CHECK_VALID(src1); - CHECK_VALID(src2); - dest.x = src1.x + (src2.x - src1.x) * t; - dest.y = src1.y + (src2.y - src1.y) * t; - dest.z = src1.z + (src2.z - src1.z) * t; -} - - -//----------------------------------------------------------------------------- -// Temporary storage for vector results so const Vector& results can be returned -//----------------------------------------------------------------------------- -inline Vector &AllocTempVector() -{ - static Vector s_vecTemp[128]; - static CInterlockedInt s_nIndex; - - int nIndex; - for (;;) - { - int nOldIndex = s_nIndex; - nIndex = ( (nOldIndex + 0x10001) & 0x7F ); - - if ( s_nIndex.AssignIf( nOldIndex, nIndex ) ) - { - break; - } - ThreadPause(); - } - return s_vecTemp[nIndex & 0xffff]; -} - - - -//----------------------------------------------------------------------------- -// dot, cross -//----------------------------------------------------------------------------- -FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b) -{ - CHECK_VALID(a); - CHECK_VALID(b); - return( a.x*b.x + a.y*b.y + a.z*b.z ); -} - -// for backwards compatability -inline vec_t Vector::Dot( const Vector& vOther ) const -{ - CHECK_VALID(vOther); - return DotProduct( *this, vOther ); -} - -inline void CrossProduct(const Vector& a, const Vector& b, Vector& result ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - Assert( &a != &result ); - Assert( &b != &result ); - result.x = a.y*b.z - a.z*b.y; - result.y = a.z*b.x - a.x*b.z; - result.z = a.x*b.y - a.y*b.x; -} - -inline vec_t DotProductAbs( const Vector &v0, const Vector &v1 ) -{ - CHECK_VALID(v0); - CHECK_VALID(v1); - return FloatMakePositive(v0.x*v1.x) + FloatMakePositive(v0.y*v1.y) + FloatMakePositive(v0.z*v1.z); -} - -inline vec_t DotProductAbs( const Vector &v0, const float *v1 ) -{ - return FloatMakePositive(v0.x * v1[0]) + FloatMakePositive(v0.y * v1[1]) + FloatMakePositive(v0.z * v1[2]); -} - -//----------------------------------------------------------------------------- -// length -//----------------------------------------------------------------------------- - -inline vec_t VectorLength( const Vector& v ) -{ - CHECK_VALID(v); - return (vec_t)FastSqrt(v.x*v.x + v.y*v.y + v.z*v.z); -} - - -inline vec_t Vector::Length(void) const -{ - CHECK_VALID(*this); - return VectorLength( *this ); -} - - -//----------------------------------------------------------------------------- -// Normalization -//----------------------------------------------------------------------------- - -/* -// FIXME: Can't use until we're un-macroed in mathlib.h -inline vec_t VectorNormalize( Vector& v ) -{ - Assert( v.IsValid() ); - vec_t l = v.Length(); - if (l != 0.0f) - { - v /= l; - } - else - { - // FIXME: - // Just copying the existing implemenation; shouldn't res.z == 0? - v.x = v.y = 0.0f; v.z = 1.0f; - } - return l; -} -*/ - - -// check a point against a box -bool Vector::WithinAABox( Vector const &boxmin, Vector const &boxmax) -{ - return ( - ( x >= boxmin.x ) && ( x <= boxmax.x) && - ( y >= boxmin.y ) && ( y <= boxmax.y) && - ( z >= boxmin.z ) && ( z <= boxmax.z) - ); -} - -//----------------------------------------------------------------------------- -// Get the distance from this vector to the other one -//----------------------------------------------------------------------------- -inline vec_t Vector::DistTo(const Vector &vOther) const -{ - Vector delta; - VectorSubtract( *this, vOther, delta ); - return delta.Length(); -} - - -//----------------------------------------------------------------------------- -// Vector equality with tolerance -//----------------------------------------------------------------------------- -inline bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance ) -{ - if (FloatMakePositive(src1.x - src2.x) > tolerance) - return false; - if (FloatMakePositive(src1.y - src2.y) > tolerance) - return false; - return (FloatMakePositive(src1.z - src2.z) <= tolerance); -} - - -//----------------------------------------------------------------------------- -// Computes the closest point to vecTarget no farther than flMaxDist from vecStart -//----------------------------------------------------------------------------- -inline void ComputeClosestPoint( const Vector& vecStart, float flMaxDist, const Vector& vecTarget, Vector *pResult ) -{ - Vector vecDelta; - VectorSubtract( vecTarget, vecStart, vecDelta ); - float flDistSqr = vecDelta.LengthSqr(); - if ( flDistSqr <= flMaxDist * flMaxDist ) - { - *pResult = vecTarget; - } - else - { - vecDelta /= FastSqrt( flDistSqr ); - VectorMA( vecStart, flMaxDist, vecDelta, *pResult ); - } -} - - -//----------------------------------------------------------------------------- -// Takes the absolute value of a vector -//----------------------------------------------------------------------------- -inline void VectorAbs( const Vector& src, Vector& dst ) -{ - dst.x = FloatMakePositive(src.x); - dst.y = FloatMakePositive(src.y); - dst.z = FloatMakePositive(src.z); -} - - -//----------------------------------------------------------------------------- -// -// Slow methods -// -//----------------------------------------------------------------------------- - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -//----------------------------------------------------------------------------- -// Returns a vector with the min or max in X, Y, and Z. -//----------------------------------------------------------------------------- -inline Vector Vector::Min(const Vector &vOther) const -{ - return Vector(x < vOther.x ? x : vOther.x, - y < vOther.y ? y : vOther.y, - z < vOther.z ? z : vOther.z); -} - -inline Vector Vector::Max(const Vector &vOther) const -{ - return Vector(x > vOther.x ? x : vOther.x, - y > vOther.y ? y : vOther.y, - z > vOther.z ? z : vOther.z); -} - - -//----------------------------------------------------------------------------- -// arithmetic operations -//----------------------------------------------------------------------------- - -inline Vector Vector::operator-(void) const -{ - return Vector(-x,-y,-z); -} - -inline Vector Vector::operator+(const Vector& v) const -{ - Vector res; - VectorAdd( *this, v, res ); - return res; -} - -inline Vector Vector::operator-(const Vector& v) const -{ - Vector res; - VectorSubtract( *this, v, res ); - return res; -} - -inline Vector Vector::operator*(float fl) const -{ - Vector res; - VectorMultiply( *this, fl, res ); - return res; -} - -inline Vector Vector::operator*(const Vector& v) const -{ - Vector res; - VectorMultiply( *this, v, res ); - return res; -} - -inline Vector Vector::operator/(float fl) const -{ - Vector res; - VectorDivide( *this, fl, res ); - return res; -} - -inline Vector Vector::operator/(const Vector& v) const -{ - Vector res; - VectorDivide( *this, v, res ); - return res; -} - -inline Vector operator*(float fl, const Vector& v) -{ - return v * fl; -} - -//----------------------------------------------------------------------------- -// cross product -//----------------------------------------------------------------------------- - -inline Vector Vector::Cross(const Vector& vOther) const -{ - Vector res; - CrossProduct( *this, vOther, res ); - return res; -} - -//----------------------------------------------------------------------------- -// 2D -//----------------------------------------------------------------------------- - -inline vec_t Vector::Length2D(void) const -{ - return (vec_t)FastSqrt(x*x + y*y); -} - -inline vec_t Vector::Length2DSqr(void) const -{ - return (x*x + y*y); -} - -inline Vector CrossProduct(const Vector& a, const Vector& b) -{ - return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); -} - -inline void VectorMin( const Vector &a, const Vector &b, Vector &result ) -{ - result.x = fpmin(a.x, b.x); - result.y = fpmin(a.y, b.y); - result.z = fpmin(a.z, b.z); -} - -inline void VectorMax( const Vector &a, const Vector &b, Vector &result ) -{ - result.x = fpmax(a.x, b.x); - result.y = fpmax(a.y, b.y); - result.z = fpmax(a.z, b.z); -} - -// Get a random vector. -inline Vector RandomVector( float minVal, float maxVal ) -{ - Vector random; - random.Random( minVal, maxVal ); - return random; -} - -#endif //slow - -//----------------------------------------------------------------------------- -// Helper debugging stuff.... -//----------------------------------------------------------------------------- - -inline bool operator==( float const* f, const Vector& v ) -{ - // AIIIEEEE!!!! - Assert(0); - return false; -} - -inline bool operator==( const Vector& v, float const* f ) -{ - // AIIIEEEE!!!! - Assert(0); - return false; -} - -inline bool operator!=( float const* f, const Vector& v ) -{ - // AIIIEEEE!!!! - Assert(0); - return false; -} - -inline bool operator!=( const Vector& v, float const* f ) -{ - // AIIIEEEE!!!! - Assert(0); - return false; -} - - -//----------------------------------------------------------------------------- -// AngularImpulse -//----------------------------------------------------------------------------- -// AngularImpulse are exponetial maps (an axis scaled by a "twist" angle in degrees) -typedef Vector AngularImpulse; - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline AngularImpulse RandomAngularImpulse( float minVal, float maxVal ) -{ - AngularImpulse angImp; - angImp.Random( minVal, maxVal ); - return angImp; -} - -#endif - - -//----------------------------------------------------------------------------- -// Quaternion -//----------------------------------------------------------------------------- - -class RadianEuler; - -class Quaternion // same data-layout as engine's vec4_t, -{ // which is a vec_t[4] -public: - inline Quaternion(void) { - - // Initialize to NAN to catch errors -#ifdef _DEBUG -#ifdef VECTOR_PARANOIA - x = y = z = w = VEC_T_NAN; -#endif -#endif - } - inline Quaternion(vec_t ix, vec_t iy, vec_t iz, vec_t iw) : x(ix), y(iy), z(iz), w(iw) { } - inline Quaternion(RadianEuler const &angle); // evil auto type promotion!!! - - inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f) { x = ix; y = iy; z = iz; w = iw; } - - bool IsValid() const; - void Invalidate(); - - bool operator==( const Quaternion &src ) const; - bool operator!=( const Quaternion &src ) const; - - vec_t* Base() { return (vec_t*)this; } - const vec_t* Base() const { return (vec_t*)this; } - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - vec_t x, y, z, w; -}; - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline vec_t& Quaternion::operator[](int i) -{ - Assert( (i >= 0) && (i < 4) ); - return ((vec_t*)this)[i]; -} - -inline vec_t Quaternion::operator[](int i) const -{ - Assert( (i >= 0) && (i < 4) ); - return ((vec_t*)this)[i]; -} - - -//----------------------------------------------------------------------------- -// Equality test -//----------------------------------------------------------------------------- -inline bool Quaternion::operator==( const Quaternion &src ) const -{ - return ( x == src.x ) && ( y == src.y ) && ( z == src.z ) && ( w == src.w ); -} - -inline bool Quaternion::operator!=( const Quaternion &src ) const -{ - return !operator==( src ); -} - - -//----------------------------------------------------------------------------- -// Quaternion equality with tolerance -//----------------------------------------------------------------------------- -inline bool QuaternionsAreEqual( const Quaternion& src1, const Quaternion& src2, float tolerance ) -{ - if (FloatMakePositive(src1.x - src2.x) > tolerance) - return false; - if (FloatMakePositive(src1.y - src2.y) > tolerance) - return false; - if (FloatMakePositive(src1.z - src2.z) > tolerance) - return false; - return (FloatMakePositive(src1.w - src2.w) <= tolerance); -} - - -//----------------------------------------------------------------------------- -// Here's where we add all those lovely SSE optimized routines -//----------------------------------------------------------------------------- -class ALIGN16 QuaternionAligned : public Quaternion -{ -public: - inline QuaternionAligned(void) {}; - inline QuaternionAligned(vec_t X, vec_t Y, vec_t Z, vec_t W) - { - Init(X,Y,Z,W); - } - -#ifdef VECTOR_NO_SLOW_OPERATIONS - -private: - // No copy constructors allowed if we're in optimal mode - QuaternionAligned(const QuaternionAligned& vOther); - QuaternionAligned(const Quaternion &vOther); - -#else -public: - explicit QuaternionAligned(const Quaternion &vOther) - { - Init(vOther.x, vOther.y, vOther.z, vOther.w); - } - - QuaternionAligned& operator=(const Quaternion &vOther) - { - Init(vOther.x, vOther.y, vOther.z, vOther.w); - return *this; - } - -#endif -}; - - -//----------------------------------------------------------------------------- -// Radian Euler angle aligned to axis (NOT ROLL/PITCH/YAW) -//----------------------------------------------------------------------------- -class QAngle; -class RadianEuler -{ -public: - inline RadianEuler(void) { } - inline RadianEuler(vec_t X, vec_t Y, vec_t Z) { x = X; y = Y; z = Z; } - inline RadianEuler(Quaternion const &q); // evil auto type promotion!!! - inline RadianEuler(QAngle const &angles); // evil auto type promotion!!! - - // Initialization - inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f) { x = ix; y = iy; z = iz; } - - // conversion to qangle - QAngle ToQAngle( void ) const; - bool IsValid() const; - void Invalidate(); - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - vec_t x, y, z; -}; - - -extern void AngleQuaternion( RadianEuler const &angles, Quaternion &qt ); -extern void QuaternionAngles( Quaternion const &q, RadianEuler &angles ); -inline Quaternion::Quaternion(RadianEuler const &angle) -{ - AngleQuaternion( angle, *this ); -} - -inline bool Quaternion::IsValid() const -{ - return IsFinite(x) && IsFinite(y) && IsFinite(z) && IsFinite(w); -} - -inline void Quaternion::Invalidate() -{ -//#ifdef _DEBUG -//#ifdef VECTOR_PARANOIA - x = y = z = w = VEC_T_NAN; -//#endif -//#endif -} - -inline RadianEuler::RadianEuler(Quaternion const &q) -{ - QuaternionAngles( q, *this ); -} - -inline void VectorCopy( RadianEuler const& src, RadianEuler &dst ) -{ - CHECK_VALID(src); - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; -} - -inline void VectorScale( RadianEuler const& src, float b, RadianEuler &dst ) -{ - CHECK_VALID(src); - Assert( IsFinite(b) ); - dst.x = src.x * b; - dst.y = src.y * b; - dst.z = src.z * b; -} - -inline bool RadianEuler::IsValid() const -{ - return IsFinite(x) && IsFinite(y) && IsFinite(z); -} - -inline void RadianEuler::Invalidate() -{ -//#ifdef _DEBUG -//#ifdef VECTOR_PARANOIA - x = y = z = VEC_T_NAN; -//#endif -//#endif -} - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline vec_t& RadianEuler::operator[](int i) -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - -inline vec_t RadianEuler::operator[](int i) const -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - - -//----------------------------------------------------------------------------- -// Degree Euler QAngle pitch, yaw, roll -//----------------------------------------------------------------------------- -class QAngleByValue; - -class QAngle -{ -public: - // Members - vec_t x, y, z; - - // Construction/destruction - QAngle(void); - QAngle(vec_t X, vec_t Y, vec_t Z); -// QAngle(RadianEuler const &angles); // evil auto type promotion!!! - - // Allow pass-by-value - operator QAngleByValue &() { return *((QAngleByValue *)(this)); } - operator const QAngleByValue &() const { return *((const QAngleByValue *)(this)); } - - // Initialization - void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f); - void Random( vec_t minVal, vec_t maxVal ); - - // Got any nasty NAN's? - bool IsValid() const; - void Invalidate(); - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - // Base address... - vec_t* Base(); - vec_t const* Base() const; - - // equality - bool operator==(const QAngle& v) const; - bool operator!=(const QAngle& v) const; - - // arithmetic operations - QAngle& operator+=(const QAngle &v); - QAngle& operator-=(const QAngle &v); - QAngle& operator*=(float s); - QAngle& operator/=(float s); - - // Get the vector's magnitude. - vec_t Length() const; - vec_t LengthSqr() const; - - // negate the QAngle components - //void Negate(); - - // No assignment operators either... - QAngle& operator=( const QAngle& src ); - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // copy constructors - - // arithmetic operations - QAngle operator-(void) const; - - QAngle operator+(const QAngle& v) const; - QAngle operator-(const QAngle& v) const; - QAngle operator*(float fl) const; - QAngle operator/(float fl) const; -#else - -private: - // No copy constructors allowed if we're in optimal mode - QAngle(const QAngle& vOther); - -#endif -}; - -//----------------------------------------------------------------------------- -// Allows us to specifically pass the vector by value when we need to -//----------------------------------------------------------------------------- -class QAngleByValue : public QAngle -{ -public: - // Construction/destruction: - QAngleByValue(void) : QAngle() {} - QAngleByValue(vec_t X, vec_t Y, vec_t Z) : QAngle( X, Y, Z ) {} - QAngleByValue(const QAngleByValue& vOther) { *this = vOther; } -}; - - -inline void VectorAdd( const QAngle& a, const QAngle& b, QAngle& result ) -{ - CHECK_VALID(a); - CHECK_VALID(b); - result.x = a.x + b.x; - result.y = a.y + b.y; - result.z = a.z + b.z; -} - -inline void VectorMA( const QAngle &start, float scale, const QAngle &direction, QAngle &dest ) -{ - CHECK_VALID(start); - CHECK_VALID(direction); - dest.x = start.x + scale * direction.x; - dest.y = start.y + scale * direction.y; - dest.z = start.z + scale * direction.z; -} - - -//----------------------------------------------------------------------------- -// constructors -//----------------------------------------------------------------------------- -inline QAngle::QAngle(void) -{ -#ifdef _DEBUG -#ifdef VECTOR_PARANOIA - // Initialize to NAN to catch errors - x = y = z = VEC_T_NAN; -#endif -#endif -} - -inline QAngle::QAngle(vec_t X, vec_t Y, vec_t Z) -{ - x = X; y = Y; z = Z; - CHECK_VALID(*this); -} - - -//----------------------------------------------------------------------------- -// initialization -//----------------------------------------------------------------------------- -inline void QAngle::Init( vec_t ix, vec_t iy, vec_t iz ) -{ - x = ix; y = iy; z = iz; - CHECK_VALID(*this); -} - -inline void QAngle::Random( vec_t minVal, vec_t maxVal ) -{ - x = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - y = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - z = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - CHECK_VALID(*this); -} - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline QAngle RandomAngle( float minVal, float maxVal ) -{ - Vector random; - random.Random( minVal, maxVal ); - QAngle ret( random.x, random.y, random.z ); - return ret; -} - -#endif - - -inline RadianEuler::RadianEuler(QAngle const &angles) -{ - Init( - angles.z * 3.14159265358979323846f / 180.f, - angles.x * 3.14159265358979323846f / 180.f, - angles.y * 3.14159265358979323846f / 180.f ); -} - - - - -inline QAngle RadianEuler::ToQAngle( void) const -{ - return QAngle( - y * 180.f / 3.14159265358979323846f, - z * 180.f / 3.14159265358979323846f, - x * 180.f / 3.14159265358979323846f ); -} - - -//----------------------------------------------------------------------------- -// assignment -//----------------------------------------------------------------------------- -inline QAngle& QAngle::operator=(const QAngle &vOther) -{ - CHECK_VALID(vOther); - x=vOther.x; y=vOther.y; z=vOther.z; - return *this; -} - - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- -inline vec_t& QAngle::operator[](int i) -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - -inline vec_t QAngle::operator[](int i) const -{ - Assert( (i >= 0) && (i < 3) ); - return ((vec_t*)this)[i]; -} - - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- -inline vec_t* QAngle::Base() -{ - return (vec_t*)this; -} - -inline vec_t const* QAngle::Base() const -{ - return (vec_t const*)this; -} - - -//----------------------------------------------------------------------------- -// IsValid? -//----------------------------------------------------------------------------- -inline bool QAngle::IsValid() const -{ - return IsFinite(x) && IsFinite(y) && IsFinite(z); -} - -//----------------------------------------------------------------------------- -// Invalidate -//----------------------------------------------------------------------------- - -inline void QAngle::Invalidate() -{ -//#ifdef _DEBUG -//#ifdef VECTOR_PARANOIA - x = y = z = VEC_T_NAN; -//#endif -//#endif -} - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- -inline bool QAngle::operator==( const QAngle& src ) const -{ - CHECK_VALID(src); - CHECK_VALID(*this); - return (src.x == x) && (src.y == y) && (src.z == z); -} - -inline bool QAngle::operator!=( const QAngle& src ) const -{ - CHECK_VALID(src); - CHECK_VALID(*this); - return (src.x != x) || (src.y != y) || (src.z != z); -} - - -//----------------------------------------------------------------------------- -// Copy -//----------------------------------------------------------------------------- -inline void VectorCopy( const QAngle& src, QAngle& dst ) -{ - CHECK_VALID(src); - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; -} - - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- -inline QAngle& QAngle::operator+=(const QAngle& v) -{ - CHECK_VALID(*this); - CHECK_VALID(v); - x+=v.x; y+=v.y; z += v.z; - return *this; -} - -inline QAngle& QAngle::operator-=(const QAngle& v) -{ - CHECK_VALID(*this); - CHECK_VALID(v); - x-=v.x; y-=v.y; z -= v.z; - return *this; -} - -inline QAngle& QAngle::operator*=(float fl) -{ - x *= fl; - y *= fl; - z *= fl; - CHECK_VALID(*this); - return *this; -} - -inline QAngle& QAngle::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - z *= oofl; - CHECK_VALID(*this); - return *this; -} - - -//----------------------------------------------------------------------------- -// length -//----------------------------------------------------------------------------- -inline vec_t QAngle::Length( ) const -{ - CHECK_VALID(*this); - return (vec_t)FastSqrt( LengthSqr( ) ); -} - - -inline vec_t QAngle::LengthSqr( ) const -{ - CHECK_VALID(*this); - return x * x + y * y + z * z; -} - - -//----------------------------------------------------------------------------- -// Vector equality with tolerance -//----------------------------------------------------------------------------- -inline bool QAnglesAreEqual( const QAngle& src1, const QAngle& src2, float tolerance = 0.0f ) -{ - if (FloatMakePositive(src1.x - src2.x) > tolerance) - return false; - if (FloatMakePositive(src1.y - src2.y) > tolerance) - return false; - return (FloatMakePositive(src1.z - src2.z) <= tolerance); -} - - -//----------------------------------------------------------------------------- -// arithmetic operations (SLOW!!) -//----------------------------------------------------------------------------- -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline QAngle QAngle::operator-(void) const -{ - QAngle ret(-x,-y,-z); - return ret; -} - -inline QAngle QAngle::operator+(const QAngle& v) const -{ - QAngle res; - res.x = x + v.x; - res.y = y + v.y; - res.z = z + v.z; - return res; -} - -inline QAngle QAngle::operator-(const QAngle& v) const -{ - QAngle res; - res.x = x - v.x; - res.y = y - v.y; - res.z = z - v.z; - return res; -} - -inline QAngle QAngle::operator*(float fl) const -{ - QAngle res; - res.x = x * fl; - res.y = y * fl; - res.z = z * fl; - return res; -} - -inline QAngle QAngle::operator/(float fl) const -{ - QAngle res; - res.x = x / fl; - res.y = y / fl; - res.z = z / fl; - return res; -} - -inline QAngle operator*(float fl, const QAngle& v) -{ - QAngle ret( v * fl ); - return ret; -} - -#endif // VECTOR_NO_SLOW_OPERATIONS - - -//----------------------------------------------------------------------------- -// NOTE: These are not completely correct. The representations are not equivalent -// unless the QAngle represents a rotational impulse along a coordinate axis (x,y,z) -inline void QAngleToAngularImpulse( const QAngle &angles, AngularImpulse &impulse ) -{ - impulse.x = angles.z; - impulse.y = angles.x; - impulse.z = angles.y; -} - -inline void AngularImpulseToQAngle( const AngularImpulse &impulse, QAngle &angles ) -{ - angles.x = impulse.y; - angles.y = impulse.z; - angles.z = impulse.x; -} - -#if !defined( _X360 ) -extern float (*pfInvRSquared)( const float *v ); - -FORCEINLINE vec_t InvRSquared( float const *v ) -{ - return (*pfInvRSquared)(v); -} - -FORCEINLINE vec_t InvRSquared( const Vector &v ) -{ - return InvRSquared(&v.x); -} - -#else - -// call directly -FORCEINLINE float _VMX_InvRSquared( const Vector &v ) -{ - XMVECTOR xmV = XMVector3ReciprocalLength( XMLoadVector3( v.Base() ) ); - xmV = XMVector3Dot( xmV, xmV ); - return xmV.x; -} - -#define InvRSquared(x) _VMX_InvRSquared(x) - -#endif // _X360 - -#if !defined( _X360 ) -extern float (FASTCALL *pfVectorNormalize)(Vector& v); - -// FIXME: Change this back to a #define once we get rid of the vec_t version -FORCEINLINE float VectorNormalize( Vector& v ) -{ - return (*pfVectorNormalize)(v); -} -// FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s -FORCEINLINE float VectorNormalize( float * v ) -{ - return VectorNormalize(*(reinterpret_cast(v))); -} - -#else - -// call directly -FORCEINLINE float _VMX_VectorNormalize( Vector &vec ) -{ - float mag = XMVector3Length( XMLoadVector3( vec.Base() ) ).x; - float den = 1.f / (mag + FLT_EPSILON ); - vec.x *= den; - vec.y *= den; - vec.z *= den; - return mag; -} -// FIXME: Change this back to a #define once we get rid of the vec_t version -FORCEINLINE float VectorNormalize( Vector& v ) -{ - return _VMX_VectorNormalize( v ); -} -// FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s -FORCEINLINE float VectorNormalize( float *pV ) -{ - return _VMX_VectorNormalize(*(reinterpret_cast(pV))); -} - -#endif // _X360 - -#if !defined( _X360 ) -extern void (FASTCALL *pfVectorNormalizeFast)(Vector& v); - -FORCEINLINE void VectorNormalizeFast( Vector& v ) -{ - (*pfVectorNormalizeFast)(v); -} - -#else - -// call directly -FORCEINLINE void VectorNormalizeFast( Vector &vec ) -{ - XMVECTOR xmV = XMVector3LengthEst( XMLoadVector3( vec.Base() ) ); - float den = 1.f / (xmV.x + FLT_EPSILON); - vec.x *= den; - vec.y *= den; - vec.z *= den; -} - -#endif // _X360 - -inline vec_t Vector::NormalizeInPlace() -{ - return VectorNormalize( *this ); -} - -inline bool Vector::IsLengthGreaterThan( float val ) const -{ - return LengthSqr() > val*val; -} - -inline bool Vector::IsLengthLessThan( float val ) const -{ - return LengthSqr() < val*val; -} - -#endif - diff --git a/Resources/NetHook/mathlib/vector2d.h b/Resources/NetHook/mathlib/vector2d.h deleted file mode 100644 index 35ed31e6..00000000 --- a/Resources/NetHook/mathlib/vector2d.h +++ /dev/null @@ -1,670 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef VECTOR2D_H -#define VECTOR2D_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include - -// For vec_t, put this somewhere else? -#include "tier0/basetypes.h" - -// For rand(). We really need a library! -#include - -#include "tier0/dbg.h" -#include "mathlib/math_pfns.h" - -//========================================================= -// 2D Vector2D -//========================================================= - -class Vector2D -{ -public: - // Members - vec_t x, y; - - // Construction/destruction - Vector2D(void); - Vector2D(vec_t X, vec_t Y); - Vector2D(const float *pFloat); - - // Initialization - void Init(vec_t ix=0.0f, vec_t iy=0.0f); - - // Got any nasty NAN's? - bool IsValid() const; - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - // Base address... - vec_t* Base(); - vec_t const* Base() const; - - // Initialization methods - void Random( float minVal, float maxVal ); - - // equality - bool operator==(const Vector2D& v) const; - bool operator!=(const Vector2D& v) const; - - // arithmetic operations - Vector2D& operator+=(const Vector2D &v); - Vector2D& operator-=(const Vector2D &v); - Vector2D& operator*=(const Vector2D &v); - Vector2D& operator*=(float s); - Vector2D& operator/=(const Vector2D &v); - Vector2D& operator/=(float s); - - // negate the Vector2D components - void Negate(); - - // Get the Vector2D's magnitude. - vec_t Length() const; - - // Get the Vector2D's magnitude squared. - vec_t LengthSqr(void) const; - - // return true if this vector is (0,0) within tolerance - bool IsZero( float tolerance = 0.01f ) const - { - return (x > -tolerance && x < tolerance && - y > -tolerance && y < tolerance); - } - - // Normalize in place and return the old length. - vec_t NormalizeInPlace(); - - // Compare length. - bool IsLengthGreaterThan( float val ) const; - bool IsLengthLessThan( float val ) const; - - // Get the distance from this Vector2D to the other one. - vec_t DistTo(const Vector2D &vOther) const; - - // Get the distance from this Vector2D to the other one squared. - vec_t DistToSqr(const Vector2D &vOther) const; - - // Copy - void CopyToArray(float* rgfl) const; - - // Multiply, add, and assign to this (ie: *this = a + b * scalar). This - // is about 12% faster than the actual Vector2D equation (because it's done per-component - // rather than per-Vector2D). - void MulAdd(const Vector2D& a, const Vector2D& b, float scalar); - - // Dot product. - vec_t Dot(const Vector2D& vOther) const; - - // assignment - Vector2D& operator=(const Vector2D &vOther); - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // copy constructors - Vector2D(const Vector2D &vOther); - - // arithmetic operations - Vector2D operator-(void) const; - - Vector2D operator+(const Vector2D& v) const; - Vector2D operator-(const Vector2D& v) const; - Vector2D operator*(const Vector2D& v) const; - Vector2D operator/(const Vector2D& v) const; - Vector2D operator*(float fl) const; - Vector2D operator/(float fl) const; - - // Cross product between two vectors. - Vector2D Cross(const Vector2D &vOther) const; - - // Returns a Vector2D with the min or max in X, Y, and Z. - Vector2D Min(const Vector2D &vOther) const; - Vector2D Max(const Vector2D &vOther) const; - -#else - -private: - // No copy constructors allowed if we're in optimal mode - Vector2D(const Vector2D& vOther); -#endif -}; - -//----------------------------------------------------------------------------- - -const Vector2D vec2_origin(0,0); -const Vector2D vec2_invalid( FLT_MAX, FLT_MAX ); - -//----------------------------------------------------------------------------- -// Vector2D related operations -//----------------------------------------------------------------------------- - -// Vector2D clear -void Vector2DClear( Vector2D& a ); - -// Copy -void Vector2DCopy( const Vector2D& src, Vector2D& dst ); - -// Vector2D arithmetic -void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& result ); -void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& result ); -void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& result ); -void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& result ); -void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& result ); -void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& result ); -void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result ); - -// Store the min or max of each of x, y, and z into the result. -void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result ); -void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result ); - -#define Vector2DExpand( v ) (v).x, (v).y - -// Normalization -vec_t Vector2DNormalize( Vector2D& v ); - -// Length -vec_t Vector2DLength( const Vector2D& v ); - -// Dot Product -vec_t DotProduct2D(const Vector2D& a, const Vector2D& b); - -// Linearly interpolate between two vectors -void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest ); - - -//----------------------------------------------------------------------------- -// -// Inlined Vector2D methods -// -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// constructors -//----------------------------------------------------------------------------- - -inline Vector2D::Vector2D(void) -{ -#ifdef _DEBUG - // Initialize to NAN to catch errors - x = y = VEC_T_NAN; -#endif -} - -inline Vector2D::Vector2D(vec_t X, vec_t Y) -{ - x = X; y = Y; - Assert( IsValid() ); -} - -inline Vector2D::Vector2D(const float *pFloat) -{ - Assert( pFloat ); - x = pFloat[0]; y = pFloat[1]; - Assert( IsValid() ); -} - - -//----------------------------------------------------------------------------- -// copy constructor -//----------------------------------------------------------------------------- - -inline Vector2D::Vector2D(const Vector2D &vOther) -{ - Assert( vOther.IsValid() ); - x = vOther.x; y = vOther.y; -} - -//----------------------------------------------------------------------------- -// initialization -//----------------------------------------------------------------------------- - -inline void Vector2D::Init( vec_t ix, vec_t iy ) -{ - x = ix; y = iy; - Assert( IsValid() ); -} - -inline void Vector2D::Random( float minVal, float maxVal ) -{ - x = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); - y = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); -} - -inline void Vector2DClear( Vector2D& a ) -{ - a.x = a.y = 0.0f; -} - -//----------------------------------------------------------------------------- -// assignment -//----------------------------------------------------------------------------- - -inline Vector2D& Vector2D::operator=(const Vector2D &vOther) -{ - Assert( vOther.IsValid() ); - x=vOther.x; y=vOther.y; - return *this; -} - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- - -inline vec_t& Vector2D::operator[](int i) -{ - Assert( (i >= 0) && (i < 2) ); - return ((vec_t*)this)[i]; -} - -inline vec_t Vector2D::operator[](int i) const -{ - Assert( (i >= 0) && (i < 2) ); - return ((vec_t*)this)[i]; -} - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- - -inline vec_t* Vector2D::Base() -{ - return (vec_t*)this; -} - -inline vec_t const* Vector2D::Base() const -{ - return (vec_t const*)this; -} - -//----------------------------------------------------------------------------- -// IsValid? -//----------------------------------------------------------------------------- - -inline bool Vector2D::IsValid() const -{ - return IsFinite(x) && IsFinite(y); -} - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- - -inline bool Vector2D::operator==( const Vector2D& src ) const -{ - Assert( src.IsValid() && IsValid() ); - return (src.x == x) && (src.y == y); -} - -inline bool Vector2D::operator!=( const Vector2D& src ) const -{ - Assert( src.IsValid() && IsValid() ); - return (src.x != x) || (src.y != y); -} - - -//----------------------------------------------------------------------------- -// Copy -//----------------------------------------------------------------------------- - -inline void Vector2DCopy( const Vector2D& src, Vector2D& dst ) -{ - Assert( src.IsValid() ); - dst.x = src.x; - dst.y = src.y; -} - -inline void Vector2D::CopyToArray(float* rgfl) const -{ - Assert( IsValid() ); - Assert( rgfl ); - rgfl[0] = x; rgfl[1] = y; -} - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- - -inline void Vector2D::Negate() -{ - Assert( IsValid() ); - x = -x; y = -y; -} - -inline Vector2D& Vector2D::operator+=(const Vector2D& v) -{ - Assert( IsValid() && v.IsValid() ); - x+=v.x; y+=v.y; - return *this; -} - -inline Vector2D& Vector2D::operator-=(const Vector2D& v) -{ - Assert( IsValid() && v.IsValid() ); - x-=v.x; y-=v.y; - return *this; -} - -inline Vector2D& Vector2D::operator*=(float fl) -{ - x *= fl; - y *= fl; - Assert( IsValid() ); - return *this; -} - -inline Vector2D& Vector2D::operator*=(const Vector2D& v) -{ - x *= v.x; - y *= v.y; - Assert( IsValid() ); - return *this; -} - -inline Vector2D& Vector2D::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - Assert( IsValid() ); - return *this; -} - -inline Vector2D& Vector2D::operator/=(const Vector2D& v) -{ - Assert( v.x != 0.0f && v.y != 0.0f ); - x /= v.x; - y /= v.y; - Assert( IsValid() ); - return *this; -} - -inline void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x + b.x; - c.y = a.y + b.y; -} - -inline void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x - b.x; - c.y = a.y - b.y; -} - -inline void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& c ) -{ - Assert( a.IsValid() && IsFinite(b) ); - c.x = a.x * b; - c.y = a.y * b; -} - -inline void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x * b.x; - c.y = a.y * b.y; -} - - -inline void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& c ) -{ - Assert( a.IsValid() ); - Assert( b != 0.0f ); - vec_t oob = 1.0f / b; - c.x = a.x * oob; - c.y = a.y * oob; -} - -inline void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& c ) -{ - Assert( a.IsValid() ); - Assert( (b.x != 0.0f) && (b.y != 0.0f) ); - c.x = a.x / b.x; - c.y = a.y / b.y; -} - -inline void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result ) -{ - Assert( start.IsValid() && IsFinite(s) && dir.IsValid() ); - result.x = start.x + s*dir.x; - result.y = start.y + s*dir.y; -} - -// FIXME: Remove -// For backwards compatability -inline void Vector2D::MulAdd(const Vector2D& a, const Vector2D& b, float scalar) -{ - x = a.x + b.x * scalar; - y = a.y + b.y * scalar; -} - -inline void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest ) -{ - dest[0] = src1[0] + (src2[0] - src1[0]) * t; - dest[1] = src1[1] + (src2[1] - src1[1]) * t; -} - -//----------------------------------------------------------------------------- -// dot, cross -//----------------------------------------------------------------------------- -inline vec_t DotProduct2D(const Vector2D& a, const Vector2D& b) -{ - Assert( a.IsValid() && b.IsValid() ); - return( a.x*b.x + a.y*b.y ); -} - -// for backwards compatability -inline vec_t Vector2D::Dot( const Vector2D& vOther ) const -{ - return DotProduct2D( *this, vOther ); -} - - -//----------------------------------------------------------------------------- -// length -//----------------------------------------------------------------------------- -inline vec_t Vector2DLength( const Vector2D& v ) -{ - Assert( v.IsValid() ); - return (vec_t)FastSqrt(v.x*v.x + v.y*v.y); -} - -inline vec_t Vector2D::LengthSqr(void) const -{ - Assert( IsValid() ); - return (x*x + y*y); -} - -inline vec_t Vector2D::NormalizeInPlace() -{ - return Vector2DNormalize( *this ); -} - -inline bool Vector2D::IsLengthGreaterThan( float val ) const -{ - return LengthSqr() > val*val; -} - -inline bool Vector2D::IsLengthLessThan( float val ) const -{ - return LengthSqr() < val*val; -} - -inline vec_t Vector2D::Length(void) const -{ - return Vector2DLength( *this ); -} - - -inline void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result ) -{ - result.x = (a.x < b.x) ? a.x : b.x; - result.y = (a.y < b.y) ? a.y : b.y; -} - - -inline void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result ) -{ - result.x = (a.x > b.x) ? a.x : b.x; - result.y = (a.y > b.y) ? a.y : b.y; -} - - -//----------------------------------------------------------------------------- -// Normalization -//----------------------------------------------------------------------------- -inline vec_t Vector2DNormalize( Vector2D& v ) -{ - Assert( v.IsValid() ); - vec_t l = v.Length(); - if (l != 0.0f) - { - v /= l; - } - else - { - v.x = v.y = 0.0f; - } - return l; -} - - -//----------------------------------------------------------------------------- -// Get the distance from this Vector2D to the other one -//----------------------------------------------------------------------------- -inline vec_t Vector2D::DistTo(const Vector2D &vOther) const -{ - Vector2D delta; - Vector2DSubtract( *this, vOther, delta ); - return delta.Length(); -} - -inline vec_t Vector2D::DistToSqr(const Vector2D &vOther) const -{ - Vector2D delta; - Vector2DSubtract( *this, vOther, delta ); - return delta.LengthSqr(); -} - - -//----------------------------------------------------------------------------- -// Computes the closest point to vecTarget no farther than flMaxDist from vecStart -//----------------------------------------------------------------------------- -inline void ComputeClosestPoint2D( const Vector2D& vecStart, float flMaxDist, const Vector2D& vecTarget, Vector2D *pResult ) -{ - Vector2D vecDelta; - Vector2DSubtract( vecTarget, vecStart, vecDelta ); - float flDistSqr = vecDelta.LengthSqr(); - if ( flDistSqr <= flMaxDist * flMaxDist ) - { - *pResult = vecTarget; - } - else - { - vecDelta /= FastSqrt( flDistSqr ); - Vector2DMA( vecStart, flMaxDist, vecDelta, *pResult ); - } -} - - - -//----------------------------------------------------------------------------- -// -// Slow methods -// -//----------------------------------------------------------------------------- - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -//----------------------------------------------------------------------------- -// Returns a Vector2D with the min or max in X, Y, and Z. -//----------------------------------------------------------------------------- - -inline Vector2D Vector2D::Min(const Vector2D &vOther) const -{ - return Vector2D(x < vOther.x ? x : vOther.x, - y < vOther.y ? y : vOther.y); -} - -inline Vector2D Vector2D::Max(const Vector2D &vOther) const -{ - return Vector2D(x > vOther.x ? x : vOther.x, - y > vOther.y ? y : vOther.y); -} - - -//----------------------------------------------------------------------------- -// arithmetic operations -//----------------------------------------------------------------------------- - -inline Vector2D Vector2D::operator-(void) const -{ - return Vector2D(-x,-y); -} - -inline Vector2D Vector2D::operator+(const Vector2D& v) const -{ - Vector2D res; - Vector2DAdd( *this, v, res ); - return res; -} - -inline Vector2D Vector2D::operator-(const Vector2D& v) const -{ - Vector2D res; - Vector2DSubtract( *this, v, res ); - return res; -} - -inline Vector2D Vector2D::operator*(float fl) const -{ - Vector2D res; - Vector2DMultiply( *this, fl, res ); - return res; -} - -inline Vector2D Vector2D::operator*(const Vector2D& v) const -{ - Vector2D res; - Vector2DMultiply( *this, v, res ); - return res; -} - -inline Vector2D Vector2D::operator/(float fl) const -{ - Vector2D res; - Vector2DDivide( *this, fl, res ); - return res; -} - -inline Vector2D Vector2D::operator/(const Vector2D& v) const -{ - Vector2D res; - Vector2DDivide( *this, v, res ); - return res; -} - -inline Vector2D operator*(float fl, const Vector2D& v) -{ - return v * fl; -} - -#endif //slow - -#endif // VECTOR2D_H - diff --git a/Resources/NetHook/mathlib/vector4d.h b/Resources/NetHook/mathlib/vector4d.h deleted file mode 100644 index a74fb3a6..00000000 --- a/Resources/NetHook/mathlib/vector4d.h +++ /dev/null @@ -1,690 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef VECTOR4D_H -#define VECTOR4D_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include // For rand(). We really need a library! -#include -#if !defined( _X360 ) -#include // For SSE -#endif -#include "basetypes.h" // For vec_t, put this somewhere else? -#include "tier0/dbg.h" -#include "mathlib/math_pfns.h" - -// forward declarations -class Vector; -class Vector2D; - -//========================================================= -// 4D Vector4D -//========================================================= - -class Vector4D -{ -public: - // Members - vec_t x, y, z, w; - - // Construction/destruction - Vector4D(void); - Vector4D(vec_t X, vec_t Y, vec_t Z, vec_t W); - Vector4D(const float *pFloat); - - // Initialization - void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f); - - // Got any nasty NAN's? - bool IsValid() const; - - // array access... - vec_t operator[](int i) const; - vec_t& operator[](int i); - - // Base address... - inline vec_t* Base(); - inline vec_t const* Base() const; - - // Cast to Vector and Vector2D... - Vector& AsVector3D(); - Vector const& AsVector3D() const; - - Vector2D& AsVector2D(); - Vector2D const& AsVector2D() const; - - // Initialization methods - void Random( vec_t minVal, vec_t maxVal ); - - // equality - bool operator==(const Vector4D& v) const; - bool operator!=(const Vector4D& v) const; - - // arithmetic operations - Vector4D& operator+=(const Vector4D &v); - Vector4D& operator-=(const Vector4D &v); - Vector4D& operator*=(const Vector4D &v); - Vector4D& operator*=(float s); - Vector4D& operator/=(const Vector4D &v); - Vector4D& operator/=(float s); - - // negate the Vector4D components - void Negate(); - - // Get the Vector4D's magnitude. - vec_t Length() const; - - // Get the Vector4D's magnitude squared. - vec_t LengthSqr(void) const; - - // return true if this vector is (0,0,0,0) within tolerance - bool IsZero( float tolerance = 0.01f ) const - { - return (x > -tolerance && x < tolerance && - y > -tolerance && y < tolerance && - z > -tolerance && z < tolerance && - w > -tolerance && w < tolerance); - } - - // Get the distance from this Vector4D to the other one. - vec_t DistTo(const Vector4D &vOther) const; - - // Get the distance from this Vector4D to the other one squared. - vec_t DistToSqr(const Vector4D &vOther) const; - - // Copy - void CopyToArray(float* rgfl) const; - - // Multiply, add, and assign to this (ie: *this = a + b * scalar). This - // is about 12% faster than the actual Vector4D equation (because it's done per-component - // rather than per-Vector4D). - void MulAdd(Vector4D const& a, Vector4D const& b, float scalar); - - // Dot product. - vec_t Dot(Vector4D const& vOther) const; - - // No copy constructors allowed if we're in optimal mode -#ifdef VECTOR_NO_SLOW_OPERATIONS -private: -#else -public: -#endif - Vector4D(Vector4D const& vOther); - - // No assignment operators either... - Vector4D& operator=( Vector4D const& src ); -}; - -const Vector4D vec4_origin( 0.0f, 0.0f, 0.0f, 0.0f ); -const Vector4D vec4_invalid( FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX ); - -//----------------------------------------------------------------------------- -// SSE optimized routines -//----------------------------------------------------------------------------- - -#ifdef _WIN32 -class __declspec(align(16)) Vector4DAligned : public Vector4D -#elif _LINUX -class __attribute__((aligned(16))) Vector4DAligned : public Vector4D -#endif -{ -public: - Vector4DAligned(void) {} - Vector4DAligned( vec_t X, vec_t Y, vec_t Z, vec_t W ); - - inline void Set( vec_t X, vec_t Y, vec_t Z, vec_t W ); - inline void InitZero( void ); - - inline __m128 &AsM128() { return *(__m128*)&x; } - inline const __m128 &AsM128() const { return *(const __m128*)&x; } - -private: - // No copy constructors allowed if we're in optimal mode - Vector4DAligned( Vector4DAligned const& vOther ); - - // No assignment operators either... - Vector4DAligned& operator=( Vector4DAligned const& src ); -}; - -//----------------------------------------------------------------------------- -// Vector4D related operations -//----------------------------------------------------------------------------- - -// Vector4D clear -void Vector4DClear( Vector4D& a ); - -// Copy -void Vector4DCopy( Vector4D const& src, Vector4D& dst ); - -// Vector4D arithmetic -void Vector4DAdd( Vector4D const& a, Vector4D const& b, Vector4D& result ); -void Vector4DSubtract( Vector4D const& a, Vector4D const& b, Vector4D& result ); -void Vector4DMultiply( Vector4D const& a, vec_t b, Vector4D& result ); -void Vector4DMultiply( Vector4D const& a, Vector4D const& b, Vector4D& result ); -void Vector4DDivide( Vector4D const& a, vec_t b, Vector4D& result ); -void Vector4DDivide( Vector4D const& a, Vector4D const& b, Vector4D& result ); -void Vector4DMA( Vector4D const& start, float s, Vector4D const& dir, Vector4D& result ); - -// Vector4DAligned arithmetic -void Vector4DMultiplyAligned( Vector4DAligned const& a, vec_t b, Vector4DAligned& result ); - - -#define Vector4DExpand( v ) (v).x, (v).y, (v).z, (v).w - -// Normalization -vec_t Vector4DNormalize( Vector4D& v ); - -// Length -vec_t Vector4DLength( Vector4D const& v ); - -// Dot Product -vec_t DotProduct4D(Vector4D const& a, Vector4D const& b); - -// Linearly interpolate between two vectors -void Vector4DLerp(Vector4D const& src1, Vector4D const& src2, vec_t t, Vector4D& dest ); - - -//----------------------------------------------------------------------------- -// -// Inlined Vector4D methods -// -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// constructors -//----------------------------------------------------------------------------- - -inline Vector4D::Vector4D(void) -{ -#ifdef _DEBUG - // Initialize to NAN to catch errors - x = y = z = w = VEC_T_NAN; -#endif -} - -inline Vector4D::Vector4D(vec_t X, vec_t Y, vec_t Z, vec_t W ) -{ - x = X; y = Y; z = Z; w = W; - Assert( IsValid() ); -} - -inline Vector4D::Vector4D(const float *pFloat) -{ - Assert( pFloat ); - x = pFloat[0]; y = pFloat[1]; z = pFloat[2]; w = pFloat[3]; - Assert( IsValid() ); -} - - -//----------------------------------------------------------------------------- -// copy constructor -//----------------------------------------------------------------------------- - -inline Vector4D::Vector4D(const Vector4D &vOther) -{ - Assert( vOther.IsValid() ); - x = vOther.x; y = vOther.y; z = vOther.z; w = vOther.w; -} - -//----------------------------------------------------------------------------- -// initialization -//----------------------------------------------------------------------------- - -inline void Vector4D::Init( vec_t ix, vec_t iy, vec_t iz, vec_t iw ) -{ - x = ix; y = iy; z = iz; w = iw; - Assert( IsValid() ); -} - -inline void Vector4D::Random( vec_t minVal, vec_t maxVal ) -{ - x = minVal + ((vec_t)rand() / RAND_MAX) * (maxVal - minVal); - y = minVal + ((vec_t)rand() / RAND_MAX) * (maxVal - minVal); - z = minVal + ((vec_t)rand() / RAND_MAX) * (maxVal - minVal); - w = minVal + ((vec_t)rand() / RAND_MAX) * (maxVal - minVal); -} - -inline void Vector4DClear( Vector4D& a ) -{ - a.x = a.y = a.z = a.w = 0.0f; -} - -//----------------------------------------------------------------------------- -// assignment -//----------------------------------------------------------------------------- - -inline Vector4D& Vector4D::operator=(const Vector4D &vOther) -{ - Assert( vOther.IsValid() ); - x=vOther.x; y=vOther.y; z=vOther.z; w=vOther.w; - return *this; -} - -//----------------------------------------------------------------------------- -// Array access -//----------------------------------------------------------------------------- - -inline vec_t& Vector4D::operator[](int i) -{ - Assert( (i >= 0) && (i < 4) ); - return ((vec_t*)this)[i]; -} - -inline vec_t Vector4D::operator[](int i) const -{ - Assert( (i >= 0) && (i < 4) ); - return ((vec_t*)this)[i]; -} - -//----------------------------------------------------------------------------- -// Cast to Vector and Vector2D... -//----------------------------------------------------------------------------- - -inline Vector& Vector4D::AsVector3D() -{ - return *(Vector*)this; -} - -inline Vector const& Vector4D::AsVector3D() const -{ - return *(Vector const*)this; -} - -inline Vector2D& Vector4D::AsVector2D() -{ - return *(Vector2D*)this; -} - -inline Vector2D const& Vector4D::AsVector2D() const -{ - return *(Vector2D const*)this; -} - -//----------------------------------------------------------------------------- -// Base address... -//----------------------------------------------------------------------------- - -inline vec_t* Vector4D::Base() -{ - return (vec_t*)this; -} - -inline vec_t const* Vector4D::Base() const -{ - return (vec_t const*)this; -} - -//----------------------------------------------------------------------------- -// IsValid? -//----------------------------------------------------------------------------- - -inline bool Vector4D::IsValid() const -{ - return IsFinite(x) && IsFinite(y) && IsFinite(z) && IsFinite(w); -} - -//----------------------------------------------------------------------------- -// comparison -//----------------------------------------------------------------------------- - -inline bool Vector4D::operator==( Vector4D const& src ) const -{ - Assert( src.IsValid() && IsValid() ); - return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w); -} - -inline bool Vector4D::operator!=( Vector4D const& src ) const -{ - Assert( src.IsValid() && IsValid() ); - return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w); -} - - -//----------------------------------------------------------------------------- -// Copy -//----------------------------------------------------------------------------- - -inline void Vector4DCopy( Vector4D const& src, Vector4D& dst ) -{ - Assert( src.IsValid() ); - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; - dst.w = src.w; -} - -inline void Vector4D::CopyToArray(float* rgfl) const -{ - Assert( IsValid() ); - Assert( rgfl ); - rgfl[0] = x; rgfl[1] = y; rgfl[2] = z; rgfl[3] = w; -} - -//----------------------------------------------------------------------------- -// standard math operations -//----------------------------------------------------------------------------- - -inline void Vector4D::Negate() -{ - Assert( IsValid() ); - x = -x; y = -y; z = -z; w = -w; -} - -inline Vector4D& Vector4D::operator+=(const Vector4D& v) -{ - Assert( IsValid() && v.IsValid() ); - x+=v.x; y+=v.y; z += v.z; w += v.w; - return *this; -} - -inline Vector4D& Vector4D::operator-=(const Vector4D& v) -{ - Assert( IsValid() && v.IsValid() ); - x-=v.x; y-=v.y; z -= v.z; w -= v.w; - return *this; -} - -inline Vector4D& Vector4D::operator*=(float fl) -{ - x *= fl; - y *= fl; - z *= fl; - w *= fl; - Assert( IsValid() ); - return *this; -} - -inline Vector4D& Vector4D::operator*=(Vector4D const& v) -{ - x *= v.x; - y *= v.y; - z *= v.z; - w *= v.w; - Assert( IsValid() ); - return *this; -} - -inline Vector4D& Vector4D::operator/=(float fl) -{ - Assert( fl != 0.0f ); - float oofl = 1.0f / fl; - x *= oofl; - y *= oofl; - z *= oofl; - w *= oofl; - Assert( IsValid() ); - return *this; -} - -inline Vector4D& Vector4D::operator/=(Vector4D const& v) -{ - Assert( v.x != 0.0f && v.y != 0.0f && v.z != 0.0f && v.w != 0.0f ); - x /= v.x; - y /= v.y; - z /= v.z; - w /= v.w; - Assert( IsValid() ); - return *this; -} - -inline void Vector4DAdd( Vector4D const& a, Vector4D const& b, Vector4D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x + b.x; - c.y = a.y + b.y; - c.z = a.z + b.z; - c.w = a.w + b.w; -} - -inline void Vector4DSubtract( Vector4D const& a, Vector4D const& b, Vector4D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x - b.x; - c.y = a.y - b.y; - c.z = a.z - b.z; - c.w = a.w - b.w; -} - -inline void Vector4DMultiply( Vector4D const& a, vec_t b, Vector4D& c ) -{ - Assert( a.IsValid() && IsFinite(b) ); - c.x = a.x * b; - c.y = a.y * b; - c.z = a.z * b; - c.w = a.w * b; -} - -inline void Vector4DMultiply( Vector4D const& a, Vector4D const& b, Vector4D& c ) -{ - Assert( a.IsValid() && b.IsValid() ); - c.x = a.x * b.x; - c.y = a.y * b.y; - c.z = a.z * b.z; - c.w = a.w * b.w; -} - -inline void Vector4DDivide( Vector4D const& a, vec_t b, Vector4D& c ) -{ - Assert( a.IsValid() ); - Assert( b != 0.0f ); - vec_t oob = 1.0f / b; - c.x = a.x * oob; - c.y = a.y * oob; - c.z = a.z * oob; - c.w = a.w * oob; -} - -inline void Vector4DDivide( Vector4D const& a, Vector4D const& b, Vector4D& c ) -{ - Assert( a.IsValid() ); - Assert( (b.x != 0.0f) && (b.y != 0.0f) && (b.z != 0.0f) && (b.w != 0.0f) ); - c.x = a.x / b.x; - c.y = a.y / b.y; - c.z = a.z / b.z; - c.w = a.w / b.w; -} - -inline void Vector4DMA( Vector4D const& start, float s, Vector4D const& dir, Vector4D& result ) -{ - Assert( start.IsValid() && IsFinite(s) && dir.IsValid() ); - result.x = start.x + s*dir.x; - result.y = start.y + s*dir.y; - result.z = start.z + s*dir.z; - result.w = start.w + s*dir.w; -} - -// FIXME: Remove -// For backwards compatability -inline void Vector4D::MulAdd(Vector4D const& a, Vector4D const& b, float scalar) -{ - x = a.x + b.x * scalar; - y = a.y + b.y * scalar; - z = a.z + b.z * scalar; - w = a.w + b.w * scalar; -} - -inline void Vector4DLerp(const Vector4D& src1, const Vector4D& src2, vec_t t, Vector4D& dest ) -{ - dest[0] = src1[0] + (src2[0] - src1[0]) * t; - dest[1] = src1[1] + (src2[1] - src1[1]) * t; - dest[2] = src1[2] + (src2[2] - src1[2]) * t; - dest[3] = src1[3] + (src2[3] - src1[3]) * t; -} - -//----------------------------------------------------------------------------- -// dot, cross -//----------------------------------------------------------------------------- - -inline vec_t DotProduct4D(const Vector4D& a, const Vector4D& b) -{ - Assert( a.IsValid() && b.IsValid() ); - return( a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w ); -} - -// for backwards compatability -inline vec_t Vector4D::Dot( Vector4D const& vOther ) const -{ - return DotProduct4D( *this, vOther ); -} - - -//----------------------------------------------------------------------------- -// length -//----------------------------------------------------------------------------- - -inline vec_t Vector4DLength( Vector4D const& v ) -{ - Assert( v.IsValid() ); - return (vec_t)FastSqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w); -} - -inline vec_t Vector4D::LengthSqr(void) const -{ - Assert( IsValid() ); - return (x*x + y*y + z*z + w*w); -} - -inline vec_t Vector4D::Length(void) const -{ - return Vector4DLength( *this ); -} - - -//----------------------------------------------------------------------------- -// Normalization -//----------------------------------------------------------------------------- - -// FIXME: Can't use until we're un-macroed in mathlib.h -inline vec_t Vector4DNormalize( Vector4D& v ) -{ - Assert( v.IsValid() ); - vec_t l = v.Length(); - if (l != 0.0f) - { - v /= l; - } - else - { - v.x = v.y = v.z = v.w = 0.0f; - } - return l; -} - -//----------------------------------------------------------------------------- -// Get the distance from this Vector4D to the other one -//----------------------------------------------------------------------------- - -inline vec_t Vector4D::DistTo(const Vector4D &vOther) const -{ - Vector4D delta; - Vector4DSubtract( *this, vOther, delta ); - return delta.Length(); -} - -inline vec_t Vector4D::DistToSqr(const Vector4D &vOther) const -{ - Vector4D delta; - Vector4DSubtract( *this, vOther, delta ); - return delta.LengthSqr(); -} - - -//----------------------------------------------------------------------------- -// Vector4DAligned routines -//----------------------------------------------------------------------------- - -inline Vector4DAligned::Vector4DAligned( vec_t X, vec_t Y, vec_t Z, vec_t W ) -{ - x = X; y = Y; z = Z; w = W; - Assert( IsValid() ); -} - -inline void Vector4DAligned::Set( vec_t X, vec_t Y, vec_t Z, vec_t W ) -{ - x = X; y = Y; z = Z; w = W; - Assert( IsValid() ); -} - -inline void Vector4DAligned::InitZero( void ) -{ -#if !defined( _X360 ) - this->AsM128() = _mm_set1_ps( 0.0f ); -#else - this->AsM128() = __vspltisw( 0 ); -#endif - Assert( IsValid() ); -} - -inline void Vector4DMultiplyAligned( Vector4DAligned const& a, Vector4DAligned const& b, Vector4DAligned& c ) -{ - Assert( a.IsValid() && b.IsValid() ); -#if !defined( _X360 ) - c.x = a.x * b.x; - c.y = a.y * b.y; - c.z = a.z * b.z; - c.w = a.w * b.w; -#else - c.AsM128() = __vmulfp( a.AsM128(), b.AsM128() ); -#endif -} - -inline void Vector4DWeightMAD( vec_t w, Vector4DAligned const& vInA, Vector4DAligned& vOutA, Vector4DAligned const& vInB, Vector4DAligned& vOutB ) -{ - Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) ); - -#if !defined( _X360 ) - vOutA.x += vInA.x * w; - vOutA.y += vInA.y * w; - vOutA.z += vInA.z * w; - vOutA.w += vInA.w * w; - - vOutB.x += vInB.x * w; - vOutB.y += vInB.y * w; - vOutB.z += vInB.z * w; - vOutB.w += vInB.w * w; -#else - __vector4 temp; - - temp = __lvlx( &w, 0 ); - temp = __vspltw( temp, 0 ); - - vOutA.AsM128() = __vmaddfp( vInA.AsM128(), temp, vOutA.AsM128() ); - vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() ); -#endif -} - -inline void Vector4DWeightMADSSE( vec_t w, Vector4DAligned const& vInA, Vector4DAligned& vOutA, Vector4DAligned const& vInB, Vector4DAligned& vOutB ) -{ - Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) ); - -#if !defined( _X360 ) - // Replicate scalar float out to 4 components - __m128 packed = _mm_set1_ps( w ); - - // 4D SSE Vector MAD - vOutA.AsM128() = _mm_add_ps( vOutA.AsM128(), _mm_mul_ps( vInA.AsM128(), packed ) ); - vOutB.AsM128() = _mm_add_ps( vOutB.AsM128(), _mm_mul_ps( vInB.AsM128(), packed ) ); -#else - __vector4 temp; - - temp = __lvlx( &w, 0 ); - temp = __vspltw( temp, 0 ); - - vOutA.AsM128() = __vmaddfp( vInA.AsM128(), temp, vOutA.AsM128() ); - vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() ); -#endif -} - -#endif // VECTOR4D_H - diff --git a/Resources/NetHook/mathlib/vmatrix.h b/Resources/NetHook/mathlib/vmatrix.h deleted file mode 100644 index 6915e81d..00000000 --- a/Resources/NetHook/mathlib/vmatrix.h +++ /dev/null @@ -1,938 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -// -// VMatrix always postmultiply vectors as in Ax = b. -// Given a set of basis vectors ((F)orward, (L)eft, (U)p), and a (T)ranslation, -// a matrix to transform a vector into that space looks like this: -// Fx Lx Ux Tx -// Fy Ly Uy Ty -// Fz Lz Uz Tz -// 0 0 0 1 - -// Note that concatenating matrices needs to multiply them in reverse order. -// ie: if I want to apply matrix A, B, then C, the equation needs to look like this: -// C * B * A * v -// ie: -// v = A * v; -// v = B * v; -// v = C * v; -//============================================================================= - -#ifndef VMATRIX_H -#define VMATRIX_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include "mathlib/vector.h" -#include "mathlib/vplane.h" -#include "mathlib/vector4d.h" -#include "mathlib/mathlib.h" - -struct cplane_t; - - -class VMatrix -{ -public: - - VMatrix(); - VMatrix( - vec_t m00, vec_t m01, vec_t m02, vec_t m03, - vec_t m10, vec_t m11, vec_t m12, vec_t m13, - vec_t m20, vec_t m21, vec_t m22, vec_t m23, - vec_t m30, vec_t m31, vec_t m32, vec_t m33 - ); - - // Creates a matrix where the X axis = forward - // the Y axis = left, and the Z axis = up - VMatrix( const Vector& forward, const Vector& left, const Vector& up ); - - // Construct from a 3x4 matrix - VMatrix( const matrix3x4_t& matrix3x4 ); - - // Set the values in the matrix. - void Init( - vec_t m00, vec_t m01, vec_t m02, vec_t m03, - vec_t m10, vec_t m11, vec_t m12, vec_t m13, - vec_t m20, vec_t m21, vec_t m22, vec_t m23, - vec_t m30, vec_t m31, vec_t m32, vec_t m33 - ); - - - // Initialize from a 3x4 - void Init( const matrix3x4_t& matrix3x4 ); - - // array access - inline float* operator[](int i) - { - return m[i]; - } - - inline const float* operator[](int i) const - { - return m[i]; - } - - // Get a pointer to m[0][0] - inline float *Base() - { - return &m[0][0]; - } - - inline const float *Base() const - { - return &m[0][0]; - } - - void SetLeft(const Vector &vLeft); - void SetUp(const Vector &vUp); - void SetForward(const Vector &vForward); - - void GetBasisVectors(Vector &vForward, Vector &vLeft, Vector &vUp) const; - void SetBasisVectors(const Vector &vForward, const Vector &vLeft, const Vector &vUp); - - // Get/set the translation. - Vector & GetTranslation( Vector &vTrans ) const; - void SetTranslation(const Vector &vTrans); - - void PreTranslate(const Vector &vTrans); - void PostTranslate(const Vector &vTrans); - - matrix3x4_t& As3x4(); - const matrix3x4_t& As3x4() const; - void CopyFrom3x4( const matrix3x4_t &m3x4 ); - void Set3x4( matrix3x4_t& matrix3x4 ) const; - - bool operator==( const VMatrix& src ) const; - bool operator!=( const VMatrix& src ) const { return !( *this == src ); } - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // Access the basis vectors. - Vector GetLeft() const; - Vector GetUp() const; - Vector GetForward() const; - Vector GetTranslation() const; -#endif - - -// Matrix->vector operations. -public: - // Multiply by a 3D vector (same as operator*). - void V3Mul(const Vector &vIn, Vector &vOut) const; - - // Multiply by a 4D vector. - void V4Mul(const Vector4D &vIn, Vector4D &vOut) const; - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // Applies the rotation (ignores translation in the matrix). (This just calls VMul3x3). - Vector ApplyRotation(const Vector &vVec) const; - - // Multiply by a vector (divides by w, assumes input w is 1). - Vector operator*(const Vector &vVec) const; - - // Multiply by the upper 3x3 part of the matrix (ie: only apply rotation). - Vector VMul3x3(const Vector &vVec) const; - - // Apply the inverse (transposed) rotation (only works on pure rotation matrix) - Vector VMul3x3Transpose(const Vector &vVec) const; - - // Multiply by the upper 3 rows. - Vector VMul4x3(const Vector &vVec) const; - - // Apply the inverse (transposed) transformation (only works on pure rotation/translation) - Vector VMul4x3Transpose(const Vector &vVec) const; -#endif - - -// Matrix->plane operations. -public: - // Transform the plane. The matrix can only contain translation and rotation. - void TransformPlane( const VPlane &inPlane, VPlane &outPlane ) const; - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // Just calls TransformPlane and returns the result. - VPlane operator*(const VPlane &thePlane) const; -#endif - -// Matrix->matrix operations. -public: - - VMatrix& operator=(const VMatrix &mOther); - - // Multiply two matrices (out = this * vm). - void MatrixMul( const VMatrix &vm, VMatrix &out ) const; - - // Add two matrices. - const VMatrix& operator+=(const VMatrix &other); - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // Just calls MatrixMul and returns the result. - VMatrix operator*(const VMatrix &mOther) const; - - // Add/Subtract two matrices. - VMatrix operator+(const VMatrix &other) const; - VMatrix operator-(const VMatrix &other) const; - - // Negation. - VMatrix operator-() const; - - // Return inverse matrix. Be careful because the results are undefined - // if the matrix doesn't have an inverse (ie: InverseGeneral returns false). - VMatrix operator~() const; -#endif - -// Matrix operations. -public: - // Set to identity. - void Identity(); - - bool IsIdentity() const; - - // Setup a matrix for origin and angles. - void SetupMatrixOrgAngles( const Vector &origin, const QAngle &vAngles ); - - // General inverse. This may fail so check the return! - bool InverseGeneral(VMatrix &vInverse) const; - - // Does a fast inverse, assuming the matrix only contains translation and rotation. - void InverseTR( VMatrix &mRet ) const; - - // Usually used for debug checks. Returns true if the upper 3x3 contains - // unit vectors and they are all orthogonal. - bool IsRotationMatrix() const; - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // This calls the other InverseTR and returns the result. - VMatrix InverseTR() const; - - // Get the scale of the matrix's basis vectors. - Vector GetScale() const; - - // (Fast) multiply by a scaling matrix setup from vScale. - VMatrix Scale(const Vector &vScale); - - // Normalize the basis vectors. - VMatrix NormalizeBasisVectors() const; - - // Transpose. - VMatrix Transpose() const; - - // Transpose upper-left 3x3. - VMatrix Transpose3x3() const; -#endif - -public: - // The matrix. - vec_t m[4][4]; -}; - - - -//----------------------------------------------------------------------------- -// Helper functions. -//----------------------------------------------------------------------------- - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -// Setup an identity matrix. -VMatrix SetupMatrixIdentity(); - -// Setup as a scaling matrix. -VMatrix SetupMatrixScale(const Vector &vScale); - -// Setup a translation matrix. -VMatrix SetupMatrixTranslation(const Vector &vTranslation); - -// Setup a matrix to reflect around the plane. -VMatrix SetupMatrixReflection(const VPlane &thePlane); - -// Setup a matrix to project from vOrigin onto thePlane. -VMatrix SetupMatrixProjection(const Vector &vOrigin, const VPlane &thePlane); - -// Setup a matrix to rotate the specified amount around the specified axis. -VMatrix SetupMatrixAxisRot(const Vector &vAxis, vec_t fDegrees); - -// Setup a matrix from euler angles. Just sets identity and calls MatrixAngles. -VMatrix SetupMatrixAngles(const QAngle &vAngles); - -// Setup a matrix for origin and angles. -VMatrix SetupMatrixOrgAngles(const Vector &origin, const QAngle &vAngles); - -#endif - -#define VMatToString(mat) (static_cast(CFmtStr("[ (%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f) ]", mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3], mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3] ))) // ** Note: this generates a temporary, don't hold reference! - -//----------------------------------------------------------------------------- -// Returns the point at the intersection on the 3 planes. -// Returns false if it can't be solved (2 or more planes are parallel). -//----------------------------------------------------------------------------- -bool PlaneIntersection( const VPlane &vp1, const VPlane &vp2, const VPlane &vp3, Vector &vOut ); - - -//----------------------------------------------------------------------------- -// These methods are faster. Use them if you want faster code -//----------------------------------------------------------------------------- -void MatrixSetIdentity( VMatrix &dst ); -void MatrixTranspose( const VMatrix& src, VMatrix& dst ); -void MatrixCopy( const VMatrix& src, VMatrix& dst ); -void MatrixMultiply( const VMatrix& src1, const VMatrix& src2, VMatrix& dst ); - -// Accessors -void MatrixGetColumn( const VMatrix &src, int nCol, Vector *pColumn ); -void MatrixSetColumn( VMatrix &src, int nCol, const Vector &column ); -void MatrixGetRow( const VMatrix &src, int nCol, Vector *pColumn ); -void MatrixSetRow( VMatrix &src, int nCol, const Vector &column ); - -// Vector3DMultiply treats src2 as if it's a direction vector -void Vector3DMultiply( const VMatrix& src1, const Vector& src2, Vector& dst ); - -// Vector3DMultiplyPosition treats src2 as if it's a point (adds the translation) -inline void Vector3DMultiplyPosition( const VMatrix& src1, const VectorByValue src2, Vector& dst ); - -// Vector3DMultiplyPositionProjective treats src2 as if it's a point -// and does the perspective divide at the end -void Vector3DMultiplyPositionProjective( const VMatrix& src1, const Vector &src2, Vector& dst ); - -// Vector3DMultiplyPosition treats src2 as if it's a direction -// and does the perspective divide at the end -// NOTE: src1 had better be an inverse transpose to use this correctly -void Vector3DMultiplyProjective( const VMatrix& src1, const Vector &src2, Vector& dst ); - -void Vector4DMultiply( const VMatrix& src1, const Vector4D& src2, Vector4D& dst ); - -// Same as Vector4DMultiply except that src2 has an implicit W of 1 -void Vector4DMultiplyPosition( const VMatrix& src1, const Vector &src2, Vector4D& dst ); - -// Multiplies the vector by the transpose of the matrix -void Vector3DMultiplyTranspose( const VMatrix& src1, const Vector& src2, Vector& dst ); -void Vector4DMultiplyTranspose( const VMatrix& src1, const Vector4D& src2, Vector4D& dst ); - -// Transform a plane -void MatrixTransformPlane( const VMatrix &src, const cplane_t &inPlane, cplane_t &outPlane ); - -// Transform a plane that has an axis-aligned normal -void MatrixTransformAxisAlignedPlane( const VMatrix &src, int nDim, float flSign, float flDist, cplane_t &outPlane ); - -void MatrixBuildTranslation( VMatrix& dst, float x, float y, float z ); -void MatrixBuildTranslation( VMatrix& dst, const Vector &translation ); - -inline void MatrixTranslate( VMatrix& dst, const Vector &translation ) -{ - VMatrix matTranslation, temp; - MatrixBuildTranslation( matTranslation, translation ); - MatrixMultiply( dst, matTranslation, temp ); - dst = temp; -} - - -void MatrixBuildRotationAboutAxis( VMatrix& dst, const Vector& vAxisOfRot, float angleDegrees ); -void MatrixBuildRotateZ( VMatrix& dst, float angleDegrees ); - -inline void MatrixRotate( VMatrix& dst, const Vector& vAxisOfRot, float angleDegrees ) -{ - VMatrix rotation, temp; - MatrixBuildRotationAboutAxis( rotation, vAxisOfRot, angleDegrees ); - MatrixMultiply( dst, rotation, temp ); - dst = temp; -} - -// Builds a rotation matrix that rotates one direction vector into another -void MatrixBuildRotation( VMatrix &dst, const Vector& initialDirection, const Vector& finalDirection ); - -// Builds a scale matrix -void MatrixBuildScale( VMatrix &dst, float x, float y, float z ); -void MatrixBuildScale( VMatrix &dst, const Vector& scale ); - -// Build a perspective matrix. -// zNear and zFar are assumed to be positive. -// You end up looking down positive Z, X is to the right, Y is up. -// X range: [0..1] -// Y range: [0..1] -// Z range: [0..1] -void MatrixBuildPerspective( VMatrix &dst, float fovX, float fovY, float zNear, float zFar ); - -//----------------------------------------------------------------------------- -// Given a projection matrix, take the extremes of the space in transformed into world space and -// get a bounding box. -//----------------------------------------------------------------------------- -void CalculateAABBFromProjectionMatrix( const VMatrix &worldToVolume, Vector *pMins, Vector *pMaxs ); - -//----------------------------------------------------------------------------- -// Given a projection matrix, take the extremes of the space in transformed into world space and -// get a bounding sphere. -//----------------------------------------------------------------------------- -void CalculateSphereFromProjectionMatrix( const VMatrix &worldToVolume, Vector *pCenter, float *pflRadius ); - -//----------------------------------------------------------------------------- -// Given an inverse projection matrix, take the extremes of the space in transformed into world space and -// get a bounding box. -//----------------------------------------------------------------------------- -void CalculateAABBFromProjectionMatrixInverse( const VMatrix &volumeToWorld, Vector *pMins, Vector *pMaxs ); - -//----------------------------------------------------------------------------- -// Given an inverse projection matrix, take the extremes of the space in transformed into world space and -// get a bounding sphere. -//----------------------------------------------------------------------------- -void CalculateSphereFromProjectionMatrixInverse( const VMatrix &volumeToWorld, Vector *pCenter, float *pflRadius ); - -//----------------------------------------------------------------------------- -// Calculate frustum planes given a clip->world space transform. -//----------------------------------------------------------------------------- -void FrustumPlanesFromMatrix( const VMatrix &clipToWorld, Frustum_t &frustum ); - -//----------------------------------------------------------------------------- -// Setup a matrix from euler angles. -//----------------------------------------------------------------------------- -void MatrixFromAngles( const QAngle& vAngles, VMatrix& dst ); - -//----------------------------------------------------------------------------- -// Creates euler angles from a matrix -//----------------------------------------------------------------------------- -void MatrixToAngles( const VMatrix& src, QAngle& vAngles ); - -//----------------------------------------------------------------------------- -// Does a fast inverse, assuming the matrix only contains translation and rotation. -//----------------------------------------------------------------------------- -void MatrixInverseTR( const VMatrix& src, VMatrix &dst ); - -//----------------------------------------------------------------------------- -// Inverts any matrix at all -//----------------------------------------------------------------------------- -bool MatrixInverseGeneral(const VMatrix& src, VMatrix& dst); - -//----------------------------------------------------------------------------- -// Computes the inverse transpose -//----------------------------------------------------------------------------- -void MatrixInverseTranspose( const VMatrix& src, VMatrix& dst ); - - - -//----------------------------------------------------------------------------- -// VMatrix inlines. -//----------------------------------------------------------------------------- -inline VMatrix::VMatrix() -{ -} - -inline VMatrix::VMatrix( - vec_t m00, vec_t m01, vec_t m02, vec_t m03, - vec_t m10, vec_t m11, vec_t m12, vec_t m13, - vec_t m20, vec_t m21, vec_t m22, vec_t m23, - vec_t m30, vec_t m31, vec_t m32, vec_t m33) -{ - Init( - m00, m01, m02, m03, - m10, m11, m12, m13, - m20, m21, m22, m23, - m30, m31, m32, m33 - ); -} - - -inline VMatrix::VMatrix( const matrix3x4_t& matrix3x4 ) -{ - Init( matrix3x4 ); -} - - -//----------------------------------------------------------------------------- -// Creates a matrix where the X axis = forward -// the Y axis = left, and the Z axis = up -//----------------------------------------------------------------------------- -inline VMatrix::VMatrix( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis ) -{ - Init( - xAxis.x, yAxis.x, zAxis.x, 0.0f, - xAxis.y, yAxis.y, zAxis.y, 0.0f, - xAxis.z, yAxis.z, zAxis.z, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - ); -} - - -inline void VMatrix::Init( - vec_t m00, vec_t m01, vec_t m02, vec_t m03, - vec_t m10, vec_t m11, vec_t m12, vec_t m13, - vec_t m20, vec_t m21, vec_t m22, vec_t m23, - vec_t m30, vec_t m31, vec_t m32, vec_t m33 - ) -{ - m[0][0] = m00; - m[0][1] = m01; - m[0][2] = m02; - m[0][3] = m03; - - m[1][0] = m10; - m[1][1] = m11; - m[1][2] = m12; - m[1][3] = m13; - - m[2][0] = m20; - m[2][1] = m21; - m[2][2] = m22; - m[2][3] = m23; - - m[3][0] = m30; - m[3][1] = m31; - m[3][2] = m32; - m[3][3] = m33; -} - - -//----------------------------------------------------------------------------- -// Initialize from a 3x4 -//----------------------------------------------------------------------------- -inline void VMatrix::Init( const matrix3x4_t& matrix3x4 ) -{ - memcpy(m, matrix3x4.Base(), sizeof( matrix3x4_t ) ); - - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; -} - - -//----------------------------------------------------------------------------- -// Methods related to the basis vectors of the matrix -//----------------------------------------------------------------------------- - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline Vector VMatrix::GetForward() const -{ - return Vector(m[0][0], m[1][0], m[2][0]); -} - -inline Vector VMatrix::GetLeft() const -{ - return Vector(m[0][1], m[1][1], m[2][1]); -} - -inline Vector VMatrix::GetUp() const -{ - return Vector(m[0][2], m[1][2], m[2][2]); -} - -#endif - -inline void VMatrix::SetForward(const Vector &vForward) -{ - m[0][0] = vForward.x; - m[1][0] = vForward.y; - m[2][0] = vForward.z; -} - -inline void VMatrix::SetLeft(const Vector &vLeft) -{ - m[0][1] = vLeft.x; - m[1][1] = vLeft.y; - m[2][1] = vLeft.z; -} - -inline void VMatrix::SetUp(const Vector &vUp) -{ - m[0][2] = vUp.x; - m[1][2] = vUp.y; - m[2][2] = vUp.z; -} - -inline void VMatrix::GetBasisVectors(Vector &vForward, Vector &vLeft, Vector &vUp) const -{ - vForward.Init( m[0][0], m[1][0], m[2][0] ); - vLeft.Init( m[0][1], m[1][1], m[2][1] ); - vUp.Init( m[0][2], m[1][2], m[2][2] ); -} - -inline void VMatrix::SetBasisVectors(const Vector &vForward, const Vector &vLeft, const Vector &vUp) -{ - SetForward(vForward); - SetLeft(vLeft); - SetUp(vUp); -} - - -//----------------------------------------------------------------------------- -// Methods related to the translation component of the matrix -//----------------------------------------------------------------------------- -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline Vector VMatrix::GetTranslation() const -{ - return Vector(m[0][3], m[1][3], m[2][3]); -} - -#endif - -inline Vector& VMatrix::GetTranslation( Vector &vTrans ) const -{ - vTrans.x = m[0][3]; - vTrans.y = m[1][3]; - vTrans.z = m[2][3]; - return vTrans; -} - -inline void VMatrix::SetTranslation(const Vector &vTrans) -{ - m[0][3] = vTrans.x; - m[1][3] = vTrans.y; - m[2][3] = vTrans.z; -} - - -//----------------------------------------------------------------------------- -// appply translation to this matrix in the input space -//----------------------------------------------------------------------------- -inline void VMatrix::PreTranslate(const Vector &vTrans) -{ - Vector tmp; - Vector3DMultiplyPosition( *this, vTrans, tmp ); - m[0][3] = tmp.x; - m[1][3] = tmp.y; - m[2][3] = tmp.z; -} - - -//----------------------------------------------------------------------------- -// appply translation to this matrix in the output space -//----------------------------------------------------------------------------- -inline void VMatrix::PostTranslate(const Vector &vTrans) -{ - m[0][3] += vTrans.x; - m[1][3] += vTrans.y; - m[2][3] += vTrans.z; -} - -inline const matrix3x4_t& VMatrix::As3x4() const -{ - return *((const matrix3x4_t*)this); -} - -inline matrix3x4_t& VMatrix::As3x4() -{ - return *((matrix3x4_t*)this); -} - -inline void VMatrix::CopyFrom3x4( const matrix3x4_t &m3x4 ) -{ - memcpy( m, m3x4.Base(), sizeof( matrix3x4_t ) ); - m[3][0] = m[3][1] = m[3][2] = 0; - m[3][3] = 1; -} - -inline void VMatrix::Set3x4( matrix3x4_t& matrix3x4 ) const -{ - memcpy(matrix3x4.Base(), m, sizeof( matrix3x4_t ) ); -} - - -//----------------------------------------------------------------------------- -// Matrix math operations -//----------------------------------------------------------------------------- -inline const VMatrix& VMatrix::operator+=(const VMatrix &other) -{ - for(int i=0; i < 4; i++) - { - for(int j=0; j < 4; j++) - { - m[i][j] += other.m[i][j]; - } - } - - return *this; -} - - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline VMatrix VMatrix::operator+(const VMatrix &other) const -{ - VMatrix ret; - for(int i=0; i < 16; i++) - { - ((float*)ret.m)[i] = ((float*)m)[i] + ((float*)other.m)[i]; - } - return ret; -} - -inline VMatrix VMatrix::operator-(const VMatrix &other) const -{ - VMatrix ret; - - for(int i=0; i < 4; i++) - { - for(int j=0; j < 4; j++) - { - ret.m[i][j] = m[i][j] - other.m[i][j]; - } - } - - return ret; -} - -inline VMatrix VMatrix::operator-() const -{ - VMatrix ret; - for( int i=0; i < 16; i++ ) - { - ((float*)ret.m)[i] = ((float*)m)[i]; - } - return ret; -} - -#endif // VECTOR_NO_SLOW_OPERATIONS - - -//----------------------------------------------------------------------------- -// Vector transformation -//----------------------------------------------------------------------------- - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline Vector VMatrix::operator*(const Vector &vVec) const -{ - Vector vRet; - vRet.x = m[0][0]*vVec.x + m[0][1]*vVec.y + m[0][2]*vVec.z + m[0][3]; - vRet.y = m[1][0]*vVec.x + m[1][1]*vVec.y + m[1][2]*vVec.z + m[1][3]; - vRet.z = m[2][0]*vVec.x + m[2][1]*vVec.y + m[2][2]*vVec.z + m[2][3]; - - return vRet; -} - -inline Vector VMatrix::VMul4x3(const Vector &vVec) const -{ - Vector vResult; - Vector3DMultiplyPosition( *this, vVec, vResult ); - return vResult; -} - - -inline Vector VMatrix::VMul4x3Transpose(const Vector &vVec) const -{ - Vector tmp = vVec; - tmp.x -= m[0][3]; - tmp.y -= m[1][3]; - tmp.z -= m[2][3]; - - return Vector( - m[0][0]*tmp.x + m[1][0]*tmp.y + m[2][0]*tmp.z, - m[0][1]*tmp.x + m[1][1]*tmp.y + m[2][1]*tmp.z, - m[0][2]*tmp.x + m[1][2]*tmp.y + m[2][2]*tmp.z - ); -} - -inline Vector VMatrix::VMul3x3(const Vector &vVec) const -{ - return Vector( - m[0][0]*vVec.x + m[0][1]*vVec.y + m[0][2]*vVec.z, - m[1][0]*vVec.x + m[1][1]*vVec.y + m[1][2]*vVec.z, - m[2][0]*vVec.x + m[2][1]*vVec.y + m[2][2]*vVec.z - ); -} - -inline Vector VMatrix::VMul3x3Transpose(const Vector &vVec) const -{ - return Vector( - m[0][0]*vVec.x + m[1][0]*vVec.y + m[2][0]*vVec.z, - m[0][1]*vVec.x + m[1][1]*vVec.y + m[2][1]*vVec.z, - m[0][2]*vVec.x + m[1][2]*vVec.y + m[2][2]*vVec.z - ); -} - -#endif // VECTOR_NO_SLOW_OPERATIONS - - -inline void VMatrix::V3Mul(const Vector &vIn, Vector &vOut) const -{ - vec_t rw; - - rw = 1.0f / (m[3][0]*vIn.x + m[3][1]*vIn.y + m[3][2]*vIn.z + m[3][3]); - vOut.x = (m[0][0]*vIn.x + m[0][1]*vIn.y + m[0][2]*vIn.z + m[0][3]) * rw; - vOut.y = (m[1][0]*vIn.x + m[1][1]*vIn.y + m[1][2]*vIn.z + m[1][3]) * rw; - vOut.z = (m[2][0]*vIn.x + m[2][1]*vIn.y + m[2][2]*vIn.z + m[2][3]) * rw; -} - -inline void VMatrix::V4Mul(const Vector4D &vIn, Vector4D &vOut) const -{ - vOut[0] = m[0][0]*vIn[0] + m[0][1]*vIn[1] + m[0][2]*vIn[2] + m[0][3]*vIn[3]; - vOut[1] = m[1][0]*vIn[0] + m[1][1]*vIn[1] + m[1][2]*vIn[2] + m[1][3]*vIn[3]; - vOut[2] = m[2][0]*vIn[0] + m[2][1]*vIn[1] + m[2][2]*vIn[2] + m[2][3]*vIn[3]; - vOut[3] = m[3][0]*vIn[0] + m[3][1]*vIn[1] + m[3][2]*vIn[2] + m[3][3]*vIn[3]; -} - - -//----------------------------------------------------------------------------- -// Plane transformation -//----------------------------------------------------------------------------- -inline void VMatrix::TransformPlane( const VPlane &inPlane, VPlane &outPlane ) const -{ - Vector vTrans; - Vector3DMultiply( *this, inPlane.m_Normal, outPlane.m_Normal ); - outPlane.m_Dist = inPlane.m_Dist * DotProduct( outPlane.m_Normal, outPlane.m_Normal ); - outPlane.m_Dist += DotProduct( outPlane.m_Normal, GetTranslation( vTrans ) ); -} - - -//----------------------------------------------------------------------------- -// Other random stuff -//----------------------------------------------------------------------------- -inline void VMatrix::Identity() -{ - MatrixSetIdentity( *this ); -} - - -inline bool VMatrix::IsIdentity() const -{ - return - m[0][0] == 1.0f && m[0][1] == 0.0f && m[0][2] == 0.0f && m[0][3] == 0.0f && - m[1][0] == 0.0f && m[1][1] == 1.0f && m[1][2] == 0.0f && m[1][3] == 0.0f && - m[2][0] == 0.0f && m[2][1] == 0.0f && m[2][2] == 1.0f && m[2][3] == 0.0f && - m[3][0] == 0.0f && m[3][1] == 0.0f && m[3][2] == 0.0f && m[3][3] == 1.0f; -} - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline Vector VMatrix::ApplyRotation(const Vector &vVec) const -{ - return VMul3x3(vVec); -} - -inline VMatrix VMatrix::operator~() const -{ - VMatrix mRet; - InverseGeneral(mRet); - return mRet; -} - -#endif - - -//----------------------------------------------------------------------------- -// Accessors -//----------------------------------------------------------------------------- -inline void MatrixGetColumn( const VMatrix &src, int nCol, Vector *pColumn ) -{ - Assert( (nCol >= 0) && (nCol <= 3) ); - - pColumn->x = src[0][nCol]; - pColumn->y = src[1][nCol]; - pColumn->z = src[2][nCol]; -} - -inline void MatrixSetColumn( VMatrix &src, int nCol, const Vector &column ) -{ - Assert( (nCol >= 0) && (nCol <= 3) ); - - src.m[0][nCol] = column.x; - src.m[1][nCol] = column.y; - src.m[2][nCol] = column.z; -} - -inline void MatrixGetRow( const VMatrix &src, int nRow, Vector *pRow ) -{ - Assert( (nRow >= 0) && (nRow <= 3) ); - *pRow = *(Vector*)src[nRow]; -} - -inline void MatrixSetRow( VMatrix &dst, int nRow, const Vector &row ) -{ - Assert( (nRow >= 0) && (nRow <= 3) ); - *(Vector*)dst[nRow] = row; -} - - -//----------------------------------------------------------------------------- -// Vector3DMultiplyPosition treats src2 as if it's a point (adds the translation) -//----------------------------------------------------------------------------- -// NJS: src2 is passed in as a full vector rather than a reference to prevent the need -// for 2 branches and a potential copy in the body. (ie, handling the case when the src2 -// reference is the same as the dst reference ). -inline void Vector3DMultiplyPosition( const VMatrix& src1, const VectorByValue src2, Vector& dst ) -{ - dst[0] = src1[0][0] * src2.x + src1[0][1] * src2.y + src1[0][2] * src2.z + src1[0][3]; - dst[1] = src1[1][0] * src2.x + src1[1][1] * src2.y + src1[1][2] * src2.z + src1[1][3]; - dst[2] = src1[2][0] * src2.x + src1[2][1] * src2.y + src1[2][2] * src2.z + src1[2][3]; -} - - -//----------------------------------------------------------------------------- -// Transform a plane that has an axis-aligned normal -//----------------------------------------------------------------------------- -inline void MatrixTransformAxisAlignedPlane( const VMatrix &src, int nDim, float flSign, float flDist, cplane_t &outPlane ) -{ - // See MatrixTransformPlane in the .cpp file for an explanation of the algorithm. - MatrixGetColumn( src, nDim, &outPlane.normal ); - outPlane.normal *= flSign; - outPlane.dist = flDist * DotProduct( outPlane.normal, outPlane.normal ); - - // NOTE: Writing this out by hand because it doesn't inline (inline depth isn't large enough) - // This should read outPlane.dist += DotProduct( outPlane.normal, src.GetTranslation ); - outPlane.dist += outPlane.normal.x * src.m[0][3] + outPlane.normal.y * src.m[1][3] + outPlane.normal.z * src.m[2][3]; -} - - -//----------------------------------------------------------------------------- -// Matrix equality test -//----------------------------------------------------------------------------- -inline bool MatricesAreEqual( const VMatrix &src1, const VMatrix &src2, float flTolerance ) -{ - for ( int i = 0; i < 3; ++i ) - { - for ( int j = 0; j < 3; ++j ) - { - if ( fabs( src1[i][j] - src2[i][j] ) > flTolerance ) - return false; - } - } - return true; -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -void MatrixBuildOrtho( VMatrix& dst, double left, double top, double right, double bottom, double zNear, double zFar ); -void MatrixBuildPerspectiveX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar ); -void MatrixBuildPerspectiveOffCenterX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar, double bottom, double top, double left, double right ); - -inline void MatrixOrtho( VMatrix& dst, double left, double top, double right, double bottom, double zNear, double zFar ) -{ - VMatrix mat; - MatrixBuildOrtho( mat, left, top, right, bottom, zNear, zFar ); - - VMatrix temp; - MatrixMultiply( dst, mat, temp ); - dst = temp; -} - -inline void MatrixPerspectiveX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar ) -{ - VMatrix mat; - MatrixBuildPerspectiveX( mat, flFovX, flAspect, flZNear, flZFar ); - - VMatrix temp; - MatrixMultiply( dst, mat, temp ); - dst = temp; -} - -inline void MatrixPerspectiveOffCenterX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar, double bottom, double top, double left, double right ) -{ - VMatrix mat; - MatrixBuildPerspectiveOffCenterX( mat, flFovX, flAspect, flZNear, flZFar, bottom, top, left, right ); - - VMatrix temp; - MatrixMultiply( dst, mat, temp ); - dst = temp; -} - -#endif - - diff --git a/Resources/NetHook/mathlib/vplane.h b/Resources/NetHook/mathlib/vplane.h deleted file mode 100644 index 0e280ab2..00000000 --- a/Resources/NetHook/mathlib/vplane.h +++ /dev/null @@ -1,182 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef VPLANE_H -#define VPLANE_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "mathlib/vector.h" - -typedef int SideType; - -// Used to represent sides of things like planes. -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 - -#define VP_EPSILON 0.01f - - -class VPlane -{ -public: - VPlane(); - VPlane(const Vector &vNormal, vec_t dist); - - void Init(const Vector &vNormal, vec_t dist); - - // Return the distance from the point to the plane. - vec_t DistTo(const Vector &vVec) const; - - // Copy. - VPlane& operator=(const VPlane &thePlane); - - // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK. - // The epsilon for SIDE_ON can be passed in. - SideType GetPointSide(const Vector &vPoint, vec_t sideEpsilon=VP_EPSILON) const; - - // Returns SIDE_FRONT or SIDE_BACK. - SideType GetPointSideExact(const Vector &vPoint) const; - - // Classify the box with respect to the plane. - // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK - SideType BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const; - -#ifndef VECTOR_NO_SLOW_OPERATIONS - // Flip the plane. - VPlane Flip(); - - // Get a point on the plane (normal*dist). - Vector GetPointOnPlane() const; - - // Snap the specified point to the plane (along the plane's normal). - Vector SnapPointToPlane(const Vector &vPoint) const; -#endif - -public: - Vector m_Normal; - vec_t m_Dist; - -#ifdef VECTOR_NO_SLOW_OPERATIONS -private: - // No copy constructors allowed if we're in optimal mode - VPlane(const VPlane& vOther); -#endif -}; - - -//----------------------------------------------------------------------------- -// Inlines. -//----------------------------------------------------------------------------- -inline VPlane::VPlane() -{ -} - -inline VPlane::VPlane(const Vector &vNormal, vec_t dist) -{ - m_Normal = vNormal; - m_Dist = dist; -} - -inline void VPlane::Init(const Vector &vNormal, vec_t dist) -{ - m_Normal = vNormal; - m_Dist = dist; -} - -inline vec_t VPlane::DistTo(const Vector &vVec) const -{ - return vVec.Dot(m_Normal) - m_Dist; -} - -inline VPlane& VPlane::operator=(const VPlane &thePlane) -{ - m_Normal = thePlane.m_Normal; - m_Dist = thePlane.m_Dist; - return *this; -} - -#ifndef VECTOR_NO_SLOW_OPERATIONS - -inline VPlane VPlane::Flip() -{ - return VPlane(-m_Normal, -m_Dist); -} - -inline Vector VPlane::GetPointOnPlane() const -{ - return m_Normal * m_Dist; -} - -inline Vector VPlane::SnapPointToPlane(const Vector &vPoint) const -{ - return vPoint - m_Normal * DistTo(vPoint); -} - -#endif - -inline SideType VPlane::GetPointSide(const Vector &vPoint, vec_t sideEpsilon) const -{ - vec_t fDist; - - fDist = DistTo(vPoint); - if(fDist >= sideEpsilon) - return SIDE_FRONT; - else if(fDist <= -sideEpsilon) - return SIDE_BACK; - else - return SIDE_ON; -} - -inline SideType VPlane::GetPointSideExact(const Vector &vPoint) const -{ - return DistTo(vPoint) > 0.0f ? SIDE_FRONT : SIDE_BACK; -} - - -// BUGBUG: This should either simply use the implementation in mathlib or cease to exist. -// mathlib implementation is much more efficient. Check to see that VPlane isn't used in -// performance critical code. -inline SideType VPlane::BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const -{ - int i, firstSide, side; - TableVector vPoints[8] = - { - { vMin.x, vMin.y, vMin.z }, - { vMin.x, vMin.y, vMax.z }, - { vMin.x, vMax.y, vMax.z }, - { vMin.x, vMax.y, vMin.z }, - - { vMax.x, vMin.y, vMin.z }, - { vMax.x, vMin.y, vMax.z }, - { vMax.x, vMax.y, vMax.z }, - { vMax.x, vMax.y, vMin.z }, - }; - - firstSide = GetPointSideExact(vPoints[0]); - for(i=1; i < 8; i++) - { - side = GetPointSideExact(vPoints[i]); - - // Does the box cross the plane? - if(side != firstSide) - return SIDE_ON; - } - - // Ok, they're all on the same side, return that. - return firstSide; -} - - - - -#endif // VPLANE_H diff --git a/Resources/NetHook/public/bitvec.h b/Resources/NetHook/public/bitvec.h deleted file mode 100644 index 65d7e660..00000000 --- a/Resources/NetHook/public/bitvec.h +++ /dev/null @@ -1,1417 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#ifndef BITVEC_H -#define BITVEC_H -#ifdef _WIN32 -#pragma once -#endif - -#include -#include "tier0/dbg.h" -#include "tier0/basetypes.h" - - -class CBitVecAccessor -{ -public: - CBitVecAccessor(uint32 *pDWords, int iBit); - - void operator=(int val); - operator uint32(); - -private: - uint32 *m_pDWords; - int m_iBit; -}; - - -//----------------------------------------------------------------------------- -// Support functions -//----------------------------------------------------------------------------- - -#define LOG2_BITS_PER_INT 5 -#define BITS_PER_INT 32 - -#if _WIN32 && !defined(_X360) -#include -#pragma intrinsic(_BitScanForward) -#endif - -inline int FirstBitInWord( unsigned int elem, int offset ) -{ -#if _WIN32 - if ( !elem ) - return -1; -#if _X360 - // this implements CountTrailingZeros() / BitScanForward() - unsigned int mask = elem-1; - unsigned int comp = ~elem; - elem = mask & comp; - return (32 - _CountLeadingZeros(elem)) + offset; -#else - unsigned long out; - _BitScanForward(&out, elem); - return out + offset; -#endif - -#else - static unsigned firstBitLUT[256] = - { - 0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0, - 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0, - 3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0, - 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 - }; - unsigned elemByte; - - elemByte = (elem & 0xFF); - if ( elemByte ) - return offset + firstBitLUT[elemByte]; - - elem >>= 8; - offset += 8; - elemByte = (elem & 0xFF); - if ( elemByte ) - return offset + firstBitLUT[elemByte]; - - elem >>= 8; - offset += 8; - elemByte = (elem & 0xFF); - if ( elemByte ) - return offset + firstBitLUT[elemByte]; - - elem >>= 8; - offset += 8; - elemByte = (elem & 0xFF); - if ( elemByte ) - return offset + firstBitLUT[elemByte]; - - return -1; -#endif -} - -//------------------------------------- - -inline unsigned GetEndMask( int numBits ) -{ - static unsigned bitStringEndMasks[] = - { - 0xffffffff, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000f, - 0x0000001f, - 0x0000003f, - 0x0000007f, - 0x000000ff, - 0x000001ff, - 0x000003ff, - 0x000007ff, - 0x00000fff, - 0x00001fff, - 0x00003fff, - 0x00007fff, - 0x0000ffff, - 0x0001ffff, - 0x0003ffff, - 0x0007ffff, - 0x000fffff, - 0x001fffff, - 0x003fffff, - 0x007fffff, - 0x00ffffff, - 0x01ffffff, - 0x03ffffff, - 0x07ffffff, - 0x0fffffff, - 0x1fffffff, - 0x3fffffff, - 0x7fffffff, - }; - - return bitStringEndMasks[numBits % BITS_PER_INT]; -} - - -inline int GetBitForBitnum( int bitNum ) -{ - static int bitsForBitnum[] = - { - ( 1 << 0 ), - ( 1 << 1 ), - ( 1 << 2 ), - ( 1 << 3 ), - ( 1 << 4 ), - ( 1 << 5 ), - ( 1 << 6 ), - ( 1 << 7 ), - ( 1 << 8 ), - ( 1 << 9 ), - ( 1 << 10 ), - ( 1 << 11 ), - ( 1 << 12 ), - ( 1 << 13 ), - ( 1 << 14 ), - ( 1 << 15 ), - ( 1 << 16 ), - ( 1 << 17 ), - ( 1 << 18 ), - ( 1 << 19 ), - ( 1 << 20 ), - ( 1 << 21 ), - ( 1 << 22 ), - ( 1 << 23 ), - ( 1 << 24 ), - ( 1 << 25 ), - ( 1 << 26 ), - ( 1 << 27 ), - ( 1 << 28 ), - ( 1 << 29 ), - ( 1 << 30 ), - ( 1 << 31 ), - }; - - return bitsForBitnum[ (bitNum) & (BITS_PER_INT-1) ]; -} - -inline int GetBitForBitnumByte( int bitNum ) -{ - static int bitsForBitnum[] = - { - ( 1 << 0 ), - ( 1 << 1 ), - ( 1 << 2 ), - ( 1 << 3 ), - ( 1 << 4 ), - ( 1 << 5 ), - ( 1 << 6 ), - ( 1 << 7 ), - }; - - return bitsForBitnum[ bitNum & 7 ]; -} - -inline int CalcNumIntsForBits( int numBits ) { return (numBits + (BITS_PER_INT-1)) / BITS_PER_INT; } - -#ifdef _X360 -#define BitVec_Bit( bitNum ) GetBitForBitnum( bitNum ) -#define BitVec_BitInByte( bitNum ) GetBitForBitnumByte( bitNum ) -#else -#define BitVec_Bit( bitNum ) ( 1 << ( (bitNum) & (BITS_PER_INT-1) ) ) -#define BitVec_BitInByte( bitNum ) ( 1 << ( (bitNum) & 7 ) ) -#endif -#define BitVec_Int( bitNum ) ( (bitNum) >> LOG2_BITS_PER_INT ) - - -//----------------------------------------------------------------------------- -// template CBitVecT -// -// Defines the operations relevant to any bit array. Simply requires a base -// class that implements GetNumBits(), Base(), GetNumDWords() & ValidateOperand() -// -// CVarBitVec and CBitVec are the actual classes generally used -// by clients -// - -template -class CBitVecT : public BASE_OPS -{ -public: - CBitVecT(); - CBitVecT(int numBits); // Must be initialized with the number of bits - - void Init(int val = 0); - - // Access the bits like an array. - CBitVecAccessor operator[](int i); - - // Do NOT override bitwise operators (see note in header) - void And(const CBitVecT &andStr, CBitVecT *out) const; - void Or(const CBitVecT &orStr, CBitVecT *out) const; - void Xor(const CBitVecT &orStr, CBitVecT *out) const; - - void Not(CBitVecT *out) const; - - void CopyTo(CBitVecT *out) const; - void Copy( const CBitVecT &other, int nBits=-1 ); - bool Compare( const CBitVecT &other, int nBits=-1 ) const; - - bool IsAllClear(void) const; // Are all bits zero? - bool IsAllSet(void) const; // Are all bits one? - - uint32 Get( uint32 bitNum ) const; - bool IsBitSet( int bitNum ) const; - void Set( int bitNum ); - void Set( int bitNum, bool bNewVal ); - void Clear(int bitNum); - - bool TestAndSet(int bitNum); - - void Set( uint32 offset, uint32 mask ); - void Clear( uint32 offset, uint32 mask ); - uint32 Get( uint32 offset, uint32 mask ); - - void SetAll(void); // Sets all bits - void ClearAll(void); // Clears all bits - - uint32 GetDWord(int i) const; - void SetDWord(int i, uint32 val); - - CBitVecT& operator=(const CBitVecT &other) { other.CopyTo( this ); return *this; } - bool operator==(const CBitVecT &other) { return Compare( other ); } - bool operator!=(const CBitVecT &other) { return !operator==( other ); } - - static void GetOffsetMaskForBit( uint32 bitNum, uint32 *pOffset, uint32 *pMask ) { *pOffset = BitVec_Int( bitNum ); *pMask = BitVec_Bit( bitNum ); } -}; - -//----------------------------------------------------------------------------- -// class CVarBitVecBase -// -// Defines the operations necessary for a variable sized bit array - -class CVarBitVecBase -{ -public: - bool IsFixedSize() const { return false; } - int GetNumBits(void) const { return m_numBits; } - void Resize( int numBits, bool bClearAll = false ); // resizes bit array - - int GetNumDWords() const { return m_numInts; } - uint32 *Base() { return m_pInt; } - const uint32 *Base() const { return m_pInt; } - - void Attach( uint32 *pBits, int numBits ); - bool Detach( uint32 **ppBits, int *pNumBits ); - - int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found - -protected: - CVarBitVecBase(); - CVarBitVecBase(int numBits); - CVarBitVecBase( const CVarBitVecBase &from ); - CVarBitVecBase &operator=( const CVarBitVecBase &from ); - ~CVarBitVecBase(void); - - void ValidateOperand( const CVarBitVecBase &operand ) const { Assert(GetNumBits() == operand.GetNumBits()); } - - unsigned GetEndMask() const { return ::GetEndMask( GetNumBits() ); } - -private: - - unsigned short m_numBits; // Number of bits in the bitstring - unsigned short m_numInts; // Number of ints to needed to store bitstring - uint32 m_iBitStringStorage; // If the bit string fits in one int, it goes here - uint32 * m_pInt; // Array of ints containing the bitstring - - void AllocInts( int numInts ); // Free the allocated bits - void ReallocInts( int numInts ); - void FreeInts( void ); // Free the allocated bits -}; - -//----------------------------------------------------------------------------- -// class CFixedBitVecBase -// -// Defines the operations necessary for a fixed sized bit array. -// - -template struct BitCountToEndMask_t { }; -template <> struct BitCountToEndMask_t< 0> { enum { MASK = 0xffffffff }; }; -template <> struct BitCountToEndMask_t< 1> { enum { MASK = 0x00000001 }; }; -template <> struct BitCountToEndMask_t< 2> { enum { MASK = 0x00000003 }; }; -template <> struct BitCountToEndMask_t< 3> { enum { MASK = 0x00000007 }; }; -template <> struct BitCountToEndMask_t< 4> { enum { MASK = 0x0000000f }; }; -template <> struct BitCountToEndMask_t< 5> { enum { MASK = 0x0000001f }; }; -template <> struct BitCountToEndMask_t< 6> { enum { MASK = 0x0000003f }; }; -template <> struct BitCountToEndMask_t< 7> { enum { MASK = 0x0000007f }; }; -template <> struct BitCountToEndMask_t< 8> { enum { MASK = 0x000000ff }; }; -template <> struct BitCountToEndMask_t< 9> { enum { MASK = 0x000001ff }; }; -template <> struct BitCountToEndMask_t<10> { enum { MASK = 0x000003ff }; }; -template <> struct BitCountToEndMask_t<11> { enum { MASK = 0x000007ff }; }; -template <> struct BitCountToEndMask_t<12> { enum { MASK = 0x00000fff }; }; -template <> struct BitCountToEndMask_t<13> { enum { MASK = 0x00001fff }; }; -template <> struct BitCountToEndMask_t<14> { enum { MASK = 0x00003fff }; }; -template <> struct BitCountToEndMask_t<15> { enum { MASK = 0x00007fff }; }; -template <> struct BitCountToEndMask_t<16> { enum { MASK = 0x0000ffff }; }; -template <> struct BitCountToEndMask_t<17> { enum { MASK = 0x0001ffff }; }; -template <> struct BitCountToEndMask_t<18> { enum { MASK = 0x0003ffff }; }; -template <> struct BitCountToEndMask_t<19> { enum { MASK = 0x0007ffff }; }; -template <> struct BitCountToEndMask_t<20> { enum { MASK = 0x000fffff }; }; -template <> struct BitCountToEndMask_t<21> { enum { MASK = 0x001fffff }; }; -template <> struct BitCountToEndMask_t<22> { enum { MASK = 0x003fffff }; }; -template <> struct BitCountToEndMask_t<23> { enum { MASK = 0x007fffff }; }; -template <> struct BitCountToEndMask_t<24> { enum { MASK = 0x00ffffff }; }; -template <> struct BitCountToEndMask_t<25> { enum { MASK = 0x01ffffff }; }; -template <> struct BitCountToEndMask_t<26> { enum { MASK = 0x03ffffff }; }; -template <> struct BitCountToEndMask_t<27> { enum { MASK = 0x07ffffff }; }; -template <> struct BitCountToEndMask_t<28> { enum { MASK = 0x0fffffff }; }; -template <> struct BitCountToEndMask_t<29> { enum { MASK = 0x1fffffff }; }; -template <> struct BitCountToEndMask_t<30> { enum { MASK = 0x3fffffff }; }; -template <> struct BitCountToEndMask_t<31> { enum { MASK = 0x7fffffff }; }; - -//------------------------------------- - -template -class CFixedBitVecBase -{ -public: - bool IsFixedSize() const { return true; } - int GetNumBits(void) const { return NUM_BITS; } - void Resize( int numBits, bool bClearAll = false ) { Assert(numBits == NUM_BITS); if ( bClearAll ) memset( m_Ints, 0, NUM_INTS * sizeof(uint32) ); }// for syntatic consistency (for when using templates) - - int GetNumDWords() const { return NUM_INTS; } - uint32 * Base() { return m_Ints; } - const uint32 * Base() const { return m_Ints; } - - int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found - -protected: - CFixedBitVecBase() {} - CFixedBitVecBase(int numBits) { Assert( numBits == NUM_BITS ); } // doesn't make sense, really. Supported to simplify templates & allow easy replacement of variable - - void ValidateOperand( const CFixedBitVecBase &operand ) const { } // no need, compiler does so statically - -public: // for test code - unsigned GetEndMask() const { return static_cast( BitCountToEndMask_t::MASK ); } - -private: - enum - { - NUM_INTS = (NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT - }; - - uint32 m_Ints[(NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT]; -}; - -//----------------------------------------------------------------------------- -// -// The actual classes used -// - -// inheritance instead of typedef to allow forward declarations -class CVarBitVec : public CBitVecT -{ -public: - CVarBitVec() - { - } - - CVarBitVec(int numBits) - : CBitVecT(numBits) - { - } -}; - -//----------------------------------------------------------------------------- - -template < int NUM_BITS > -class CBitVec : public CBitVecT< CFixedBitVecBase > -{ -public: - CBitVec() - { - } - - CBitVec(int numBits) - : CBitVecT< CFixedBitVecBase >(numBits) - { - } -}; - - -//----------------------------------------------------------------------------- - -typedef CBitVec<32> CDWordBitVec; - -//----------------------------------------------------------------------------- - -inline CVarBitVecBase::CVarBitVecBase() -{ - memset( this, 0, sizeof( *this ) ); -} - -//----------------------------------------------------------------------------- - -inline CVarBitVecBase::CVarBitVecBase(int numBits) -{ - Assert( numBits ); - m_numBits = numBits; - - // Figure out how many ints are needed - m_numInts = CalcNumIntsForBits( numBits ); - m_pInt = NULL; - AllocInts( m_numInts ); -} - -//----------------------------------------------------------------------------- - -inline CVarBitVecBase::CVarBitVecBase( const CVarBitVecBase &from ) -{ - if ( from.m_numInts ) - { - m_numBits = from.m_numBits; - m_numInts = from.m_numInts; - m_pInt = NULL; - AllocInts( m_numInts ); - memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) ); - } - else - memset( this, 0, sizeof( *this ) ); -} - -//----------------------------------------------------------------------------- - -inline CVarBitVecBase &CVarBitVecBase::operator=( const CVarBitVecBase &from ) -{ - Resize( from.GetNumBits() ); - if ( m_pInt ) - memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) ); - return (*this); -} - -//----------------------------------------------------------------------------- -// Purpose: Destructor -// Input : -// Output : -//----------------------------------------------------------------------------- - -inline CVarBitVecBase::~CVarBitVecBase(void) -{ - FreeInts(); -} - -//----------------------------------------------------------------------------- - -inline void CVarBitVecBase::Attach( uint32 *pBits, int numBits ) -{ - FreeInts(); - m_numBits = numBits; - m_numInts = CalcNumIntsForBits( numBits ); - if ( m_numInts > 1 ) - { - m_pInt = pBits; - } - else - { - m_iBitStringStorage = *pBits; - m_pInt = &m_iBitStringStorage; - free( pBits ); - } -} - -//----------------------------------------------------------------------------- - -inline bool CVarBitVecBase::Detach( uint32 **ppBits, int *pNumBits ) -{ - if ( !m_numBits ) - { - return false; - } - - *pNumBits = m_numBits; - if ( m_numInts > 1 ) - { - *ppBits = m_pInt; - } - else - { - *ppBits = (uint32 *)malloc( sizeof(uint32) ); - **ppBits = m_iBitStringStorage; - free( m_pInt ); - } - - memset( this, 0, sizeof( *this ) ); - return true; -} - -//----------------------------------------------------------------------------- - -template -inline CBitVecT::CBitVecT() -{ - // undef this is ints are not 4 bytes - // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler) - - COMPILE_TIME_ASSERT( sizeof(int)==4 ); - - // Initialize bitstring by clearing all bits - ClearAll(); -} - -//----------------------------------------------------------------------------- -template -inline CBitVecT::CBitVecT(int numBits) - : BASE_OPS( numBits ) -{ - // undef this is ints are not 4 bytes - // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler) - - COMPILE_TIME_ASSERT( sizeof(int)==4 ); - - // Initialize bitstring by clearing all bits - ClearAll(); -} - -//----------------------------------------------------------------------------- - -template -inline CBitVecAccessor CBitVecT::operator[](int i) -{ - Assert(i >= 0 && i < GetNumBits()); - return CBitVecAccessor(Base(), i); -} - - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Init( int val ) -{ - if ( Base() ) - memset( Base(), ( val ) ? 0xff : 0, GetNumDWords() * sizeof(int) ); -} - -//----------------------------------------------------------------------------- - -template -inline uint32 CBitVecT::Get( uint32 bitNum ) const -{ - Assert( bitNum < (uint32)GetNumBits() ); - const uint32 *pInt = Base() + BitVec_Int( bitNum ); - return ( *pInt & BitVec_Bit( bitNum ) ); -} - -//----------------------------------------------------------------------------- - -template -inline bool CBitVecT::IsBitSet( int bitNum ) const -{ - Assert( bitNum >= 0 && bitNum < GetNumBits() ); - const uint32 *pInt = Base() + BitVec_Int( bitNum ); - return ( ( *pInt & BitVec_Bit( bitNum ) ) != 0 ); -} - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Set( int bitNum ) -{ - Assert( bitNum >= 0 && bitNum < GetNumBits() ); - uint32 *pInt = Base() + BitVec_Int( bitNum ); - *pInt |= BitVec_Bit( bitNum ); -} - -//----------------------------------------------------------------------------- - -template -inline bool CBitVecT::TestAndSet(int bitNum) -{ - Assert( bitNum >= 0 && bitNum < GetNumBits() ); - uint32 bitVecBit = BitVec_Bit( bitNum ); - uint32 *pInt = Base() + BitVec_Int( bitNum ); - bool bResult = ( ( *pInt & bitVecBit) != 0 ); - *pInt |= bitVecBit; - return bResult; -} - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Clear(int bitNum) -{ - Assert( bitNum >= 0 && bitNum < GetNumBits() ); - uint32 *pInt = Base() + BitVec_Int( bitNum ); - *pInt &= ~BitVec_Bit( bitNum ); -} - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Set( int bitNum, bool bNewVal ) -{ - uint32 *pInt = Base() + BitVec_Int( bitNum ); - uint32 bitMask = BitVec_Bit( bitNum ); - if ( bNewVal ) - { - *pInt |= bitMask; - } - else - { - *pInt &= ~bitMask; - } -} - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Set( uint32 offset, uint32 mask ) -{ - uint32 *pInt = Base() + offset; - *pInt |= mask; -} - -//----------------------------------------------------------------------------- - -template -inline void CBitVecT::Clear( uint32 offset, uint32 mask ) -{ - uint32 *pInt = Base() + offset; - *pInt &= ~mask; -} - -//----------------------------------------------------------------------------- - -template -inline uint32 CBitVecT::Get( uint32 offset, uint32 mask ) -{ - uint32 *pInt = Base() + offset; - return ( *pInt & mask ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::And(const CBitVecT &addStr, CBitVecT *out) const -{ - ValidateOperand( addStr ); - ValidateOperand( *out ); - - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - for (int i = GetNumDWords() - 1; i >= 0 ; --i) - { - pDest[i] = pOperand1[i] & pOperand2[i]; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::Or(const CBitVecT &orStr, CBitVecT *out) const -{ - ValidateOperand( orStr ); - ValidateOperand( *out ); - - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = orStr.Base(); - - for (int i = GetNumDWords() - 1; i >= 0; --i) - { - pDest[i] = pOperand1[i] | pOperand2[i]; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::Xor(const CBitVecT &xorStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = xorStr.Base(); - - for (int i = GetNumDWords() - 1; i >= 0; --i) - { - pDest[i] = pOperand1[i] ^ pOperand2[i]; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::Not(CBitVecT *out) const -{ - ValidateOperand( *out ); - - uint32 * pDest = out->Base(); - const uint32 *pOperand = Base(); - - for (int i = GetNumDWords() - 1; i >= 0; --i) - { - pDest[i] = ~(pOperand[i]); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Copy a bit string -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::CopyTo(CBitVecT *out) const -{ - out->Resize( GetNumBits() ); - - ValidateOperand( *out ); - Assert( out != this ); - - memcpy( out->Base(), Base(), GetNumDWords() * sizeof( int ) ); -} - -//----------------------------------------------------------------------------- -// Purpose: Are all bits zero? -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline bool CBitVecT::IsAllClear(void) const -{ - // Number of available bits may be more than the number - // actually used, so make sure to mask out unused bits - // before testing for zero - (const_cast(this))->Base()[GetNumDWords()-1] &= CBitVecT::GetEndMask(); // external semantics of const retained - - for (int i = GetNumDWords() - 1; i >= 0; --i) - { - if ( Base()[i] !=0 ) - { - return false; - } - } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Are all bits set? -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline bool CBitVecT::IsAllSet(void) const -{ - // Number of available bits may be more than the number - // actually used, so make sure to mask out unused bits - // before testing for set bits - (const_cast(this))->Base()[GetNumDWords()-1] |= ~CBitVecT::GetEndMask(); // external semantics of const retained - - for (int i = GetNumDWords() - 1; i >= 0; --i) - { - if ( Base()[i] != ~0 ) - { - return false; - } - } - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets all bits -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::SetAll(void) -{ - if ( Base() ) - memset( Base(), 0xff, GetNumDWords() * sizeof(int) ); -} - -//----------------------------------------------------------------------------- -// Purpose: Clears all bits -// Input : -// Output : -//----------------------------------------------------------------------------- -template -inline void CBitVecT::ClearAll(void) -{ - if ( Base() ) - memset( Base(), 0, GetNumDWords() * sizeof(int) ); -} - -//----------------------------------------------------------------------------- -template -inline void CBitVecT::Copy( const CBitVecT &other, int nBits=-1 ) -{ - if ( nBits == - 1 ) - { - nBits = other.GetNumBits(); - } - - Resize( nBits ); - - ValidateOperand( other ); - Assert( &other != this ); - - memcpy( Base(), other.Base(), GetNumDWords() * sizeof( uint32 ) ); -} - -//----------------------------------------------------------------------------- -template -inline bool CBitVecT::Compare( const CBitVecT &other, int nBits=-1 ) const -{ - if ( nBits == - 1 ) - { - if ( other.GetNumBits() != GetNumBits() ) - { - return false; - } - - nBits = other.GetNumBits(); - } - - if ( nBits > other.GetNumBits() || nBits > GetNumBits() ) - { - return false; - } - - (const_cast(this))->Base()[GetNumDWords()-1] &= CBitVecT::GetEndMask(); // external semantics of const retained - (const_cast(&other))->Base()[GetNumDWords()-1] &= other.CBitVecT::GetEndMask(); // external semantics of const retained - - int nBytes = PAD_NUMBER( nBits, 8 ) >> 3; - - return ( memcmp( Base(), other.Base(), nBytes ) == 0 ); -} - -//----------------------------------------------------------------------------- -template -inline uint32 CBitVecT::GetDWord(int i) const -{ - Assert(i >= 0 && i < GetNumDWords()); - return Base()[i]; -} - -//----------------------------------------------------------------------------- -template -inline void CBitVecT::SetDWord(int i, uint32 val) -{ - Assert(i >= 0 && i < GetNumDWords()); - Base()[i] = val; -} - -//----------------------------------------------------------------------------- - -inline unsigned GetStartBitMask( int startBit ) -{ - static unsigned int g_StartMask[32] = - { - 0xffffffff, - 0xfffffffe, - 0xfffffffc, - 0xfffffff8, - 0xfffffff0, - 0xffffffe0, - 0xffffffc0, - 0xffffff80, - 0xffffff00, - 0xfffffe00, - 0xfffffc00, - 0xfffff800, - 0xfffff000, - 0xffffe000, - 0xffffc000, - 0xffff8000, - 0xffff0000, - 0xfffe0000, - 0xfffc0000, - 0xfff80000, - 0xfff00000, - 0xffe00000, - 0xffc00000, - 0xff800000, - 0xff000000, - 0xfe000000, - 0xfc000000, - 0xf8000000, - 0xf0000000, - 0xe0000000, - 0xc0000000, - 0x80000000, - }; - - return g_StartMask[ startBit & 31 ]; -} - -inline int CVarBitVecBase::FindNextSetBit( int startBit ) const -{ - if ( startBit < GetNumBits() ) - { - int wordIndex = BitVec_Int(startBit); - unsigned int startMask = GetStartBitMask( startBit ); - int lastWord = GetNumDWords()-1; - - // handle non dword lengths - if ( (GetNumBits() % BITS_PER_INT) != 0 ) - { - unsigned int elem = Base()[wordIndex]; - elem &= startMask; - if ( wordIndex == lastWord) - { - elem &= (GetEndMask()); - // there's a bit remaining in this word - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - } - else - { - // there's a bit remaining in this word - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - - // iterate the words - for ( int i = wordIndex+1; i < lastWord; i++ ) - { - elem = Base()[i]; - if ( elem ) - return FirstBitInWord(elem, i << 5); - } - elem = Base()[lastWord] & GetEndMask(); - if ( elem ) - return FirstBitInWord(elem, lastWord << 5); - } - } - else - { - const uint32 * RESTRICT pCurElem = Base() + wordIndex; - unsigned int elem = *pCurElem; - elem &= startMask; - do - { - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - ++pCurElem; - elem = *pCurElem; - ++wordIndex; - } while( wordIndex <= lastWord ); - } - - } - - return -1; -} - -template -inline int CFixedBitVecBase::FindNextSetBit( int startBit ) const -{ - if ( startBit < NUM_BITS ) - { - int wordIndex = BitVec_Int(startBit); - unsigned int startMask = GetStartBitMask( startBit ); - - // handle non dword lengths - if ( (NUM_BITS % BITS_PER_INT) != 0 ) - { - unsigned int elem = Base()[wordIndex]; - elem &= startMask; - if ( wordIndex == NUM_INTS-1) - { - elem &= (GetEndMask()); - // there's a bit remaining in this word - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - } - else - { - // there's a bit remaining in this word - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - - // iterate the words - for ( int i = wordIndex+1; i < NUM_INTS-1; i++ ) - { - elem = Base()[i]; - if ( elem ) - return FirstBitInWord(elem, i << 5); - } - elem = Base()[NUM_INTS-1] & GetEndMask(); - if ( elem ) - return FirstBitInWord(elem, (NUM_INTS-1) << 5); - } - } - else - { - const uint32 * RESTRICT pCurElem = Base() + wordIndex; - unsigned int elem = *pCurElem; - elem &= startMask; - do - { - if ( elem ) - return FirstBitInWord(elem, wordIndex << 5); - ++pCurElem; - elem = *pCurElem; - ++wordIndex; - } while( wordIndex <= NUM_INTS-1); - } - - } - - return -1; -} - -//----------------------------------------------------------------------------- -// Unrolled loops for some common sizes - -template<> -FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::And(const CBitVecT &addStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - pDest[0] = pOperand1[0] & pOperand2[0]; - pDest[1] = pOperand1[1] & pOperand2[1]; - pDest[2] = pOperand1[2] & pOperand2[2]; - pDest[3] = pOperand1[3] & pOperand2[3]; - pDest[4] = pOperand1[4] & pOperand2[4]; - pDest[5] = pOperand1[5] & pOperand2[5]; - pDest[6] = pOperand1[6] & pOperand2[6]; - pDest[7] = pOperand1[7] & pOperand2[7]; -} - -template<> -FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<256> >::IsAllClear(void) const -{ - const uint32 *pInts = Base(); - return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 && pInts[4] == 0 && pInts[5] == 0 && pInts[6] == 0 && pInts[7] == 0 ); -} - -template<> -FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::CopyTo(CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pInts = Base(); - - pDest[0] = pInts[0]; - pDest[1] = pInts[1]; - pDest[2] = pInts[2]; - pDest[3] = pInts[3]; - pDest[4] = pInts[4]; - pDest[5] = pInts[5]; - pDest[6] = pInts[6]; - pDest[7] = pInts[7]; -} - -template<> -FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::And(const CBitVecT &addStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - pDest[0] = pOperand1[0] & pOperand2[0]; - pDest[1] = pOperand1[1] & pOperand2[1]; - pDest[2] = pOperand1[2] & pOperand2[2]; - pDest[3] = pOperand1[3] & pOperand2[3]; -} - -template<> -FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<128> >::IsAllClear(void) const -{ - const uint32 *pInts = Base(); - return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 ); -} - -template<> -FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::CopyTo(CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pInts = Base(); - - pDest[0] = pInts[0]; - pDest[1] = pInts[1]; - pDest[2] = pInts[2]; - pDest[3] = pInts[3]; -} - -template<> -inline void CBitVecT< CFixedBitVecBase<96> >::And(const CBitVecT &addStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - pDest[0] = pOperand1[0] & pOperand2[0]; - pDest[1] = pOperand1[1] & pOperand2[1]; - pDest[2] = pOperand1[2] & pOperand2[2]; -} - -template<> -inline bool CBitVecT< CFixedBitVecBase<96> >::IsAllClear(void) const -{ - const uint32 *pInts = Base(); - return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 ); -} - -template<> -inline void CBitVecT< CFixedBitVecBase<96> >::CopyTo(CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pInts = Base(); - - pDest[0] = pInts[0]; - pDest[1] = pInts[1]; - pDest[2] = pInts[2]; -} - -template<> -inline void CBitVecT< CFixedBitVecBase<64> >::And(const CBitVecT &addStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - pDest[0] = pOperand1[0] & pOperand2[0]; - pDest[1] = pOperand1[1] & pOperand2[1]; -} - -template<> -inline bool CBitVecT< CFixedBitVecBase<64> >::IsAllClear(void) const -{ - const uint32 *pInts = Base(); - return ( pInts[0] == 0 && pInts[1] == 0 ); -} - -template<> -inline void CBitVecT< CFixedBitVecBase<64> >::CopyTo(CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pInts = Base(); - - pDest[0] = pInts[0]; - pDest[1] = pInts[1]; -} - -template<> -inline void CBitVecT< CFixedBitVecBase<32> >::And(const CBitVecT &addStr, CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pOperand1 = Base(); - const uint32 *pOperand2 = addStr.Base(); - - pDest[0] = pOperand1[0] & pOperand2[0]; -} - -template<> -inline bool CBitVecT< CFixedBitVecBase<32> >::IsAllClear(void) const -{ - const uint32 *pInts = Base(); - - return ( pInts[0] == 0 ); -} - -template<> -inline void CBitVecT< CFixedBitVecBase<32> >::CopyTo(CBitVecT *out) const -{ - uint32 * pDest = out->Base(); - const uint32 *pInts = Base(); - - pDest[0] = pInts[0]; -} - -//----------------------------------------------------------------------------- - -template <> -inline uint32 CBitVecT< CFixedBitVecBase<32> >::Get( uint32 bitNum ) const -{ - return ( *Base() & BitVec_Bit( bitNum ) ); -} - -//----------------------------------------------------------------------------- - -template <> -inline bool CBitVecT< CFixedBitVecBase<32> >::IsBitSet( int bitNum ) const -{ - return ( ( *Base() & BitVec_Bit( bitNum ) ) != 0 ); -} - -//----------------------------------------------------------------------------- - -template <> -inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum ) -{ - *Base() |= BitVec_Bit( bitNum ); -} - -//----------------------------------------------------------------------------- - -template <> -inline void CBitVecT< CFixedBitVecBase<32> >::Clear(int bitNum) -{ - *Base() &= ~BitVec_Bit( bitNum ); -} - -//----------------------------------------------------------------------------- - -template <> -inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum, bool bNewVal ) -{ - uint32 bitMask = BitVec_Bit( bitNum ); - if ( bNewVal ) - { - *Base() |= bitMask; - } - else - { - *Base() &= ~bitMask; - } -} - - -//----------------------------------------------------------------------------- - -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Purpose: Resizes the bit string to a new number of bits -// Input : resizeNumBits - -//----------------------------------------------------------------------------- -inline void CVarBitVecBase::Resize( int resizeNumBits, bool bClearAll ) -{ - Assert( resizeNumBits >= 0 && resizeNumBits <= USHRT_MAX ); - - int newIntCount = CalcNumIntsForBits( resizeNumBits ); - if ( newIntCount != GetNumDWords() ) - { - if ( Base() ) - { - ReallocInts( newIntCount ); - if ( !bClearAll && resizeNumBits >= GetNumBits() ) - { - Base()[GetNumDWords() - 1] &= GetEndMask(); - memset( Base() + GetNumDWords(), 0, (newIntCount - GetNumDWords()) * sizeof(int) ); - } - } - else - { - // Figure out how many ints are needed - AllocInts( newIntCount ); - // Initialize bitstring by clearing all bits - bClearAll = true; - } - - m_numInts = newIntCount; - } - else if ( !bClearAll && resizeNumBits >= GetNumBits() && Base() ) - { - Base()[GetNumDWords() - 1] &= GetEndMask(); - } - - if ( bClearAll && Base() ) - { - memset( Base(), 0, newIntCount * sizeof(int) ); - } - - // store the new size and end mask - m_numBits = resizeNumBits; -} - -//----------------------------------------------------------------------------- -// Purpose: Allocate the storage for the ints -// Input : numInts - -//----------------------------------------------------------------------------- -inline void CVarBitVecBase::AllocInts( int numInts ) -{ - Assert( !m_pInt ); - - if ( numInts == 0 ) - return; - - if ( numInts == 1 ) - { - m_pInt = &m_iBitStringStorage; - return; - } - - m_pInt = (uint32 *)malloc( numInts * sizeof(int) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Reallocate the storage for the ints -// Input : numInts - -//----------------------------------------------------------------------------- -inline void CVarBitVecBase::ReallocInts( int numInts ) -{ - Assert( Base() ); - if ( numInts == 0) - { - FreeInts(); - return; - } - - if ( m_pInt == &m_iBitStringStorage ) - { - if ( numInts != 1 ) - { - m_pInt = ((uint32 *)malloc( numInts * sizeof(int) )); - *m_pInt = m_iBitStringStorage; - } - - return; - } - - if ( numInts == 1 ) - { - m_iBitStringStorage = *m_pInt; - free( m_pInt ); - m_pInt = &m_iBitStringStorage; - return; - } - - m_pInt = (uint32 *)realloc( m_pInt, numInts * sizeof(int) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Free storage allocated with AllocInts -//----------------------------------------------------------------------------- -inline void CVarBitVecBase::FreeInts( void ) -{ - if ( m_numInts > 1 ) - { - free( m_pInt ); - } - m_pInt = NULL; -} - -#include "tier0/memdbgoff.h" - -// ------------------------------------------------------------------------ // -// CBitVecAccessor inlines. -// ------------------------------------------------------------------------ // - -inline CBitVecAccessor::CBitVecAccessor(uint32 *pDWords, int iBit) -{ - m_pDWords = pDWords; - m_iBit = iBit; -} - - -inline void CBitVecAccessor::operator=(int val) -{ - if(val) - m_pDWords[m_iBit >> 5] |= (1 << (m_iBit & 31)); - else - m_pDWords[m_iBit >> 5] &= ~(unsigned long)(1 << (m_iBit & 31)); -} - -inline CBitVecAccessor::operator uint32() -{ - return m_pDWords[m_iBit >> 5] & (1 << (m_iBit & 31)); -} - - -//============================================================================= - -#endif // BITVEC_H diff --git a/Resources/NetHook/public/coordsize.h b/Resources/NetHook/public/coordsize.h deleted file mode 100644 index 95e02a29..00000000 --- a/Resources/NetHook/public/coordsize.h +++ /dev/null @@ -1,98 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef COORDSIZE_H -#define COORDSIZE_H -#pragma once - -#include "worldsize.h" - -// OVERALL Coordinate Size Limits used in COMMON.C MSG_*BitCoord() Routines (and someday the HUD) -#define COORD_INTEGER_BITS 14 -#define COORD_FRACTIONAL_BITS 5 -#define COORD_DENOMINATOR (1<<(COORD_FRACTIONAL_BITS)) -#define COORD_RESOLUTION (1.0/(COORD_DENOMINATOR)) - -// Special threshold for networking multiplayer origins -#define COORD_INTEGER_BITS_MP 11 -#define COORD_FRACTIONAL_BITS_MP_LOWPRECISION 3 -#define COORD_DENOMINATOR_LOWPRECISION (1<<(COORD_FRACTIONAL_BITS_MP_LOWPRECISION)) -#define COORD_RESOLUTION_LOWPRECISION (1.0/(COORD_DENOMINATOR_LOWPRECISION)) - -#define NORMAL_FRACTIONAL_BITS 11 -#define NORMAL_DENOMINATOR ( (1<<(NORMAL_FRACTIONAL_BITS)) - 1 ) -#define NORMAL_RESOLUTION (1.0/(NORMAL_DENOMINATOR)) - -// this is limited by the network fractional bits used for coords -// because net coords will be only be accurate to 5 bits fractional -// Standard collision test epsilon -// 1/32nd inch collision epsilon -#define DIST_EPSILON (0.03125) - -// Verify that coordsize.h and worldsize.h are consistently defined -#if (MAX_COORD_INTEGER != (1<=MIN_COORD_INTEGER*2) && (v.x<=MAX_COORD_INTEGER*2) && \ - (v.y>=MIN_COORD_INTEGER*2) && (v.y<=MAX_COORD_INTEGER*2) && \ - (v.z>=MIN_COORD_INTEGER*2) && (v.z<=MAX_COORD_INTEGER*2) ); \ - - -#endif // WORLDSIZE_H \ No newline at end of file diff --git a/Resources/NetHook/sigscan.cpp b/Resources/NetHook/sigscan.cpp deleted file mode 100644 index d574b02b..00000000 --- a/Resources/NetHook/sigscan.cpp +++ /dev/null @@ -1,124 +0,0 @@ - -#include "sigscan.h" - -/* There is no ANSI ustrncpy */ -unsigned char* ustrncpy(unsigned char *dest, const unsigned char *src, int len) { - while(len--) - dest[len] = src[len]; - - return dest; -} - -/* ////////////////////////////////////// - CSigScan Class - ////////////////////////////////////// */ -unsigned char* CSigScan::base_addr; -size_t CSigScan::base_len; -void *(*CSigScan::sigscan_dllfunc)(const char *pName, int *pReturnCode); - -/* Initialize the Signature Object */ -int CSigScan::Init(unsigned char *sig, char *mask, size_t len) { - is_set = 0; - - sig_len = len; - - if ( sig_str ) - delete[] sig_str; - - sig_str = new unsigned char[sig_len]; - ustrncpy(sig_str, sig, sig_len); - - if ( sig_mask ) - delete[] sig_mask; - - sig_mask = new char[sig_len/*+1*/]; - strncpy(sig_mask, mask, sig_len); - //sig_mask[sig_len+1] = 0; - - if(!base_addr) - return 2; // GetDllMemInfo() Failed - - if((sig_addr = FindSignature()) == NULL) - return 1; // FindSignature() Failed - - is_set = 1; - // SigScan Successful! - - return 0; -} - -/* Destructor frees sig-string allocated memory */ -CSigScan::~CSigScan(void) { - delete[] sig_str; - delete[] sig_mask; -} - -/* Get base address of the server module (base_addr) and get its ending offset (base_len) */ -bool CSigScan::GetDllMemInfo(void) { - void *pAddr = (void*)sigscan_dllfunc; - base_addr = 0; - base_len = 0; - - #ifdef WIN32 - MEMORY_BASIC_INFORMATION mem; - - if(!pAddr) - return false; // GetDllMemInfo failed!pAddr - - if(!VirtualQuery(pAddr, &mem, sizeof(mem))) - return false; - - base_addr = (unsigned char*)mem.AllocationBase; - - IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)mem.AllocationBase; - IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS*)((unsigned long)dos+(unsigned long)dos->e_lfanew); - - if(pe->Signature != IMAGE_NT_SIGNATURE) { - base_addr = 0; - return false; // GetDllMemInfo failedpe points to a bad location - } - - base_len = (size_t)pe->OptionalHeader.SizeOfImage; - - #else - - Dl_info info; - struct stat buf; - - if(!dladdr(pAddr, &info)) - return false; - - if(!info.dli_fbase || !info.dli_fname) - return false; - - if(stat(info.dli_fname, &buf) != 0) - return false; - - base_addr = (unsigned char*)info.dli_fbase; - base_len = buf.st_size; - #endif - - return true; -} - -/* Scan for the signature in memory then return the starting position's address */ -void* CSigScan::FindSignature(void) { - unsigned char *pBasePtr = base_addr; - unsigned char *pEndPtr = base_addr+base_len; - size_t i; - - while(pBasePtr < pEndPtr) { - for(i = 0;i < sig_len;i++) { - if((sig_mask[i] != '?') && (sig_str[i] != pBasePtr[i])) - break; - } - - // If 'i' reached the end, we know we have a match! - if(i == sig_len) - return (void*)pBasePtr; - - pBasePtr++; - } - - return NULL; -} \ No newline at end of file diff --git a/Resources/NetHook/sigscan.h b/Resources/NetHook/sigscan.h deleted file mode 100644 index b05e7197..00000000 --- a/Resources/NetHook/sigscan.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef SIGSCAN_H -#define SIGSCAN_H - -#include "interface.h" - -#include - -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include -#else - #include - #include - #include -#endif - -class CSigScan { -private: - /* Private Variables */ - /* Base Address of the server module in memory */ - static unsigned char *base_addr; - /* The length to the module's ending address */ - static size_t base_len; - - /* The signature to scan for */ - unsigned char *sig_str; - /* A mask to ignore certain bytes in the signature such as addresses - The mask should be as long as all the bytes in the signature string - Use '?' to ignore a byte and 'x' to check it - Example: "xxx????xx" - The first 3 bytes are checked, then the next 4 are - ignored, then the last 2 are checked */ - char *sig_mask; - /* The length of sig_str and sig_mask (not including a terminating null for sig_mask) */ - size_t sig_len; - - /* Private Functions */ - void* FindSignature(void); - -public: - /* Public Variables */ - - /* sigscan_dllfunc is a pointer of something that resides inside the gamedll so we can get - the base address of it. From a SourceMM plugin, just set this to ismm->serverFactory(0) - in Load(). From a Valve Server Plugin, you must set this to an actual factory returned - from gameServerFactory and hope that a SourceMM plugin did not override it. */ - static void *(*sigscan_dllfunc)(const char *pName, int *pReturnCode); - - /* If the scan was successful or not */ - char is_set; - /* Starting address of the found function */ - void *sig_addr; - - CSigScan(void): sig_str(NULL), sig_mask(NULL), sig_len(0), sig_addr(NULL) {} - ~CSigScan(void); - - static bool GetDllMemInfo(void); - int Init(unsigned char *sig, char *mask, size_t len); -}; - -/* Sigscanned member functions are casted to member function pointers of this class - and called with member function pointer syntax */ -class EmptyClass { }; - -void InitSigs(void); - -#endif \ No newline at end of file diff --git a/Resources/NetHook/steam/clientmsgs.h b/Resources/NetHook/steam/clientmsgs.h deleted file mode 100644 index 11876d18..00000000 --- a/Resources/NetHook/steam/clientmsgs.h +++ /dev/null @@ -1,90 +0,0 @@ - -#ifndef CLIENTMSGS_H_ -#define CLIENTMSGS_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#include "steam/steamtypes.h" -#include "steam/csteamid.h" - - - -#pragma pack( push, 1 ) - -struct MsgChannelEncryptRequest_t -{ - uint32 m_unProtocolVer; - int32 m_EUniverse; // EUniverse -}; - -struct MsgChannelEncryptResponse_t -{ - uint32 m_unProtocolVer; - uint32 m_cubEncryptedKey; -}; - -struct MsgChannelEncryptResult_t -{ - int32 m_EResult; -}; - -struct MsgMulti_t -{ - uint32 m_cubUnzipped; -}; - -struct MsgClientAnonLogOn_t -{ - uint32 m_unProtocolVer; - - uint32 m_unIPPrivateObfuscated; - uint32 m_unIPPublic; - -}; - -struct MsgClientLogOnResponse_t -{ - int m_EResult; - - int m_nOutOfGameHeartbeatRateSec; - int m_nInGameHeartbeatRateSec; - - CSteamID m_ulClientSuppliedSteamId; - - uint32 m_unIPPublic; - - RTime32 m_RTime32ServerRealTime; -}; - - -struct MsgClientLogOnWithCredentials_t -{ - uint32 m_unProtocolVer; - - uint32 m_unIPPrivateObfuscated; - uint32 m_unIPPublic; - - uint64 m_ulClientSuppliedSteamId; - - uint32 m_unTicketLength; - - char m_rgchAccountName[ 64 ]; - char m_rgchPassword[ 20 ]; - - uint32 m_qosLevel; // ENetQOSLevel -}; - -struct MsgClientRegisterAuthTicketWithCM_t -{ - uint32 m_unProtocolVer; - uint32 m_unTicketLengthWithSignature; //B0 00 00 00 -}; - - - -#pragma pack( pop ) - - -#endif // !CLIENTMSGS_H_ diff --git a/Resources/NetHook/steam/csteamid.h b/Resources/NetHook/steam/csteamid.h deleted file mode 100644 index 79951696..00000000 --- a/Resources/NetHook/steam/csteamid.h +++ /dev/null @@ -1,515 +0,0 @@ - -#ifndef CSTEAMID_H -#define CSTEAMID_H -#ifdef _WIN32 -#pragma once -#endif - -#include "steamtypes.h" - -#pragma pack( push, 1 ) - -// Steam universes. Each universe is a self-contained Steam instance. -enum EUniverse -{ - k_EUniverseInvalid = 0, - k_EUniversePublic = 1, - k_EUniverseBeta = 2, - k_EUniverseInternal = 3, - k_EUniverseDev = 4, - k_EUniverseRC = 5, - - k_EUniverseMax -}; - - -// Steam account types -enum EAccountType -{ - k_EAccountTypeInvalid = 0, - k_EAccountTypeIndividual = 1, // single user account - k_EAccountTypeMultiseat = 2, // multiseat (e.g. cybercafe) account - k_EAccountTypeGameServer = 3, // game server account - k_EAccountTypeAnonGameServer = 4, // anonymous game server account - k_EAccountTypePending = 5, // pending - k_EAccountTypeContentServer = 6, // content server - k_EAccountTypeClan = 7, - k_EAccountTypeChat = 8, - k_EAccountTypeP2PSuperSeeder = 9, // a fake steamid used by superpeers to seed content to users of Steam P2P stuff - k_EAccountTypeAnonUser = 10, - - // Max of 16 items in this field - k_EAccountTypeMax -}; - -const int k_unSteamAccountIDMask = 0xFFFFFFFF; -const int k_unSteamAccountInstanceMask = 0x000FFFFF; - -// Special flags for Chat accounts - they go in the top 8 bits -// of the steam ID's "instance", leaving 12 for the actual instances -enum EChatSteamIDInstanceFlags -{ - k_EChatAccountInstanceMask = 0x00000FFF, // top 8 bits are flags - - k_EChatInstanceFlagClan = ( k_unSteamAccountInstanceMask + 1 ) >> 1, // top bit - k_EChatInstanceFlagLobby = ( k_unSteamAccountInstanceMask + 1 ) >> 2, // next one down, etc - k_EChatInstanceFlagMMSLobby = ( k_unSteamAccountInstanceMask + 1 ) >> 3, // next one down, etc - - // Max of 8 flags -}; - -// Steam ID structure (64 bits total) -class CSteamID -{ -public: - - //----------------------------------------------------------------------------- - // Purpose: Constructor - //----------------------------------------------------------------------------- - CSteamID() - { - m_steamid.m_comp.m_unAccountID = 0; - m_steamid.m_comp.m_EAccountType = k_EAccountTypeInvalid; - m_steamid.m_comp.m_EUniverse = k_EUniverseInvalid; - m_steamid.m_comp.m_unAccountInstance = 0; - } - - - //----------------------------------------------------------------------------- - // Purpose: Constructor - // Input : unAccountID - 32-bit account ID - // eUniverse - Universe this account belongs to - // eAccountType - Type of account - //----------------------------------------------------------------------------- - CSteamID( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType ) - { - Set( unAccountID, eUniverse, eAccountType ); - } - - - //----------------------------------------------------------------------------- - // Purpose: Constructor - // Input : unAccountID - 32-bit account ID - // unAccountInstance - instance - // eUniverse - Universe this account belongs to - // eAccountType - Type of account - //----------------------------------------------------------------------------- - CSteamID( uint32 unAccountID, unsigned int unAccountInstance, EUniverse eUniverse, EAccountType eAccountType ) - { -#if defined(_SERVER) && defined(Assert) - Assert( ! ( ( k_EAccountTypeIndividual == eAccountType ) && ( 1 != unAccountInstance ) ) ); // enforce that for individual accounts, instance is always 1 -#endif // _SERVER - InstancedSet( unAccountID, unAccountInstance, eUniverse, eAccountType ); - } - - - //----------------------------------------------------------------------------- - // Purpose: Constructor - // Input : ulSteamID - 64-bit representation of a Steam ID - // Note: Will not accept a uint32 or int32 as input, as that is a probable mistake. - // See the stubbed out overloads in the private: section for more info. - //----------------------------------------------------------------------------- - CSteamID( uint64 ulSteamID ) - { - SetFromUint64( ulSteamID ); - } - - - //----------------------------------------------------------------------------- - // Purpose: Sets parameters for steam ID - // Input : unAccountID - 32-bit account ID - // eUniverse - Universe this account belongs to - // eAccountType - Type of account - //----------------------------------------------------------------------------- - void Set( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType ) - { - m_steamid.m_comp.m_unAccountID = unAccountID; - m_steamid.m_comp.m_EUniverse = eUniverse; - m_steamid.m_comp.m_EAccountType = eAccountType; - - if ( eAccountType == k_EAccountTypeClan ) - { - m_steamid.m_comp.m_unAccountInstance = 0; - } - else - { - m_steamid.m_comp.m_unAccountInstance = 1; - } - } - - - //----------------------------------------------------------------------------- - // Purpose: Sets parameters for steam ID - // Input : unAccountID - 32-bit account ID - // eUniverse - Universe this account belongs to - // eAccountType - Type of account - //----------------------------------------------------------------------------- - void InstancedSet( uint32 unAccountID, uint32 unInstance, EUniverse eUniverse, EAccountType eAccountType ) - { - m_steamid.m_comp.m_unAccountID = unAccountID; - m_steamid.m_comp.m_EUniverse = eUniverse; - m_steamid.m_comp.m_EAccountType = eAccountType; - m_steamid.m_comp.m_unAccountInstance = unInstance; - } - - - //----------------------------------------------------------------------------- - // Purpose: Initializes a steam ID from its 52 bit parts and universe/type - // Input : ulIdentifier - 52 bits of goodness - //----------------------------------------------------------------------------- - void FullSet( uint64 ulIdentifier, EUniverse eUniverse, EAccountType eAccountType ) - { - m_steamid.m_comp.m_unAccountID = ( ulIdentifier & 0xFFFFFFFF ); // account ID is low 32 bits - m_steamid.m_comp.m_unAccountInstance = ( ( ulIdentifier >> 32 ) & 0xFFFFF ); // account instance is next 20 bits - m_steamid.m_comp.m_EUniverse = eUniverse; - m_steamid.m_comp.m_EAccountType = eAccountType; - } - - - //----------------------------------------------------------------------------- - // Purpose: Initializes a steam ID from its 64-bit representation - // Input : ulSteamID - 64-bit representation of a Steam ID - //----------------------------------------------------------------------------- - void SetFromUint64( uint64 ulSteamID ) - { - m_steamid.m_unAll64Bits = ulSteamID; - } - - //----------------------------------------------------------------------------- - // Purpose: Initializes a steam ID from a Steam2 ID structure - // Input: pTSteamGlobalUserID - Steam2 ID to convert - // eUniverse - universe this ID belongs to - //----------------------------------------------------------------------------- - void SetFromSteam2( TSteamGlobalUserID *pTSteamGlobalUserID, EUniverse eUniverse ) - { - m_steamid.m_comp.m_unAccountID = pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits * 2 + - pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits; - m_steamid.m_comp.m_EUniverse = eUniverse; // set the universe - m_steamid.m_comp.m_EAccountType = k_EAccountTypeIndividual; // Steam 2 accounts always map to account type of individual - m_steamid.m_comp.m_unAccountInstance = 1; // individual accounts always have an account instance ID of 1 - } - - //----------------------------------------------------------------------------- - // Purpose: Fills out a Steam2 ID structure - // Input: pTSteamGlobalUserID - Steam2 ID to write to - //----------------------------------------------------------------------------- - void ConvertToSteam2( TSteamGlobalUserID *pTSteamGlobalUserID ) const - { - // only individual accounts have any meaning in Steam 2, only they can be mapped - // Assert( m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual ); - - pTSteamGlobalUserID->m_SteamInstanceID = 0; - pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits = m_steamid.m_comp.m_unAccountID % 2; - pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits = m_steamid.m_comp.m_unAccountID / 2; - } - - //----------------------------------------------------------------------------- - // Purpose: Converts steam ID to its 64-bit representation - // Output : 64-bit representation of a Steam ID - //----------------------------------------------------------------------------- - uint64 ConvertToUint64() const - { - return m_steamid.m_unAll64Bits; - } - - - //----------------------------------------------------------------------------- - // Purpose: Converts the static parts of a steam ID to a 64-bit representation. - // For multiseat accounts, all instances of that account will have the - // same static account key, so they can be grouped together by the static - // account key. - // Output : 64-bit static account key - //----------------------------------------------------------------------------- - uint64 GetStaticAccountKey() const - { - // note we do NOT include the account instance (which is a dynamic property) in the static account key - return (uint64) ( ( ( (uint64) m_steamid.m_comp.m_EUniverse ) << 56 ) + ((uint64) m_steamid.m_comp.m_EAccountType << 52 ) + m_steamid.m_comp.m_unAccountID ); - } - - - //----------------------------------------------------------------------------- - // Purpose: create an anonymous game server login to be filled in by the AM - //----------------------------------------------------------------------------- - void CreateBlankAnonLogon( EUniverse eUniverse ) - { - m_steamid.m_comp.m_unAccountID = 0; - m_steamid.m_comp.m_EAccountType = k_EAccountTypeAnonGameServer; - m_steamid.m_comp.m_EUniverse = eUniverse; - m_steamid.m_comp.m_unAccountInstance = 0; - } - - - //----------------------------------------------------------------------------- - // Purpose: create an anonymous game server login to be filled in by the AM - //----------------------------------------------------------------------------- - void CreateBlankAnonUserLogon( EUniverse eUniverse ) - { - m_steamid.m_comp.m_unAccountID = 0; - m_steamid.m_comp.m_EAccountType = k_EAccountTypeAnonUser; - m_steamid.m_comp.m_EUniverse = eUniverse; - m_steamid.m_comp.m_unAccountInstance = 0; - } - - //----------------------------------------------------------------------------- - // Purpose: Is this an anonymous game server login that will be filled in? - //----------------------------------------------------------------------------- - bool BBlankAnonAccount() const - { - return m_steamid.m_comp.m_unAccountID == 0 && BAnonAccount() && m_steamid.m_comp.m_unAccountInstance == 0; - } - - //----------------------------------------------------------------------------- - // Purpose: Is this a game server account id? - //----------------------------------------------------------------------------- - bool BGameServerAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeGameServer || m_steamid.m_comp.m_EAccountType == k_EAccountTypeAnonGameServer; - } - - //----------------------------------------------------------------------------- - // Purpose: Is this a content server account id? - //----------------------------------------------------------------------------- - bool BContentServerAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeContentServer; - } - - - //----------------------------------------------------------------------------- - // Purpose: Is this a clan account id? - //----------------------------------------------------------------------------- - bool BClanAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeClan; - } - - - //----------------------------------------------------------------------------- - // Purpose: Is this a chat account id? - //----------------------------------------------------------------------------- - bool BChatAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeChat; - } - - //----------------------------------------------------------------------------- - // Purpose: Is this a chat account id? - //----------------------------------------------------------------------------- - bool IsLobby() const - { - return ( m_steamid.m_comp.m_EAccountType == k_EAccountTypeChat ) - && ( m_steamid.m_comp.m_unAccountInstance & k_EChatInstanceFlagLobby ); - } - - - //----------------------------------------------------------------------------- - // Purpose: Is this an individual user account id? - //----------------------------------------------------------------------------- - bool BIndividualAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual; - } - - - //----------------------------------------------------------------------------- - // Purpose: Is this an anonymous account? - //----------------------------------------------------------------------------- - bool BAnonAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeAnonUser || m_steamid.m_comp.m_EAccountType == k_EAccountTypeAnonGameServer; - } - - //----------------------------------------------------------------------------- - // Purpose: Is this an anonymous user account? ( used to create an account or reset a password ) - //----------------------------------------------------------------------------- - bool BAnonUserAccount() const - { - return m_steamid.m_comp.m_EAccountType == k_EAccountTypeAnonUser; - } - - - // simple accessors - void SetAccountID( uint32 unAccountID ) { m_steamid.m_comp.m_unAccountID = unAccountID; } - uint32 GetAccountID() const { return m_steamid.m_comp.m_unAccountID; } - uint32 GetUnAccountInstance() const { return m_steamid.m_comp.m_unAccountInstance; } - EAccountType GetEAccountType() const { return ( EAccountType ) m_steamid.m_comp.m_EAccountType; } - EUniverse GetEUniverse() const { return m_steamid.m_comp.m_EUniverse; } - void SetEUniverse( EUniverse eUniverse ) { m_steamid.m_comp.m_EUniverse = eUniverse; } - bool IsValid() const; - - // this set of functions is hidden, will be moved out of class - explicit CSteamID( const char *pchSteamID, EUniverse eDefaultUniverse = k_EUniverseInvalid ); - const char * Render() const // renders this steam ID to string - { - static char szSteamID[64]; - switch(m_steamid.m_comp.m_EAccountType) - { - case k_EAccountTypeInvalid: - case k_EAccountTypeIndividual: - sprintf_s(szSteamID, sizeof(szSteamID), "STEAM_0:%u:%u", (m_steamid.m_comp.m_unAccountID % 2) ? 1 : 0, (int32)m_steamid.m_comp.m_unAccountID/2); - break; - default: - sprintf_s(szSteamID, sizeof(szSteamID), "%llu", ConvertToUint64()); - } - return szSteamID; - } - static const char * Render( uint64 ulSteamID ) // static method to render a uint64 representation of a steam ID to a string - { - return CSteamID(ulSteamID).Render(); - } - - const char *SteamRender() const // renders this steam ID to string using the new rendering style - { - const int k_cBufLen = 37; - const int k_cBufs = 4; - char* pchBuf; - - static char rgchBuf[k_cBufs][k_cBufLen]; - static int nBuf = 0; - - pchBuf = rgchBuf[nBuf++]; - nBuf %= k_cBufs; - - switch (m_steamid.m_comp.m_EAccountType) - { - case k_EAccountTypeAnonGameServer: - sprintf_s(pchBuf, k_cBufLen, "[A:%u:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID, m_steamid.m_comp.m_unAccountInstance); - break; - case k_EAccountTypeGameServer: - sprintf_s(pchBuf, k_cBufLen, "[G:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EAccountTypeMultiseat: - sprintf_s(pchBuf, k_cBufLen, "[M:%u:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID, m_steamid.m_comp.m_unAccountInstance); - break; - case k_EAccountTypePending: - sprintf_s(pchBuf, k_cBufLen, "[P:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EAccountTypeContentServer: - sprintf_s(pchBuf, k_cBufLen, "[C:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EAccountTypeClan: - sprintf_s(pchBuf, k_cBufLen, "[g:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EAccountTypeChat: - switch (m_steamid.m_comp.m_unAccountInstance & ~k_EChatAccountInstanceMask) - { - case k_EChatInstanceFlagClan: - sprintf_s(pchBuf, k_cBufLen, "[c:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EChatInstanceFlagLobby: - sprintf_s(pchBuf, k_cBufLen, "[L:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - default: - sprintf_s(pchBuf, k_cBufLen, "[T:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - } - break; - case k_EAccountTypeInvalid: - sprintf_s(pchBuf, k_cBufLen, "[I:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - case k_EAccountTypeIndividual: - sprintf_s(pchBuf, k_cBufLen, "[U:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - default: - sprintf_s(pchBuf, k_cBufLen, "[i:%u:%u]", m_steamid.m_comp.m_EUniverse, m_steamid.m_comp.m_unAccountID); - break; - } - - return pchBuf; - } - - static const char *SteamRender( uint64 ulSteamID ) // static method to render a uint64 representation of a steam ID to a string - { - return CSteamID(ulSteamID).SteamRender(); - } - - void SetFromString( const char *pchSteamID, EUniverse eDefaultUniverse ); - bool SetFromSteam2String( const char *pchSteam2ID, EUniverse eUniverse ); - - inline bool operator==( const CSteamID &val ) const { return m_steamid.m_unAll64Bits == val.m_steamid.m_unAll64Bits; } - inline bool operator!=( const CSteamID &val ) const { return !operator==( val ); } - inline bool operator<( const CSteamID &val ) const { return m_steamid.m_unAll64Bits < val.m_steamid.m_unAll64Bits; } - inline bool operator>( const CSteamID &val ) const { return m_steamid.m_unAll64Bits > val.m_steamid.m_unAll64Bits; } - - // DEBUG function - bool BValidExternalSteamID() const; - -private: - // These are defined here to prevent accidental implicit conversion of a u32AccountID to a CSteamID. - // If you get a compiler error about an ambiguous constructor/function then it may be because you're - // passing a 32-bit int to a function that takes a CSteamID. You should explicitly create the SteamID - // using the correct Universe and account Type/Instance values. - CSteamID( uint32 ); - CSteamID( int32 ); - - // 64 bits total - union SteamID_t - { - struct SteamIDComponent_t - { - uint32 m_unAccountID : 32; // unique account identifier - unsigned int m_unAccountInstance : 20; // dynamic instance ID (used for multiseat type accounts only) - unsigned int m_EAccountType : 4; // type of account - can't show as EAccountType, due to signed / unsigned difference - EUniverse m_EUniverse : 8; // universe this account belongs to - } m_comp; - - uint64 m_unAll64Bits; - } m_steamid; -}; - - -inline bool CSteamID::IsValid() const -{ - if ( m_steamid.m_comp.m_EAccountType <= k_EAccountTypeInvalid || m_steamid.m_comp.m_EAccountType >= k_EAccountTypeMax ) - return false; - - if ( m_steamid.m_comp.m_EUniverse <= k_EUniverseInvalid || m_steamid.m_comp.m_EUniverse >= k_EUniverseMax ) - return false; - - if ( m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual ) - { - if ( m_steamid.m_comp.m_unAccountID == 0 || m_steamid.m_comp.m_unAccountInstance != 1 ) - return false; - } - - if ( m_steamid.m_comp.m_EAccountType == k_EAccountTypeClan ) - { - if ( m_steamid.m_comp.m_unAccountID == 0 || m_steamid.m_comp.m_unAccountInstance != 0 ) - return false; - } - return true; -} - -// generic invalid CSteamID -const CSteamID k_steamIDNil; - -// This steamID comes from a user game connection to an out of date GS that hasnt implemented the protocol -// to provide its steamID -const CSteamID k_steamIDOutofDateGS( 0, 0, k_EUniverseInvalid, k_EAccountTypeInvalid ); -// This steamID comes from a user game connection to an sv_lan GS -const CSteamID k_steamIDLanModeGS( 0, 0, k_EUniversePublic, k_EAccountTypeInvalid ); -// This steamID can come from a user game connection to a GS that has just booted but hasnt yet even initialized -// its steam3 component and started logging on. -const CSteamID k_steamIDNotInitYetGS( 1, 0, k_EUniverseInvalid, k_EAccountTypeInvalid ); -// This steamID can come from a user game connection to a GS that isn't using the steam authentication system but still -// wants to support the "Join Game" option in the friends list -const CSteamID k_steamIDNonSteamGS( 2, 0, k_EUniverseInvalid, k_EAccountTypeInvalid ); - - -#ifdef STEAM -// Returns the matching chat steamID, with the default instance of 0 -// If the steamID passed in is already of type k_EAccountTypeChat it will be returned with the same instance -CSteamID ChatIDFromSteamID( const CSteamID &steamID ); -// Returns the matching clan steamID, with the default instance of 0 -// If the steamID passed in is already of type k_EAccountTypeClan it will be returned with the same instance -CSteamID ClanIDFromSteamID( const CSteamID &steamID ); -// Asserts steamID type before conversion -CSteamID ChatIDFromClanID( const CSteamID &steamIDClan ); -// Asserts steamID type before conversion -CSteamID ClanIDFromChatID( const CSteamID &steamIDChat ); - -#endif // _STEAM - -#pragma pack( pop ) - -#endif // CSTEAMID_H diff --git a/Resources/NetHook/steam/emsg.h b/Resources/NetHook/steam/emsg.h deleted file mode 100644 index 9d3305c9..00000000 --- a/Resources/NetHook/steam/emsg.h +++ /dev/null @@ -1,348 +0,0 @@ - -#ifndef EMSG_H_ -#define EMSG_H_ -#ifdef _WIN32 -#pragma once -#endif - -enum EMsg -{ - k_EMsgInvalid = 0, - - k_EMsgMulti = 1, - - k_EMsgRemoteSysID = 128, - k_EMsgClientChatAction = 597, - k_EMsgCSUserContentRequest = 652, - k_EMsgClientLogOn_Deprecated = 701, - k_EMsgClientAnonLogOn_Deprecated = 702, - k_EMsgClientHeartBeat = 703, - k_EMsgClientVACResponse = 704, - k_EMsgClientLogOff = 706, - k_EMsgClientNoUDPConnectivity = 707, - k_EMsgClientInformOfCreateAccount = 708, - k_EMsgClientAckVACBan = 709, - k_EMsgClientConnectionStats = 710, - k_EMsgClientInitPurchase = 711, - k_EMsgClientPingResponse = 712, - k_EMsgClientAddFriend = 713, - k_EMsgClientRemoveFriend = 714, - k_EMsgClientGamesPlayedNoDataBlob = 715, - k_EMsgClientChangeStatus = 716, - k_EMsgClientVacStatusResponse = 717, - k_EMsgClientFriendMsg = 718, - k_EMsgClientGetFinalPrice = 722, - k_EMsgClientSystemIM = 726, - k_EMsgClientSystemIMAck = 727, - k_EMsgClientGetLicenses = 728, - k_EMsgClientCancelLicense = 729, - k_EMsgClientGetLegacyGameKey = 730, - k_EMsgClientContentServerLogOn_Deprecated = 731, - k_EMsgClientAckVACBan2 = 732, - k_EMsgClientCompletePurchase = 733, - k_EMsgClientCancelPurchase = 734, - k_EMsgClientAckMessageByGID = 735, - k_EMsgClientGetPurchaseReceipts = 736, - k_EMsgClientAckPurchaseReceipt = 737, - k_EMsgClientSendGuestPass = 739, - k_EMsgClientAckGuestPass = 740, - k_EMsgClientRedeemGuestPass = 741, - k_EMsgClientGamesPlayed = 742, - k_EMsgClientRegisterKey = 743, - k_EMsgClientInviteUserToClan = 744, - k_EMsgClientAcknowledgeClanInvite = 745, - k_EMsgClientPurchaseWithMachineID = 746, - k_EMsgClientAppUsageEvent = 747, - k_EMsgClientGetGiftTargetList = 748, - k_EMsgClientGetGiftTargetListResponse = 749, - k_EMsgClientLogOnResponse = 751, - k_EMsgClientVACChallenge = 753, - k_EMsgClientSetHeartbeatRate = 755, - k_EMsgClientNotLoggedOnDeprecated = 756, - k_EMsgClientLoggedOff = 757, - k_EMsgGSApprove = 758, - k_EMsgGSDeny = 759, - k_EMsgGSKick = 760, - k_EMsgClientCreateAcctResponse = 761, - k_EMsgClientPurchaseResponse = 763, - k_EMsgClientPing = 764, - k_EMsgClientNOP = 765, - k_EMsgClientPersonaState = 766, - k_EMsgClientFriendsList = 767, - k_EMsgClientAccountInfo = 768, - k_EMsgClientAddFriendResponse = 769, - k_EMsgClientVacStatusQuery = 770, - k_EMsgClientNewsUpdate = 771, - k_EMsgClientGameConnectDeny = 773, - k_EMsgGSStatusReply = 774, - k_EMsgClientGetFinalPriceResponse = 775, - k_EMsgClientGameConnectTokens = 779, - k_EMsgClientLicenseList = 780, - k_EMsgClientCancelLicenseResponse = 781, - k_EMsgClientVACBanStatus = 782, - k_EMsgClientCMList = 783, - k_EMsgClientEncryptPct = 784, - k_EMsgClientGetLegacyGameKeyResponse = 785, - k_EMsgCSUserContentApprove = 787, - k_EMsgCSUserContentDeny = 788, - k_EMsgClientInitPurchaseResponse = 789, - k_EMsgClientAddFriend2 = 791, - k_EMsgClientAddFriendResponse2 = 792, - k_EMsgClientInviteFriend = 793, - k_EMsgClientInviteFriendResponse = 794, - k_EMsgClientSendGuestPassResponse = 795, - k_EMsgClientAckGuestPassResponse = 796, - k_EMsgClientRedeemGuestPassResponse = 797, - k_EMsgClientUpdateGuestPassesList = 798, - k_EMsgClientChatMsg = 799, - k_EMsgClientChatInvite = 800, - k_EMsgClientJoinChat = 801, - k_EMsgClientChatMemberInfo = 802, - k_EMsgClientLogOnWithCredentials_Deprecated = 803, - k_EMsgClientPasswordChange = 804, - k_EMsgClientPasswordChangeResponse = 805, - k_EMsgClientChatEnter = 807, - k_EMsgClientFriendRemovedFromSource = 808, - k_EMsgClientCreateChat = 809, - k_EMsgClientCreateChatResponse = 810, - k_EMsgClientUpdateChatMetadata = 811, - k_EMsgClientP2PIntroducerMessage = 813, - k_EMsgClientChatActionResult = 814, - k_EMsgClientRequestFriendData = 815, - k_EMsgClientOneTimeWGAuthPassword = 816, - k_EMsgClientGetUserStats = 818, - k_EMsgClientGetUserStatsResponse = 819, - k_EMsgClientStoreUserStats = 820, - k_EMsgClientStoreUserStatsResponse = 821, - k_EMsgClientClanState = 822, - k_EMsgClientServiceModule = 830, - k_EMsgClientServiceCall = 831, - k_EMsgClientServiceCallResponse = 832, - k_EMsgClientNatTraversalStatEvent = 839, - k_EMsgClientAppInfoRequest = 840, - k_EMsgClientAppInfoResponse = 841, - k_EMsgClientSteamUsageEvent = 842, - k_EMsgClientEmailChange = 843, - k_EMsgClientPersonalQAChange = 844, - k_EMsgClientCheckPassword = 845, - k_EMsgClientResetPassword = 846, - k_EMsgClientCheckPasswordResponse = 848, - k_EMsgClientResetPasswordResponse = 849, - k_EMsgClientSessionToken = 850, - k_EMsgClientDRMProblemReport = 851, - k_EMsgClientSetIgnoreFriend = 855, - k_EMsgClientSetIgnoreFriendResponse = 856, - k_EMsgClientGetAppOwnershipTicket = 857, - k_EMsgClientGetAppOwnershipTicketResponse = 858, - k_EMsgClientGetLobbyListResponse = 860, - k_EMsgClientGetLobbyMetadata = 861, - k_EMsgClientGetLobbyMetadataResponse = 862, - k_EMsgClientVTTCert = 863, - k_EMsgClientAppInfoUpdate = 866, - k_EMsgClientAppInfoChanges = 867, - k_EMsgClientServerList = 880, - k_EMsgClientGetFriendsLobbies = 888, - k_EMsgClientGetFriendsLobbiesResponse = 889, - k_EMsgClientGetLobbyList = 890, - k_EMsgClientEmailChangeResponse = 891, - k_EMsgClientSecretQAChangeResponse = 892, - k_EMsgClientPasswordChange2 = 893, - k_EMsgClientEmailChange2 = 894, - k_EMsgClientPersonalQAChange2 = 895, - k_EMsgClientDRMBlobRequest = 896, - k_EMsgClientDRMBlobResponse = 897, - k_EMsgClientLookupKey = 898, - k_EMsgClientLookupKeyResponse = 899, - k_EMsgGSDisconnectNotice = 901, - k_EMsgGSStatus = 903, - k_EMsgGSUserPlaying = 905, - k_EMsgGSStatus2 = 906, - k_EMsgGSStatusUpdate_Unused = 907, - k_EMsgGSServerType = 908, - k_EMsgGSPlayerList = 909, - k_EMsgGSGetUserAchievementStatus = 910, - k_EMsgGSGetUserAchievementStatusResponse = 911, - k_EMsgGSGetPlayStats = 918, - k_EMsgGSGetPlayStatsResponse = 919, - k_EMsgGSGetUserGroupStatus = 920, - k_EMsgGSGetUserGroupStatusResponse = 923, - k_EMsgGSGetReputation = 936, - k_EMsgGSGetReputationResponse = 937, - k_EMsgChannelEncryptRequest = 1303, - k_EMsgChannelEncryptResponse = 1304, - k_EMsgClientChatRoomInfo = 4026, - k_EMsgClientUFSUploadFileRequest = 5202, - k_EMsgClientUFSUploadFileResponse = 5203, - k_EMsgClientUFSUploadFileChunk = 5204, - k_EMsgClientUFSUploadFileFinished = 5205, - k_EMsgClientUFSGetFileListForApp = 5206, - k_EMsgClientUFSGetFileListForAppResponse = 5207, - k_EMsgClientUFSDownloadRequest = 5210, - k_EMsgClientUFSDownloadResponse = 5211, - k_EMsgClientUFSDownloadChunk = 5212, - k_EMsgClientUFSLoginRequest = 5213, - k_EMsgClientUFSLoginResponse = 5214, - k_EMsgClientUFSTransferHeartbeat = 5216, - k_EMsgClientUFSDeleteFileRequest = 5219, - k_EMsgClientUFSDeleteFileResponse = 5220, - k_EMsgClientUFSGetUGCDetails = 5226, - k_EMsgClientUFSGetUGCDetailsResponse = 5227, - k_EMsgClientUFSGetSingleFileInfo = 5230, - k_EMsgClientUFSGetSingleFileInfoResponse = 5231, - k_EMsgClientUFSShareFile = 5232, - k_EMsgClientUFSShareFileResponse = 5233, - k_EMsgClientRequestForgottenPasswordEmail = 5401, - k_EMsgClientRequestForgottenPasswordEmailResponse = 5402, - k_EMsgClientCreateAccountResponse = 5403, - k_EMsgClientResetForgottenPassword = 5404, - k_EMsgClientResetForgottenPasswordResponse = 5405, - k_EMsgClientCreateAccount2 = 5406, - k_EMsgClientInformOfResetForgottenPassword = 5407, - k_EMsgClientInformOfResetForgottenPasswordResponse = 5408, - k_EMsgClientAnonUserLogOn_Deprecated = 5409, - k_EMsgClientGamesPlayedWithDataBlob = 5410, - k_EMsgClientUpdateUserGameInfo = 5411, - k_EMsgClientFileToDownload = 5412, - k_EMsgClientFileToDownloadResponse = 5413, - k_EMsgClientLBSSetScore = 5414, - k_EMsgClientLBSSetScoreResponse = 5415, - k_EMsgClientLBSFindOrCreateLB = 5416, - k_EMsgClientLBSFindOrCreateLBResponse = 5417, - k_EMsgClientLBSGetLBEntries = 5418, - k_EMsgClientLBSGetLBEntriesResponse = 5419, - k_EMsgClientMarketingMessageUpdate = 5420, - k_EMsgClientChatDeclined = 5426, - k_EMsgClientFriendMsgIncoming = 5427, - k_EMsgClientAuthList_Deprecated = 5428, - k_EMsgClientTicketAuthComplete = 5429, - k_EMsgClientIsLimitedAccount = 5430, - k_EMsgClientAuthList = 5432, - k_EMsgClientStat = 5433, - k_EMsgClientP2PConnectionInfo = 5434, - k_EMsgClientP2PConnectionFailInfo = 5435, - k_EMsgClientGetNumberOfCurrentPlayers = 5436, - k_EMsgClientGetNumberOfCurrentPlayersResponse = 5437, - k_EMsgClientGetDepotDecryptionKey = 5438, - k_EMsgClientGetDepotDecryptionKeyResponse = 5439, - k_EMsgGSPerformHardwareSurvey = 5440, - k_EMsgClientEnableTestLicense = 5443, - k_EMsgClientEnableTestLicenseResponse = 5444, - k_EMsgClientDisableTestLicense = 5445, - k_EMsgClientDisableTestLicenseResponse = 5446, - k_EMsgClientRequestValidationMail = 5448, - k_EMsgClientRequestValidationMailResponse = 5449, - k_EMsgClientToGC = 5452, - k_EMsgClientFromGC = 5453, - k_EMsgClientRequestChangeMail = 5454, - k_EMsgClientRequestChangeMailResponse = 5455, - k_EMsgClientEmailAddrInfo = 5456, - k_EMsgClientPasswordChange3 = 5457, - k_EMsgClientEmailChange3 = 5458, - k_EMsgClientPersonalQAChange3 = 5459, - k_EMsgClientResetForgottenPassword3 = 5460, - k_EMsgClientRequestForgottenPasswordEmail3 = 5461, - k_EMsgClientCreateAccount3 = 5462, - k_EMsgClientNewLoginKey = 5463, - k_EMsgClientNewLoginKeyAccepted = 5464, - k_EMsgClientLogOnWithHash_Deprecated = 5465, - k_EMsgClientStoreUserStats2 = 5466, - k_EMsgClientStatsUpdated = 5467, - k_EMsgClientActivateOEMLicense = 5468, - k_EMsgClientRequestedClientStats = 5480, - k_EMsgClientStat2Int32 = 5481, - k_EMsgClientStat2 = 5482, - k_EMsgClientVerifyPassword = 5483, - k_EMsgClientVerifyPasswordResponse = 5484, - k_EMsgClientDRMDownloadRequest = 5485, - k_EMsgClientDRMDownloadResponse = 5486, - k_EMsgClientDRMFinalResult = 5487, - k_EMsgClientGetFriendsWhoPlayGame = 5488, - k_EMsgClientGetFriendsWhoPlayGameResponse = 5489, - k_EMsgClientOGSBeginSession = 5490, - k_EMsgClientOGSBeginSessionResponse = 5491, - k_EMsgClientOGSEndSession = 5492, - k_EMsgClientOGSEndSessionResponse = 5493, - k_EMsgClientOGSWriteRow = 5494, - k_EMsgClientDRMTest = 5495, - k_EMsgClientDRMTestResult = 5496, - k_EMsgClientServerUnavailable = 5500, - k_EMsgClientServersAvailable = 5501, - k_EMsgClientRegisterAuthTicketWithCM = 5502, - k_EMsgClientGCMsgFailed = 5503, - k_EMsgClientMicroTxnAuthRequest = 5504, - k_EMsgClientMicroTxnAuthorize = 5505, - k_EMsgClientMicroTxnAuthorizeResponse = 5506, - k_EMsgClientAppMinutesPlayedData = 5507, - k_EMsgClientGetMicroTxnInfo = 5508, - k_EMsgClientGetMicroTxnInfoResponse = 5509, - k_EMsgClientMarketingMessageUpdate2 = 5510, - k_EMsgClientDeregisterWithServer = 5511, - k_EMsgClientSubscribeToPersonaFeed = 5512, - k_EMsgClientLogon = 5514, - k_EMsgClientGetClientDetails = 5515, - k_EMsgClientGetClientDetailsResponse = 5516, - k_EMsgClientReportOverlayDetourFailure = 5517, - k_EMsgClientGetClientAppList = 5518, - k_EMsgClientGetClientAppListResponse = 5519, - k_EMsgClientInstallClientApp = 5520, - k_EMsgClientInstallClientAppResponse = 5521, - k_EMsgClientUninstallClientApp = 5522, - k_EMsgClientUninstallClientAppResponse = 5523, - k_EMsgClientSetClientAppUpdateState = 5524, - k_EMsgClientSetClientAppUpdateStateResponse = 5525, - k_EMsgClientRequestEncryptedAppTicket = 5526, - k_EMsgClientRequestEncryptedAppTicketResponse = 5527, - k_EMsgClientWalletInfoUpdate = 5528, - k_EMsgClientLBSSetUGC = 5529, - k_EMsgClientLBSSetUGCResponse = 5530, - k_EMsgClientAMGetClanOfficers = 5531, - k_EMsgClientAMGetClanOfficersResponse = 5532, - k_EMsgClientDFSAuthenticateRequest = 5605, - k_EMsgClientDFSAuthenticateResponse = 5606, - k_EMsgClientDFSEndSession = 5607, - k_EMsgClientDFSDownloadStatus = 5617, - k_EMsgClientMDSLoginRequest = 5801, - k_EMsgClientMDSLoginResponse = 5802, - k_EMsgClientMDSUploadManifestRequest = 5803, - k_EMsgClientMDSUploadManifestResponse = 5804, - k_EMsgClientMDSTransmitManifestDataChunk = 5805, - k_EMsgClientMDSHeartbeat = 5806, - k_EMsgClientMDSUploadDepotChunks = 5807, - k_EMsgClientMDSUploadDepotChunksResponse = 5808, - k_EMsgClientMDSInitDepotBuildRequest = 5809, - k_EMsgClientMDSInitDepotBuildResponse = 5810, - k_EMsgClientMDSGetDepotManifest = 5818, - k_EMsgClientMDSGetDepotManifestResponse = 5819, - k_EMsgClientMDSGetDepotManifestChunk = 5820, - k_EMsgClientMDSDownloadDepotChunksRequest = 5823, - k_EMsgClientMDSDownloadDepotChunksAsync = 5824, - k_EMsgClientMDSDownloadDepotChunksAck = 5825, - k_EMsgClientMMSCreateLobby = 6601, - k_EMsgClientMMSCreateLobbyResponse = 6602, - k_EMsgClientMMSJoinLobby = 6603, - k_EMsgClientMMSJoinLobbyResponse = 6604, - k_EMsgClientMMSLeaveLobby = 6605, - k_EMsgClientMMSLeaveLobbyResponse = 6606, - k_EMsgClientMMSGetLobbyList = 6607, - k_EMsgClientMMSGetLobbyListResponse = 6608, - k_EMsgClientMMSSetLobbyData = 6609, - k_EMsgClientMMSSetLobbyDataResponse = 6610, - k_EMsgClientMMSGetLobbyData = 6611, - k_EMsgClientMMSLobbyData = 6612, - k_EMsgClientMMSSendLobbyChatMsg = 6613, - k_EMsgClientMMSLobbyChatMsg = 6614, - k_EMsgClientMMSSetLobbyOwner = 6615, - k_EMsgClientMMSSetLobbyOwnerResponse = 6616, - k_EMsgClientMMSSetLobbyGameServer = 6617, - k_EMsgClientMMSLobbyGameServerSet = 6618, - k_EMsgClientMMSUserJoinedLobby = 6619, - k_EMsgClientMMSUserLeftLobby = 6620, - k_EMsgClientMMSInviteToLobby = 6621, - k_EMsgClientUDSP2PSessionStarted = 7001, - k_EMsgClientUDSP2PSessionEnded = 7002, - -}; - - - -#endif // !EMSG_H_ diff --git a/Resources/NetHook/steam/steamtypes.h b/Resources/NetHook/steam/steamtypes.h deleted file mode 100644 index 45e1fb0b..00000000 --- a/Resources/NetHook/steam/steamtypes.h +++ /dev/null @@ -1,306 +0,0 @@ - -#ifndef STEAMTYPES_H_ -#define STEAMTYPES_H_ -#ifdef _WIN32 -#pragma once -#endif - -#include - -#ifdef _WIN32 - #if defined( STEAM_API_EXPORTS ) - #define S_API extern "C" __declspec( dllexport ) - #else - #define S_API extern "C" __declspec( dllimport ) - #endif -#else - #define S_API extern "C" - - #ifndef __cdecl - #define __cdecl __attribute__((__cdecl__)) - #endif -#endif - -#if defined( __x86_64__ ) || defined( _WIN64 ) - #define X64BITS -#endif - - -#define STEAM_CALL __cdecl - - -// Steam-specific types. Defined here so this header file can be included in other code bases. -#ifndef WCHARTYPES_H - typedef unsigned char uint8; -#endif - -#if defined( _WIN32 ) - - typedef __int16 int16; - typedef unsigned __int16 uint16; - typedef __int32 int32; - typedef unsigned __int32 uint32; - typedef __int64 int64; - typedef unsigned __int64 uint64; - - #ifdef X64BITS - typedef __int64 intp; // intp is an integer that can accomodate a pointer - typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *) - #else - typedef __int32 intp; - typedef unsigned __int32 uintp; - #endif - -#else // !_WIN32 - - typedef short int16; - typedef unsigned short uint16; - typedef int int32; - typedef unsigned int uint32; - typedef long long int64; - typedef unsigned long long uint64; - - #ifdef X64BITS - typedef long long intp; - typedef unsigned long long uintp; - #else - typedef int intp; - typedef unsigned int uintp; - #endif - -#endif // else _WIN32 - - -typedef uint64 SteamUnsigned64_t; - - -typedef void (*SteamAPIWarningMessageHook_t)(int hpipe, const char *message); - - -//----------------------------------------------------------------------------- -// GID (GlobalID) stuff -// This is a globally unique identifier. It's guaranteed to be unique across all -// racks and servers for as long as a given universe persists. -//----------------------------------------------------------------------------- -// NOTE: for GID parsing/rendering and other utils, see gid.h -typedef uint64 GID_t; - -const GID_t k_GIDNil = 0xffffffffffffffffull; - -// For convenience, we define a number of types that are just new names for GIDs -typedef GID_t JobID_t; // Each Job has a unique ID -typedef GID_t TxnID_t; // Each financial transaction has a unique ID - -const GID_t k_TxnIDNil = k_GIDNil; -const GID_t k_TxnIDUnknown = 0; - -// this is baked into client messages and interfaces as an int, -// make sure we never break this. AppIds and DepotIDs also presently -// share the same namespace, but since we'd like to change that in the future -// I've defined it seperately here. -typedef uint32 AppId_t; -typedef uint32 PackageId_t; -typedef uint32 DepotId_t; - -const AppId_t k_uAppIdInvalid = 0x0; - -const PackageId_t k_uPackageIdFreeSub = 0x0; -const PackageId_t k_uPackageIdInvalid = 0xFFFFFFFF; -const PackageId_t k_uPackageIdWallet = -2; -const PackageId_t k_uPackageIdMicroTxn = -3; - -const DepotId_t k_uDepotIdInvalid = 0x0; - - -typedef uint32 CellID_t; -const CellID_t k_uCellIDInvalid = 0xFFFFFFFF; - -// handle to a Steam API call -typedef uint64 SteamAPICall_t; -const SteamAPICall_t k_uAPICallInvalid = 0x0; - - -// handle to a communication pipe to the Steam client -typedef int32 HSteamPipe; -// handle to single instance of a steam user -typedef int32 HSteamUser; -// reference to a steam call, to filter results by -typedef int32 HSteamCall; - -// return type of GetAuthSessionTicket -typedef uint32 HAuthTicket; -const HAuthTicket k_HAuthTicketInvalid = 0; - -typedef int HVoiceCall; - - -const int k_cchSystemIMTextMax = 4096; - - - -// RTime32 -// We use this 32 bit time representing real world time. -// It offers 1 second resolution beginning on January 1, 1970 (Unix time) -typedef uint32 RTime32; -const RTime32 k_RTime32Nil = 0; -const RTime32 k_RTime32MinValid = 10; -const RTime32 k_RTime32Infinite = 0x7FFFFFFF; - - - -const uint32 k_nMagic = 0x31305356; // "VS01" -const uint32 k_nMagic_Old1 = 0x4D545356; // "VSTM" - -const uint32 k_cchTruncatedPassword = 20; -const uint32 k_cchAccountName = 64; - -const uint32 k_nChallengeMask = 0xA426DF2B; -const uint32 k_nObfuscationMask = 0xBAADF00D; - - -// General result codes -enum EResult -{ - k_EResultOK = 1, // success - k_EResultFail = 2, // generic failure - k_EResultNoConnection = 3, // no/failed network connection - // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed - k_EResultInvalidPassword = 5, // password/ticket is invalid - k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere - k_EResultInvalidProtocolVer = 7, // protocol version is incorrect - k_EResultInvalidParam = 8, // a parameter is incorrect - k_EResultFileNotFound = 9, // file was not found - k_EResultBusy = 10, // called method busy - action not taken - k_EResultInvalidState = 11, // called object was in an invalid state - k_EResultInvalidName = 12, // name is invalid - k_EResultInvalidEmail = 13, // email is invalid - k_EResultDuplicateName = 14, // name is not unique - k_EResultAccessDenied = 15, // access is denied - k_EResultTimeout = 16, // operation timed out - k_EResultBanned = 17, // VAC2 banned - k_EResultAccountNotFound = 18, // account not found - k_EResultInvalidSteamID = 19, // steamID is invalid - k_EResultServiceUnavailable = 20, // The requested service is currently unavailable - k_EResultNotLoggedOn = 21, // The user is not logged on - k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party) - k_EResultEncryptionFailure = 23, // Encryption or Decryption failed - k_EResultInsufficientPrivilege = 24, // Insufficient privilege - k_EResultLimitExceeded = 25, // Too much of a good thing - k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes) - k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired - k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again - k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time - k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user - k_EResultIPNotFound = 31, // IP address not found - k_EResultPersistFailed = 32, // failed to write change to the data store - k_EResultLockingFailed = 33, // failed to acquire access lock for this operation - k_EResultLogonSessionReplaced = 34, - k_EResultConnectFailed = 35, - k_EResultHandshakeFailed = 36, - k_EResultIOFailure = 37, - k_EResultRemoteDisconnect = 38, - k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested - k_EResultBlocked = 40, // a user didn't allow it - k_EResultIgnored = 41, // target is ignoring sender - k_EResultNoMatch = 42, // nothing matching the request found - k_EResultAccountDisabled = 43, - k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now - k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available - k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin - k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol. - k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another. - k_EResultPasswordRequiredToKickSession = 49, // You are already logged in elsewhere, this cached credential login has failed. - k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait - k_EResultSuspended = 51, - k_EResultCancelled = 52, - k_EResultDataCorruption = 53, - k_EResultDiskFull = 54, - k_EResultRemoteCallFailed = 55, - -}; - - -//----------------------------------------------------------------------------- -// Purpose: Base values for callback identifiers, each callback must -// have a unique ID. -//----------------------------------------------------------------------------- -enum ECallbackType -{ - k_iSteamUserCallbacks = 100, - k_iSteamGameServerCallbacks = 200, - k_iSteamFriendsCallbacks = 300, - k_iSteamBillingCallbacks = 400, - k_iSteamMatchmakingCallbacks = 500, - k_iSteamContentServerCallbacks = 600, - k_iSteamUtilsCallbacks = 700, - k_iClientFriendsCallbacks = 800, - k_iClientUserCallbacks = 900, - k_iSteamAppsCallbacks = 1000, - k_iSteamUserStatsCallbacks = 1100, - k_iSteamNetworkingCallbacks = 1200, - k_iClientRemoteStorageCallbacks = 1300, - k_iSteamUserItemsCallbacks = 1400, - k_iSteamGameServerItemsCallbacks = 1500, - k_iClientUtilsCallbacks = 1600, - k_iSteamGameCoordinatorCallbacks = 1700, - k_iSteamGameServerStatsCallbacks = 1800, - k_iSteam2AsyncCallbacks = 1900, - k_iSteamGameStatsCallbacks = 2000, - k_iClientHTTPCallbacks = 2100 -}; - -// Each Steam instance (licensed Steam Service Provider) has a unique SteamInstanceID_t. -// -// Each Steam instance as its own DB of users. -// Each user in the DB has a unique SteamLocalUserID_t (a serial number, with possible -// rare gaps in the sequence). - -typedef unsigned short SteamInstanceID_t; // MUST be 16 bits - -#if defined (WIN32) - typedef unsigned __int64 SteamLocalUserID_t; // MUST be 64 bits -#else - typedef unsigned long long SteamLocalUserID_t; // MUST be 64 bits -#endif - - - - - - -// Applications need to be able to authenticate Steam users from ANY instance. -// So a SteamIDTicket contains SteamGlobalUserID, which is a unique combination of -// instance and user id. - -// SteamLocalUserID is an unsigned 64-bit integer. -// For platforms without 64-bit int support, we provide access via a union that splits it into -// high and low unsigned 32-bit ints. Such platforms will only need to compare LocalUserIDs -// for equivalence anyway - not perform arithmetic with them. -struct TSteamSplitLocalUserID -{ - unsigned int Low32bits; - unsigned int High32bits; -}; - -struct TSteamGlobalUserID -{ - SteamInstanceID_t m_SteamInstanceID; - - union m_SteamLocalUserID - { - SteamLocalUserID_t As64bits; - TSteamSplitLocalUserID Split; - } m_SteamLocalUserID; - -}; - -// structure that contains client callback data -struct CallbackMsg_t -{ - HSteamUser m_hSteamUser; - int m_iCallback; - uint8 *m_pubParam; - int m_cubParam; -}; - -#endif // !STEAMTYPES_H_ diff --git a/Resources/NetHook/steam/udppkt.h b/Resources/NetHook/steam/udppkt.h deleted file mode 100644 index 551f9486..00000000 --- a/Resources/NetHook/steam/udppkt.h +++ /dev/null @@ -1,121 +0,0 @@ - -#ifndef UDPPKT_H_ -#define UDPPKT_H_ -#ifdef _WIN32 -#pragma once -#endif - -#include "steamtypes.h" - -#include "csteamid.h" -#include "emsg.h" - -const uint32 k_uNetFlagNoIOCP = 1; -const uint32 k_uNetFlagFindAvailPort = 2; -const uint32 k_uNetFlagUseAuthentication = 4; -const uint32 k_uNetFlagUseEncryption = 8; -const uint32 k_uNetFlagRawStream = 16; -const uint32 k_uNetFlagRawStreamSend = 32; -const uint32 k_uNetFlagUnboundSocket = 64; -const uint32 k_uNetFlagRawIORecv = 128; - -const uint32 k_uNetFlagsKeyCallbackRequired = k_uNetFlagUseAuthentication | k_uNetFlagUseEncryption; // 12 - -enum EUDPPktType -{ - // This is the first packet type sent to Steam servers by the client. - // The client iterates through approximately 20 servers in an attempt to find the "best" one. - // Only the UDPPktType, local connection ID and outgoing sequence need to be given an appropriate value to request a challenge. - k_EUDPPktTypeChallengeReq = 1, - - // Steam servers respond to k_EUDPPktTypeChallengeReq with this packet type value and 8 bytes of information. - // The data is not encrypted. - // The first 4 bytes are the 'base' challenge which is used in k_EUDPPktTypeConnect after going through some changes. - // The next 4 bytes are unconfirmed, but they may be involved in the process of generating the actual challenge value used by the client. - k_EUDPPktTypeChallenge = 2, - - // The client sends this packet type after choosing the "best" Steam server available. - // A challenge is attached which is derived from the challenge in k_EUDPPktTypeChallenge. - // The instruction "XOR EDI, A426DF2B" is executed, EDI being the challenge, however this is not always the correct value and can be offset by small amounts. - // The Steam client uses the flag 4 when sending this, so assume it is necessary. - // UDPPktHdr should be filled in as normal but without encryption on the data. - k_EUDPPktTypeConnect = 3, - - // If the k_EUDPPktTypeConnect packet is received by the destination server and acknowledged as valid then it responds with this packet type. - // No data is attached, however a destination connection ID is generated and should be stored for use in later traffic. - // The Steam client uses the flag 4 when sending this, so assume it is necessary. - k_EUDPPktTypeAccept = 4, - - // Unknown, most likely sent to signify process termination. - k_EUDPPktTypeDisconnect = 5, - - // This packet type is used for the majority of VS01 traffic, incoming and outgoing. - // The flag is usually 4, however this is not confirmed as necessary or constant. - // The packet should include valid destination and source connection IDs. - // Not all data sent through this type is encrypted and it's currently unclear what indicates when it is and when it isn't. - k_EUDPPktTypeData = 6, - - // The datagram message type appears to be used for a packet resend. - // Sometimes the sequence number isn't included, but message size is. - // Sometimes the sequence number is included, but message size isn't. - // Sequence number may be replaced by size in the case of the seq value being incremented between initial send time and retry time. - k_EUDPPktTypeDatagram = 7, - - // Max enum value. - k_EUDPPktTypeMax = 8, -}; - -#pragma pack( push, 1 ) - -struct UDPPktHdr_t -{ - uint32 m_nMagic; // "VS01" or "VT01" - - uint16 m_cbPkt; - - uint8 m_EUDPPktType; // EUDPPktType - - uint8 m_nFlags; // NetFlags - - uint32 m_nSrcConnectionID; - uint32 m_nDstConnectionID; - - uint32 m_nSeqThis; - uint32 m_nSeqAcked; - - uint32 m_nPktsInMsg; - uint32 m_nMsgStartSeq; - - uint32 m_cbMsgData; -}; - -struct MsgHdr_t -{ - int32 m_EMsg; // EMsg - - JobID_t m_JobIDTarget; - JobID_t m_JobIDSource; -}; - -struct ExtendedClientMsgHdr_t -{ - int32 m_EMsg; // EMsg - - uint8 m_nCubHdr; - - uint16 m_nHdrVersion; - - JobID_t m_JobIDTarget; - JobID_t m_JobIDSource; - - uint8 m_nHdrCanary; - - CSteamID m_ulSteamID; - - int32 m_nSessionID; -}; - -#pragma pack( pop ) - - -#endif // !UDPPKT_H_ diff --git a/Resources/NetHook/steammessages_base.pb.cc b/Resources/NetHook/steammessages_base.pb.cc deleted file mode 100644 index e054793e..00000000 --- a/Resources/NetHook/steammessages_base.pb.cc +++ /dev/null @@ -1,1289 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "steammessages_base.pb.h" -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace { - -const ::google::protobuf::Descriptor* CMsgProtoBufHeader_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - CMsgProtoBufHeader_reflection_ = NULL; -const ::google::protobuf::Descriptor* CMsgMulti_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - CMsgMulti_reflection_ = NULL; -const ::google::protobuf::Descriptor* CMsgAuthTicket_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - CMsgAuthTicket_reflection_ = NULL; - -} // namespace - - -void protobuf_AssignDesc_steammessages_5fbase_2eproto() { - protobuf_AddDesc_steammessages_5fbase_2eproto(); - const ::google::protobuf::FileDescriptor* file = - ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "steammessages_base.proto"); - GOOGLE_CHECK(file != NULL); - CMsgProtoBufHeader_descriptor_ = file->message_type(0); - static const int CMsgProtoBufHeader_offsets_[6] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, client_steam_id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, client_session_id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, routing_appid_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, job_id_source_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, job_id_target_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, target_job_name_), - }; - CMsgProtoBufHeader_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - CMsgProtoBufHeader_descriptor_, - CMsgProtoBufHeader::default_instance_, - CMsgProtoBufHeader_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgProtoBufHeader, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(CMsgProtoBufHeader)); - CMsgMulti_descriptor_ = file->message_type(1); - static const int CMsgMulti_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgMulti, size_unzipped_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgMulti, message_body_), - }; - CMsgMulti_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - CMsgMulti_descriptor_, - CMsgMulti::default_instance_, - CMsgMulti_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgMulti, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgMulti, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(CMsgMulti)); - CMsgAuthTicket_descriptor_ = file->message_type(2); - static const int CMsgAuthTicket_offsets_[7] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, estate_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, eresult_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, steam_id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, game_id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, h_steam_pipe_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, ticket_crc_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, ticket_), - }; - CMsgAuthTicket_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - CMsgAuthTicket_descriptor_, - CMsgAuthTicket::default_instance_, - CMsgAuthTicket_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CMsgAuthTicket, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(CMsgAuthTicket)); -} - -namespace { - -GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); -inline void protobuf_AssignDescriptorsOnce() { - ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_steammessages_5fbase_2eproto); -} - -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - CMsgProtoBufHeader_descriptor_, &CMsgProtoBufHeader::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - CMsgMulti_descriptor_, &CMsgMulti::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - CMsgAuthTicket_descriptor_, &CMsgAuthTicket::default_instance()); -} - -} // namespace - -void protobuf_ShutdownFile_steammessages_5fbase_2eproto() { - delete CMsgProtoBufHeader::default_instance_; - delete CMsgProtoBufHeader_reflection_; - delete CMsgMulti::default_instance_; - delete CMsgMulti_reflection_; - delete CMsgAuthTicket::default_instance_; - delete CMsgAuthTicket_reflection_; -} - -void protobuf_AddDesc_steammessages_5fbase_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\030steammessages_base.proto\"\322\001\n\022CMsgProto" - "BufHeader\022\027\n\017client_steam_id\030\001 \001(\006\022\031\n\021cl" - "ient_session_id\030\002 \001(\005\022\025\n\rrouting_appid\030\003" - " \001(\r\022+\n\rjob_id_source\030\n \001(\006:\02418446744073" - "709551615\022+\n\rjob_id_target\030\013 \001(\006:\024184467" - "44073709551615\022\027\n\017target_job_name\030\014 \001(\t\"" - "8\n\tCMsgMulti\022\025\n\rsize_unzipped\030\001 \001(\r\022\024\n\014m" - "essage_body\030\002 \001(\014\"\221\001\n\016CMsgAuthTicket\022\016\n\006" - "estate\030\001 \001(\r\022\022\n\007eresult\030\002 \001(\r:\0012\022\020\n\010stea" - "m_id\030\003 \001(\006\022\017\n\007game_id\030\004 \001(\006\022\024\n\014h_steam_p" - "ipe\030\005 \001(\r\022\022\n\nticket_crc\030\006 \001(\r\022\016\n\006ticket\030" - "\007 \001(\014", 445); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "steammessages_base.proto", &protobuf_RegisterTypes); - CMsgProtoBufHeader::default_instance_ = new CMsgProtoBufHeader(); - CMsgMulti::default_instance_ = new CMsgMulti(); - CMsgAuthTicket::default_instance_ = new CMsgAuthTicket(); - CMsgProtoBufHeader::default_instance_->InitAsDefaultInstance(); - CMsgMulti::default_instance_->InitAsDefaultInstance(); - CMsgAuthTicket::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_steammessages_5fbase_2eproto); -} - -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_steammessages_5fbase_2eproto { - StaticDescriptorInitializer_steammessages_5fbase_2eproto() { - protobuf_AddDesc_steammessages_5fbase_2eproto(); - } -} static_descriptor_initializer_steammessages_5fbase_2eproto_; - - -// =================================================================== - -const ::std::string CMsgProtoBufHeader::_default_target_job_name_; -#ifndef _MSC_VER -const int CMsgProtoBufHeader::kClientSteamIdFieldNumber; -const int CMsgProtoBufHeader::kClientSessionIdFieldNumber; -const int CMsgProtoBufHeader::kRoutingAppidFieldNumber; -const int CMsgProtoBufHeader::kJobIdSourceFieldNumber; -const int CMsgProtoBufHeader::kJobIdTargetFieldNumber; -const int CMsgProtoBufHeader::kTargetJobNameFieldNumber; -#endif // !_MSC_VER - -CMsgProtoBufHeader::CMsgProtoBufHeader() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void CMsgProtoBufHeader::InitAsDefaultInstance() { -} - -CMsgProtoBufHeader::CMsgProtoBufHeader(const CMsgProtoBufHeader& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void CMsgProtoBufHeader::SharedCtor() { - _cached_size_ = 0; - client_steam_id_ = GOOGLE_ULONGLONG(0); - client_session_id_ = 0; - routing_appid_ = 0u; - job_id_source_ = GOOGLE_ULONGLONG(18446744073709551615); - job_id_target_ = GOOGLE_ULONGLONG(18446744073709551615); - target_job_name_ = const_cast< ::std::string*>(&_default_target_job_name_); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -CMsgProtoBufHeader::~CMsgProtoBufHeader() { - SharedDtor(); -} - -void CMsgProtoBufHeader::SharedDtor() { - if (target_job_name_ != &_default_target_job_name_) { - delete target_job_name_; - } - if (this != default_instance_) { - } -} - -void CMsgProtoBufHeader::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* CMsgProtoBufHeader::descriptor() { - protobuf_AssignDescriptorsOnce(); - return CMsgProtoBufHeader_descriptor_; -} - -const CMsgProtoBufHeader& CMsgProtoBufHeader::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_steammessages_5fbase_2eproto(); return *default_instance_; -} - -CMsgProtoBufHeader* CMsgProtoBufHeader::default_instance_ = NULL; - -CMsgProtoBufHeader* CMsgProtoBufHeader::New() const { - return new CMsgProtoBufHeader; -} - -void CMsgProtoBufHeader::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - client_steam_id_ = GOOGLE_ULONGLONG(0); - client_session_id_ = 0; - routing_appid_ = 0u; - job_id_source_ = GOOGLE_ULONGLONG(18446744073709551615); - job_id_target_ = GOOGLE_ULONGLONG(18446744073709551615); - if (_has_bit(5)) { - if (target_job_name_ != &_default_target_job_name_) { - target_job_name_->clear(); - } - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool CMsgProtoBufHeader::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional fixed64 client_steam_id = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( - input, &client_steam_id_))); - _set_bit(0); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_client_session_id; - break; - } - - // optional int32 client_session_id = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_client_session_id: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( - input, &client_session_id_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(24)) goto parse_routing_appid; - break; - } - - // optional uint32 routing_appid = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_routing_appid: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &routing_appid_))); - _set_bit(2); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(81)) goto parse_job_id_source; - break; - } - - // optional fixed64 job_id_source = 10 [default = 18446744073709551615]; - case 10: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_job_id_source: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( - input, &job_id_source_))); - _set_bit(3); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(89)) goto parse_job_id_target; - break; - } - - // optional fixed64 job_id_target = 11 [default = 18446744073709551615]; - case 11: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_job_id_target: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( - input, &job_id_target_))); - _set_bit(4); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(98)) goto parse_target_job_name; - break; - } - - // optional string target_job_name = 12; - case 12: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_target_job_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_target_job_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->target_job_name().data(), this->target_job_name().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void CMsgProtoBufHeader::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional fixed64 client_steam_id = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->client_steam_id(), output); - } - - // optional int32 client_session_id = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->client_session_id(), output); - } - - // optional uint32 routing_appid = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->routing_appid(), output); - } - - // optional fixed64 job_id_source = 10 [default = 18446744073709551615]; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteFixed64(10, this->job_id_source(), output); - } - - // optional fixed64 job_id_target = 11 [default = 18446744073709551615]; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormatLite::WriteFixed64(11, this->job_id_target(), output); - } - - // optional string target_job_name = 12; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->target_job_name().data(), this->target_job_name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 12, this->target_job_name(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* CMsgProtoBufHeader::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional fixed64 client_steam_id = 1; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->client_steam_id(), target); - } - - // optional int32 client_session_id = 2; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->client_session_id(), target); - } - - // optional uint32 routing_appid = 3; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->routing_appid(), target); - } - - // optional fixed64 job_id_source = 10 [default = 18446744073709551615]; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(10, this->job_id_source(), target); - } - - // optional fixed64 job_id_target = 11 [default = 18446744073709551615]; - if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(11, this->job_id_target(), target); - } - - // optional string target_job_name = 12; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->target_job_name().data(), this->target_job_name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 12, this->target_job_name(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int CMsgProtoBufHeader::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional fixed64 client_steam_id = 1; - if (has_client_steam_id()) { - total_size += 1 + 8; - } - - // optional int32 client_session_id = 2; - if (has_client_session_id()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size( - this->client_session_id()); - } - - // optional uint32 routing_appid = 3; - if (has_routing_appid()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->routing_appid()); - } - - // optional fixed64 job_id_source = 10 [default = 18446744073709551615]; - if (has_job_id_source()) { - total_size += 1 + 8; - } - - // optional fixed64 job_id_target = 11 [default = 18446744073709551615]; - if (has_job_id_target()) { - total_size += 1 + 8; - } - - // optional string target_job_name = 12; - if (has_target_job_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->target_job_name()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void CMsgProtoBufHeader::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const CMsgProtoBufHeader* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void CMsgProtoBufHeader::MergeFrom(const CMsgProtoBufHeader& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_client_steam_id(from.client_steam_id()); - } - if (from._has_bit(1)) { - set_client_session_id(from.client_session_id()); - } - if (from._has_bit(2)) { - set_routing_appid(from.routing_appid()); - } - if (from._has_bit(3)) { - set_job_id_source(from.job_id_source()); - } - if (from._has_bit(4)) { - set_job_id_target(from.job_id_target()); - } - if (from._has_bit(5)) { - set_target_job_name(from.target_job_name()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void CMsgProtoBufHeader::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void CMsgProtoBufHeader::CopyFrom(const CMsgProtoBufHeader& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool CMsgProtoBufHeader::IsInitialized() const { - - return true; -} - -void CMsgProtoBufHeader::Swap(CMsgProtoBufHeader* other) { - if (other != this) { - std::swap(client_steam_id_, other->client_steam_id_); - std::swap(client_session_id_, other->client_session_id_); - std::swap(routing_appid_, other->routing_appid_); - std::swap(job_id_source_, other->job_id_source_); - std::swap(job_id_target_, other->job_id_target_); - std::swap(target_job_name_, other->target_job_name_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata CMsgProtoBufHeader::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = CMsgProtoBufHeader_descriptor_; - metadata.reflection = CMsgProtoBufHeader_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string CMsgMulti::_default_message_body_; -#ifndef _MSC_VER -const int CMsgMulti::kSizeUnzippedFieldNumber; -const int CMsgMulti::kMessageBodyFieldNumber; -#endif // !_MSC_VER - -CMsgMulti::CMsgMulti() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void CMsgMulti::InitAsDefaultInstance() { -} - -CMsgMulti::CMsgMulti(const CMsgMulti& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void CMsgMulti::SharedCtor() { - _cached_size_ = 0; - size_unzipped_ = 0u; - message_body_ = const_cast< ::std::string*>(&_default_message_body_); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -CMsgMulti::~CMsgMulti() { - SharedDtor(); -} - -void CMsgMulti::SharedDtor() { - if (message_body_ != &_default_message_body_) { - delete message_body_; - } - if (this != default_instance_) { - } -} - -void CMsgMulti::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* CMsgMulti::descriptor() { - protobuf_AssignDescriptorsOnce(); - return CMsgMulti_descriptor_; -} - -const CMsgMulti& CMsgMulti::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_steammessages_5fbase_2eproto(); return *default_instance_; -} - -CMsgMulti* CMsgMulti::default_instance_ = NULL; - -CMsgMulti* CMsgMulti::New() const { - return new CMsgMulti; -} - -void CMsgMulti::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - size_unzipped_ = 0u; - if (_has_bit(1)) { - if (message_body_ != &_default_message_body_) { - message_body_->clear(); - } - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool CMsgMulti::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 size_unzipped = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &size_unzipped_))); - _set_bit(0); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(18)) goto parse_message_body; - break; - } - - // optional bytes message_body = 2; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_message_body: - DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( - input, this->mutable_message_body())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void CMsgMulti::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional uint32 size_unzipped = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->size_unzipped(), output); - } - - // optional bytes message_body = 2; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteBytes( - 2, this->message_body(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* CMsgMulti::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional uint32 size_unzipped = 1; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->size_unzipped(), target); - } - - // optional bytes message_body = 2; - if (_has_bit(1)) { - target = - ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( - 2, this->message_body(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int CMsgMulti::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional uint32 size_unzipped = 1; - if (has_size_unzipped()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->size_unzipped()); - } - - // optional bytes message_body = 2; - if (has_message_body()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->message_body()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void CMsgMulti::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const CMsgMulti* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void CMsgMulti::MergeFrom(const CMsgMulti& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_size_unzipped(from.size_unzipped()); - } - if (from._has_bit(1)) { - set_message_body(from.message_body()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void CMsgMulti::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void CMsgMulti::CopyFrom(const CMsgMulti& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool CMsgMulti::IsInitialized() const { - - return true; -} - -void CMsgMulti::Swap(CMsgMulti* other) { - if (other != this) { - std::swap(size_unzipped_, other->size_unzipped_); - std::swap(message_body_, other->message_body_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata CMsgMulti::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = CMsgMulti_descriptor_; - metadata.reflection = CMsgMulti_reflection_; - return metadata; -} - - -// =================================================================== - -const ::std::string CMsgAuthTicket::_default_ticket_; -#ifndef _MSC_VER -const int CMsgAuthTicket::kEstateFieldNumber; -const int CMsgAuthTicket::kEresultFieldNumber; -const int CMsgAuthTicket::kSteamIdFieldNumber; -const int CMsgAuthTicket::kGameIdFieldNumber; -const int CMsgAuthTicket::kHSteamPipeFieldNumber; -const int CMsgAuthTicket::kTicketCrcFieldNumber; -const int CMsgAuthTicket::kTicketFieldNumber; -#endif // !_MSC_VER - -CMsgAuthTicket::CMsgAuthTicket() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void CMsgAuthTicket::InitAsDefaultInstance() { -} - -CMsgAuthTicket::CMsgAuthTicket(const CMsgAuthTicket& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void CMsgAuthTicket::SharedCtor() { - _cached_size_ = 0; - estate_ = 0u; - eresult_ = 2u; - steam_id_ = GOOGLE_ULONGLONG(0); - game_id_ = GOOGLE_ULONGLONG(0); - h_steam_pipe_ = 0u; - ticket_crc_ = 0u; - ticket_ = const_cast< ::std::string*>(&_default_ticket_); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -CMsgAuthTicket::~CMsgAuthTicket() { - SharedDtor(); -} - -void CMsgAuthTicket::SharedDtor() { - if (ticket_ != &_default_ticket_) { - delete ticket_; - } - if (this != default_instance_) { - } -} - -void CMsgAuthTicket::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* CMsgAuthTicket::descriptor() { - protobuf_AssignDescriptorsOnce(); - return CMsgAuthTicket_descriptor_; -} - -const CMsgAuthTicket& CMsgAuthTicket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_steammessages_5fbase_2eproto(); return *default_instance_; -} - -CMsgAuthTicket* CMsgAuthTicket::default_instance_ = NULL; - -CMsgAuthTicket* CMsgAuthTicket::New() const { - return new CMsgAuthTicket; -} - -void CMsgAuthTicket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - estate_ = 0u; - eresult_ = 2u; - steam_id_ = GOOGLE_ULONGLONG(0); - game_id_ = GOOGLE_ULONGLONG(0); - h_steam_pipe_ = 0u; - ticket_crc_ = 0u; - if (_has_bit(6)) { - if (ticket_ != &_default_ticket_) { - ticket_->clear(); - } - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool CMsgAuthTicket::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint32 estate = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &estate_))); - _set_bit(0); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(16)) goto parse_eresult; - break; - } - - // optional uint32 eresult = 2 [default = 2]; - case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_eresult: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &eresult_))); - _set_bit(1); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(25)) goto parse_steam_id; - break; - } - - // optional fixed64 steam_id = 3; - case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_steam_id: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( - input, &steam_id_))); - _set_bit(2); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(33)) goto parse_game_id; - break; - } - - // optional fixed64 game_id = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { - parse_game_id: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( - input, &game_id_))); - _set_bit(3); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(40)) goto parse_h_steam_pipe; - break; - } - - // optional uint32 h_steam_pipe = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_h_steam_pipe: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &h_steam_pipe_))); - _set_bit(4); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(48)) goto parse_ticket_crc; - break; - } - - // optional uint32 ticket_crc = 6; - case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - parse_ticket_crc: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &ticket_crc_))); - _set_bit(5); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(58)) goto parse_ticket; - break; - } - - // optional bytes ticket = 7; - case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_ticket: - DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( - input, this->mutable_ticket())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void CMsgAuthTicket::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // optional uint32 estate = 1; - if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->estate(), output); - } - - // optional uint32 eresult = 2 [default = 2]; - if (_has_bit(1)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->eresult(), output); - } - - // optional fixed64 steam_id = 3; - if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->steam_id(), output); - } - - // optional fixed64 game_id = 4; - if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->game_id(), output); - } - - // optional uint32 h_steam_pipe = 5; - if (_has_bit(4)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->h_steam_pipe(), output); - } - - // optional uint32 ticket_crc = 6; - if (_has_bit(5)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->ticket_crc(), output); - } - - // optional bytes ticket = 7; - if (_has_bit(6)) { - ::google::protobuf::internal::WireFormatLite::WriteBytes( - 7, this->ticket(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* CMsgAuthTicket::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // optional uint32 estate = 1; - if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->estate(), target); - } - - // optional uint32 eresult = 2 [default = 2]; - if (_has_bit(1)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->eresult(), target); - } - - // optional fixed64 steam_id = 3; - if (_has_bit(2)) { - target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->steam_id(), target); - } - - // optional fixed64 game_id = 4; - if (_has_bit(3)) { - target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->game_id(), target); - } - - // optional uint32 h_steam_pipe = 5; - if (_has_bit(4)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->h_steam_pipe(), target); - } - - // optional uint32 ticket_crc = 6; - if (_has_bit(5)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->ticket_crc(), target); - } - - // optional bytes ticket = 7; - if (_has_bit(6)) { - target = - ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( - 7, this->ticket(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int CMsgAuthTicket::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional uint32 estate = 1; - if (has_estate()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->estate()); - } - - // optional uint32 eresult = 2 [default = 2]; - if (has_eresult()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->eresult()); - } - - // optional fixed64 steam_id = 3; - if (has_steam_id()) { - total_size += 1 + 8; - } - - // optional fixed64 game_id = 4; - if (has_game_id()) { - total_size += 1 + 8; - } - - // optional uint32 h_steam_pipe = 5; - if (has_h_steam_pipe()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->h_steam_pipe()); - } - - // optional uint32 ticket_crc = 6; - if (has_ticket_crc()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->ticket_crc()); - } - - // optional bytes ticket = 7; - if (has_ticket()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->ticket()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void CMsgAuthTicket::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const CMsgAuthTicket* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void CMsgAuthTicket::MergeFrom(const CMsgAuthTicket& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_estate(from.estate()); - } - if (from._has_bit(1)) { - set_eresult(from.eresult()); - } - if (from._has_bit(2)) { - set_steam_id(from.steam_id()); - } - if (from._has_bit(3)) { - set_game_id(from.game_id()); - } - if (from._has_bit(4)) { - set_h_steam_pipe(from.h_steam_pipe()); - } - if (from._has_bit(5)) { - set_ticket_crc(from.ticket_crc()); - } - if (from._has_bit(6)) { - set_ticket(from.ticket()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void CMsgAuthTicket::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void CMsgAuthTicket::CopyFrom(const CMsgAuthTicket& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool CMsgAuthTicket::IsInitialized() const { - - return true; -} - -void CMsgAuthTicket::Swap(CMsgAuthTicket* other) { - if (other != this) { - std::swap(estate_, other->estate_); - std::swap(eresult_, other->eresult_); - std::swap(steam_id_, other->steam_id_); - std::swap(game_id_, other->game_id_); - std::swap(h_steam_pipe_, other->h_steam_pipe_); - std::swap(ticket_crc_, other->ticket_crc_); - std::swap(ticket_, other->ticket_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata CMsgAuthTicket::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = CMsgAuthTicket_descriptor_; - metadata.reflection = CMsgAuthTicket_reflection_; - return metadata; -} - - -// @@protoc_insertion_point(namespace_scope) - -// @@protoc_insertion_point(global_scope) diff --git a/Resources/NetHook/steammessages_base.pb.h b/Resources/NetHook/steammessages_base.pb.h deleted file mode 100644 index eb17d9ce..00000000 --- a/Resources/NetHook/steammessages_base.pb.h +++ /dev/null @@ -1,759 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: steammessages_base.proto - -#ifndef PROTOBUF_steammessages_5fbase_2eproto__INCLUDED -#define PROTOBUF_steammessages_5fbase_2eproto__INCLUDED - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 2003000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -// Internal implementation detail -- do not call these. -void protobuf_AddDesc_steammessages_5fbase_2eproto(); -void protobuf_AssignDesc_steammessages_5fbase_2eproto(); -void protobuf_ShutdownFile_steammessages_5fbase_2eproto(); - -class CMsgProtoBufHeader; -class CMsgMulti; -class CMsgAuthTicket; - -// =================================================================== - -class CMsgProtoBufHeader : public ::google::protobuf::Message { - public: - CMsgProtoBufHeader(); - virtual ~CMsgProtoBufHeader(); - - CMsgProtoBufHeader(const CMsgProtoBufHeader& from); - - inline CMsgProtoBufHeader& operator=(const CMsgProtoBufHeader& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const CMsgProtoBufHeader& default_instance(); - - void Swap(CMsgProtoBufHeader* other); - - // implements Message ---------------------------------------------- - - CMsgProtoBufHeader* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const CMsgProtoBufHeader& from); - void MergeFrom(const CMsgProtoBufHeader& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional fixed64 client_steam_id = 1; - inline bool has_client_steam_id() const; - inline void clear_client_steam_id(); - static const int kClientSteamIdFieldNumber = 1; - inline ::google::protobuf::uint64 client_steam_id() const; - inline void set_client_steam_id(::google::protobuf::uint64 value); - - // optional int32 client_session_id = 2; - inline bool has_client_session_id() const; - inline void clear_client_session_id(); - static const int kClientSessionIdFieldNumber = 2; - inline ::google::protobuf::int32 client_session_id() const; - inline void set_client_session_id(::google::protobuf::int32 value); - - // optional uint32 routing_appid = 3; - inline bool has_routing_appid() const; - inline void clear_routing_appid(); - static const int kRoutingAppidFieldNumber = 3; - inline ::google::protobuf::uint32 routing_appid() const; - inline void set_routing_appid(::google::protobuf::uint32 value); - - // optional fixed64 job_id_source = 10 [default = 18446744073709551615]; - inline bool has_job_id_source() const; - inline void clear_job_id_source(); - static const int kJobIdSourceFieldNumber = 10; - inline ::google::protobuf::uint64 job_id_source() const; - inline void set_job_id_source(::google::protobuf::uint64 value); - - // optional fixed64 job_id_target = 11 [default = 18446744073709551615]; - inline bool has_job_id_target() const; - inline void clear_job_id_target(); - static const int kJobIdTargetFieldNumber = 11; - inline ::google::protobuf::uint64 job_id_target() const; - inline void set_job_id_target(::google::protobuf::uint64 value); - - // optional string target_job_name = 12; - inline bool has_target_job_name() const; - inline void clear_target_job_name(); - static const int kTargetJobNameFieldNumber = 12; - inline const ::std::string& target_job_name() const; - inline void set_target_job_name(const ::std::string& value); - inline void set_target_job_name(const char* value); - inline void set_target_job_name(const char* value, size_t size); - inline ::std::string* mutable_target_job_name(); - - // @@protoc_insertion_point(class_scope:CMsgProtoBufHeader) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::uint64 client_steam_id_; - ::google::protobuf::int32 client_session_id_; - ::google::protobuf::uint32 routing_appid_; - ::google::protobuf::uint64 job_id_source_; - ::google::protobuf::uint64 job_id_target_; - ::std::string* target_job_name_; - static const ::std::string _default_target_job_name_; - friend void protobuf_AddDesc_steammessages_5fbase_2eproto(); - friend void protobuf_AssignDesc_steammessages_5fbase_2eproto(); - friend void protobuf_ShutdownFile_steammessages_5fbase_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static CMsgProtoBufHeader* default_instance_; -}; -// ------------------------------------------------------------------- - -class CMsgMulti : public ::google::protobuf::Message { - public: - CMsgMulti(); - virtual ~CMsgMulti(); - - CMsgMulti(const CMsgMulti& from); - - inline CMsgMulti& operator=(const CMsgMulti& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const CMsgMulti& default_instance(); - - void Swap(CMsgMulti* other); - - // implements Message ---------------------------------------------- - - CMsgMulti* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const CMsgMulti& from); - void MergeFrom(const CMsgMulti& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional uint32 size_unzipped = 1; - inline bool has_size_unzipped() const; - inline void clear_size_unzipped(); - static const int kSizeUnzippedFieldNumber = 1; - inline ::google::protobuf::uint32 size_unzipped() const; - inline void set_size_unzipped(::google::protobuf::uint32 value); - - // optional bytes message_body = 2; - inline bool has_message_body() const; - inline void clear_message_body(); - static const int kMessageBodyFieldNumber = 2; - inline const ::std::string& message_body() const; - inline void set_message_body(const ::std::string& value); - inline void set_message_body(const char* value); - inline void set_message_body(const void* value, size_t size); - inline ::std::string* mutable_message_body(); - - // @@protoc_insertion_point(class_scope:CMsgMulti) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::uint32 size_unzipped_; - ::std::string* message_body_; - static const ::std::string _default_message_body_; - friend void protobuf_AddDesc_steammessages_5fbase_2eproto(); - friend void protobuf_AssignDesc_steammessages_5fbase_2eproto(); - friend void protobuf_ShutdownFile_steammessages_5fbase_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static CMsgMulti* default_instance_; -}; -// ------------------------------------------------------------------- - -class CMsgAuthTicket : public ::google::protobuf::Message { - public: - CMsgAuthTicket(); - virtual ~CMsgAuthTicket(); - - CMsgAuthTicket(const CMsgAuthTicket& from); - - inline CMsgAuthTicket& operator=(const CMsgAuthTicket& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _unknown_fields_; - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return &_unknown_fields_; - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const CMsgAuthTicket& default_instance(); - - void Swap(CMsgAuthTicket* other); - - // implements Message ---------------------------------------------- - - CMsgAuthTicket* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const CMsgAuthTicket& from); - void MergeFrom(const CMsgAuthTicket& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional uint32 estate = 1; - inline bool has_estate() const; - inline void clear_estate(); - static const int kEstateFieldNumber = 1; - inline ::google::protobuf::uint32 estate() const; - inline void set_estate(::google::protobuf::uint32 value); - - // optional uint32 eresult = 2 [default = 2]; - inline bool has_eresult() const; - inline void clear_eresult(); - static const int kEresultFieldNumber = 2; - inline ::google::protobuf::uint32 eresult() const; - inline void set_eresult(::google::protobuf::uint32 value); - - // optional fixed64 steam_id = 3; - inline bool has_steam_id() const; - inline void clear_steam_id(); - static const int kSteamIdFieldNumber = 3; - inline ::google::protobuf::uint64 steam_id() const; - inline void set_steam_id(::google::protobuf::uint64 value); - - // optional fixed64 game_id = 4; - inline bool has_game_id() const; - inline void clear_game_id(); - static const int kGameIdFieldNumber = 4; - inline ::google::protobuf::uint64 game_id() const; - inline void set_game_id(::google::protobuf::uint64 value); - - // optional uint32 h_steam_pipe = 5; - inline bool has_h_steam_pipe() const; - inline void clear_h_steam_pipe(); - static const int kHSteamPipeFieldNumber = 5; - inline ::google::protobuf::uint32 h_steam_pipe() const; - inline void set_h_steam_pipe(::google::protobuf::uint32 value); - - // optional uint32 ticket_crc = 6; - inline bool has_ticket_crc() const; - inline void clear_ticket_crc(); - static const int kTicketCrcFieldNumber = 6; - inline ::google::protobuf::uint32 ticket_crc() const; - inline void set_ticket_crc(::google::protobuf::uint32 value); - - // optional bytes ticket = 7; - inline bool has_ticket() const; - inline void clear_ticket(); - static const int kTicketFieldNumber = 7; - inline const ::std::string& ticket() const; - inline void set_ticket(const ::std::string& value); - inline void set_ticket(const char* value); - inline void set_ticket(const void* value, size_t size); - inline ::std::string* mutable_ticket(); - - // @@protoc_insertion_point(class_scope:CMsgAuthTicket) - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::uint32 estate_; - ::google::protobuf::uint32 eresult_; - ::google::protobuf::uint64 steam_id_; - ::google::protobuf::uint64 game_id_; - ::google::protobuf::uint32 h_steam_pipe_; - ::google::protobuf::uint32 ticket_crc_; - ::std::string* ticket_; - static const ::std::string _default_ticket_; - friend void protobuf_AddDesc_steammessages_5fbase_2eproto(); - friend void protobuf_AssignDesc_steammessages_5fbase_2eproto(); - friend void protobuf_ShutdownFile_steammessages_5fbase_2eproto(); - - ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - - void InitAsDefaultInstance(); - static CMsgAuthTicket* default_instance_; -}; -// =================================================================== - - -// =================================================================== - -// CMsgProtoBufHeader - -// optional fixed64 client_steam_id = 1; -inline bool CMsgProtoBufHeader::has_client_steam_id() const { - return _has_bit(0); -} -inline void CMsgProtoBufHeader::clear_client_steam_id() { - client_steam_id_ = GOOGLE_ULONGLONG(0); - _clear_bit(0); -} -inline ::google::protobuf::uint64 CMsgProtoBufHeader::client_steam_id() const { - return client_steam_id_; -} -inline void CMsgProtoBufHeader::set_client_steam_id(::google::protobuf::uint64 value) { - _set_bit(0); - client_steam_id_ = value; -} - -// optional int32 client_session_id = 2; -inline bool CMsgProtoBufHeader::has_client_session_id() const { - return _has_bit(1); -} -inline void CMsgProtoBufHeader::clear_client_session_id() { - client_session_id_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 CMsgProtoBufHeader::client_session_id() const { - return client_session_id_; -} -inline void CMsgProtoBufHeader::set_client_session_id(::google::protobuf::int32 value) { - _set_bit(1); - client_session_id_ = value; -} - -// optional uint32 routing_appid = 3; -inline bool CMsgProtoBufHeader::has_routing_appid() const { - return _has_bit(2); -} -inline void CMsgProtoBufHeader::clear_routing_appid() { - routing_appid_ = 0u; - _clear_bit(2); -} -inline ::google::protobuf::uint32 CMsgProtoBufHeader::routing_appid() const { - return routing_appid_; -} -inline void CMsgProtoBufHeader::set_routing_appid(::google::protobuf::uint32 value) { - _set_bit(2); - routing_appid_ = value; -} - -// optional fixed64 job_id_source = 10 [default = 18446744073709551615]; -inline bool CMsgProtoBufHeader::has_job_id_source() const { - return _has_bit(3); -} -inline void CMsgProtoBufHeader::clear_job_id_source() { - job_id_source_ = GOOGLE_ULONGLONG(18446744073709551615); - _clear_bit(3); -} -inline ::google::protobuf::uint64 CMsgProtoBufHeader::job_id_source() const { - return job_id_source_; -} -inline void CMsgProtoBufHeader::set_job_id_source(::google::protobuf::uint64 value) { - _set_bit(3); - job_id_source_ = value; -} - -// optional fixed64 job_id_target = 11 [default = 18446744073709551615]; -inline bool CMsgProtoBufHeader::has_job_id_target() const { - return _has_bit(4); -} -inline void CMsgProtoBufHeader::clear_job_id_target() { - job_id_target_ = GOOGLE_ULONGLONG(18446744073709551615); - _clear_bit(4); -} -inline ::google::protobuf::uint64 CMsgProtoBufHeader::job_id_target() const { - return job_id_target_; -} -inline void CMsgProtoBufHeader::set_job_id_target(::google::protobuf::uint64 value) { - _set_bit(4); - job_id_target_ = value; -} - -// optional string target_job_name = 12; -inline bool CMsgProtoBufHeader::has_target_job_name() const { - return _has_bit(5); -} -inline void CMsgProtoBufHeader::clear_target_job_name() { - if (target_job_name_ != &_default_target_job_name_) { - target_job_name_->clear(); - } - _clear_bit(5); -} -inline const ::std::string& CMsgProtoBufHeader::target_job_name() const { - return *target_job_name_; -} -inline void CMsgProtoBufHeader::set_target_job_name(const ::std::string& value) { - _set_bit(5); - if (target_job_name_ == &_default_target_job_name_) { - target_job_name_ = new ::std::string; - } - target_job_name_->assign(value); -} -inline void CMsgProtoBufHeader::set_target_job_name(const char* value) { - _set_bit(5); - if (target_job_name_ == &_default_target_job_name_) { - target_job_name_ = new ::std::string; - } - target_job_name_->assign(value); -} -inline void CMsgProtoBufHeader::set_target_job_name(const char* value, size_t size) { - _set_bit(5); - if (target_job_name_ == &_default_target_job_name_) { - target_job_name_ = new ::std::string; - } - target_job_name_->assign(reinterpret_cast(value), size); -} -inline ::std::string* CMsgProtoBufHeader::mutable_target_job_name() { - _set_bit(5); - if (target_job_name_ == &_default_target_job_name_) { - target_job_name_ = new ::std::string; - } - return target_job_name_; -} - -// ------------------------------------------------------------------- - -// CMsgMulti - -// optional uint32 size_unzipped = 1; -inline bool CMsgMulti::has_size_unzipped() const { - return _has_bit(0); -} -inline void CMsgMulti::clear_size_unzipped() { - size_unzipped_ = 0u; - _clear_bit(0); -} -inline ::google::protobuf::uint32 CMsgMulti::size_unzipped() const { - return size_unzipped_; -} -inline void CMsgMulti::set_size_unzipped(::google::protobuf::uint32 value) { - _set_bit(0); - size_unzipped_ = value; -} - -// optional bytes message_body = 2; -inline bool CMsgMulti::has_message_body() const { - return _has_bit(1); -} -inline void CMsgMulti::clear_message_body() { - if (message_body_ != &_default_message_body_) { - message_body_->clear(); - } - _clear_bit(1); -} -inline const ::std::string& CMsgMulti::message_body() const { - return *message_body_; -} -inline void CMsgMulti::set_message_body(const ::std::string& value) { - _set_bit(1); - if (message_body_ == &_default_message_body_) { - message_body_ = new ::std::string; - } - message_body_->assign(value); -} -inline void CMsgMulti::set_message_body(const char* value) { - _set_bit(1); - if (message_body_ == &_default_message_body_) { - message_body_ = new ::std::string; - } - message_body_->assign(value); -} -inline void CMsgMulti::set_message_body(const void* value, size_t size) { - _set_bit(1); - if (message_body_ == &_default_message_body_) { - message_body_ = new ::std::string; - } - message_body_->assign(reinterpret_cast(value), size); -} -inline ::std::string* CMsgMulti::mutable_message_body() { - _set_bit(1); - if (message_body_ == &_default_message_body_) { - message_body_ = new ::std::string; - } - return message_body_; -} - -// ------------------------------------------------------------------- - -// CMsgAuthTicket - -// optional uint32 estate = 1; -inline bool CMsgAuthTicket::has_estate() const { - return _has_bit(0); -} -inline void CMsgAuthTicket::clear_estate() { - estate_ = 0u; - _clear_bit(0); -} -inline ::google::protobuf::uint32 CMsgAuthTicket::estate() const { - return estate_; -} -inline void CMsgAuthTicket::set_estate(::google::protobuf::uint32 value) { - _set_bit(0); - estate_ = value; -} - -// optional uint32 eresult = 2 [default = 2]; -inline bool CMsgAuthTicket::has_eresult() const { - return _has_bit(1); -} -inline void CMsgAuthTicket::clear_eresult() { - eresult_ = 2u; - _clear_bit(1); -} -inline ::google::protobuf::uint32 CMsgAuthTicket::eresult() const { - return eresult_; -} -inline void CMsgAuthTicket::set_eresult(::google::protobuf::uint32 value) { - _set_bit(1); - eresult_ = value; -} - -// optional fixed64 steam_id = 3; -inline bool CMsgAuthTicket::has_steam_id() const { - return _has_bit(2); -} -inline void CMsgAuthTicket::clear_steam_id() { - steam_id_ = GOOGLE_ULONGLONG(0); - _clear_bit(2); -} -inline ::google::protobuf::uint64 CMsgAuthTicket::steam_id() const { - return steam_id_; -} -inline void CMsgAuthTicket::set_steam_id(::google::protobuf::uint64 value) { - _set_bit(2); - steam_id_ = value; -} - -// optional fixed64 game_id = 4; -inline bool CMsgAuthTicket::has_game_id() const { - return _has_bit(3); -} -inline void CMsgAuthTicket::clear_game_id() { - game_id_ = GOOGLE_ULONGLONG(0); - _clear_bit(3); -} -inline ::google::protobuf::uint64 CMsgAuthTicket::game_id() const { - return game_id_; -} -inline void CMsgAuthTicket::set_game_id(::google::protobuf::uint64 value) { - _set_bit(3); - game_id_ = value; -} - -// optional uint32 h_steam_pipe = 5; -inline bool CMsgAuthTicket::has_h_steam_pipe() const { - return _has_bit(4); -} -inline void CMsgAuthTicket::clear_h_steam_pipe() { - h_steam_pipe_ = 0u; - _clear_bit(4); -} -inline ::google::protobuf::uint32 CMsgAuthTicket::h_steam_pipe() const { - return h_steam_pipe_; -} -inline void CMsgAuthTicket::set_h_steam_pipe(::google::protobuf::uint32 value) { - _set_bit(4); - h_steam_pipe_ = value; -} - -// optional uint32 ticket_crc = 6; -inline bool CMsgAuthTicket::has_ticket_crc() const { - return _has_bit(5); -} -inline void CMsgAuthTicket::clear_ticket_crc() { - ticket_crc_ = 0u; - _clear_bit(5); -} -inline ::google::protobuf::uint32 CMsgAuthTicket::ticket_crc() const { - return ticket_crc_; -} -inline void CMsgAuthTicket::set_ticket_crc(::google::protobuf::uint32 value) { - _set_bit(5); - ticket_crc_ = value; -} - -// optional bytes ticket = 7; -inline bool CMsgAuthTicket::has_ticket() const { - return _has_bit(6); -} -inline void CMsgAuthTicket::clear_ticket() { - if (ticket_ != &_default_ticket_) { - ticket_->clear(); - } - _clear_bit(6); -} -inline const ::std::string& CMsgAuthTicket::ticket() const { - return *ticket_; -} -inline void CMsgAuthTicket::set_ticket(const ::std::string& value) { - _set_bit(6); - if (ticket_ == &_default_ticket_) { - ticket_ = new ::std::string; - } - ticket_->assign(value); -} -inline void CMsgAuthTicket::set_ticket(const char* value) { - _set_bit(6); - if (ticket_ == &_default_ticket_) { - ticket_ = new ::std::string; - } - ticket_->assign(value); -} -inline void CMsgAuthTicket::set_ticket(const void* value, size_t size) { - _set_bit(6); - if (ticket_ == &_default_ticket_) { - ticket_ = new ::std::string; - } - ticket_->assign(reinterpret_cast(value), size); -} -inline ::std::string* CMsgAuthTicket::mutable_ticket() { - _set_bit(6); - if (ticket_ == &_default_ticket_) { - ticket_ = new ::std::string; - } - return ticket_; -} - - -// @@protoc_insertion_point(namespace_scope) - -#ifndef SWIG -namespace google { -namespace protobuf { - - -} // namespace google -} // namespace protobuf -#endif // SWIG - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_steammessages_5fbase_2eproto__INCLUDED diff --git a/Resources/NetHook/tier0.lib b/Resources/NetHook/tier0.lib deleted file mode 100644 index 54081731482af4c5cbfe3f3691a823372cff40b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85916 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Îh~_H8Ep8(PsZDrjYho?=7c*t zv4;_j{OE0@uV-05)77b~vv{3RL#Jlnc;%&fRcEe=?o$4FMF-5oI%enAt<@cycaB|B z9Uj;*Kq7SIRHJd;GVyP9PtTe)J$-A}u9v^n|Er>p-t~Ra*Gm>}4fdfIzx2t?aGnaU zpyFS!aw@!hZhFOp{7LYk32&Md2;h{Q1AO(0uO;~ZIpQlOLj9Alz6YbHf9R$3Yj`}C)EJ-tF=vZN zmA9Wr@VZBZh>~%NeN;#<;~)SYN2640bqI%_$p1zEICp}lQ2lQae3=pyqO|S#0%=H3 z@A-y?ED{<5cf>*t_>-w2Q<{D8WoXD66~!8Ihx!ryWexdF)O?W|JpnvaWqV4Anij{} zQLtV0tXpeHO|~mI9`;Jj)2`MkL9rHcyE6Y7?W$LWGaj6gTmKePxRWoP{gzS`Xa=Y`W>&KDxN&A zt4p0)>(S$bB6=x1*Dh)Ldf{lQ=^AlG!s2^^82`k*5t zx{3a;yK;K^yrWEdzlA>U=!l-(=fSw3%RaAfUA9cmgG`SRGz(mD?4lR!b7=4?&_C9q zZyk&dY_zUBY6jx3f^&#IM;)ID`uzS0`){{(%0amNXzrOc9cNNj+T|czy2Kv3#|yf? zOQSKh(z7+6q?Zc1-ixT3aA`^RI&_>@Zzo_@3|IH6$o>6&gZ;W_^H^s%=4dB_)`^Oi z-H5xT=$R>!&l-B6r2RpugVH4^~j> zGX(v)sp+sI4*B_vw9p0gZus%E+B4_H58JP5hT^Y+T5-OkrCbd8oR!ay|E7G*%slkQ zF`AqUzRqU8@~_`_L4BQLS8_e5pA%6pey3kE5`Pt}ojwO2E5XOPijN#W0WnRjB}J)w z=EN%%bvcK~aNM_f1pW=W(oNs!ex9K3@n@imUApJ)bF|TOAoW#(Zl03_O+5Z8DsxAF z#e37M1??Qi3o*g+ZLZf*-%CNeC!!655yMS_CKi7cET@mwnuwO|k|Cy0T919}_1=h9 zbdbLwW%Ko^YX!ZO{atZS7FrCY_1Y)%KISXs9zzq0zZRf=*G05`8}++BqP39q>zmV@ zFX+{0YnL}dZ3mrk!zdPL`F6U_F_SwV?eqdcztrR6U2xLp*nwLOPM*)46mw$I4F`_- z3-6m;C^<+tJ+Ut4bwk-v3%p}>Q6^=zfuekE>UHnzBUtRB6We+MIgrw~!HQg_W#T=9# zSI>9sf^0?$7*f2<+tbec`SQ))hXr3{y!XtXk3NTd&Vqb4G9R${RM#)fGbiN{X#SLa z64(?`HZE-Dcp2(~4~Mq0@!G{{KAfJ5=Ffp|tlpgFAijhYcUF80Ns}+#SNV3LM$+^R zr!}h6g6{{rqb|*ZZf_*im8+`7tDd+hO>Vga3tbM2EBFD3uW+475TJxU0txF^Nes66t#qwI`Y5kW) zv~xYcY4W8tz;^<&E21yE9eEE$*tcT%?QRC(vr2rSMb$pvPZEv`UbLnieH~jgyhzct zJ-;NjDeS3FY5E>b`yEX`)4NKyBcE^7{oRPR-%np$+VWcN*|YyWMLWm$Ul-IpJ^PCd z>iHdP%tKLqbM&vgb6r)GeLf0fg5~EG>m8%YMWFo>gSOGT`1*KT@k{qJ>m7Bl0o>F~ zZc2Dl)WV6siq?x~kM44Vn;dV2G1>C9<68$$8XPRVPOfwGL40*+DnZ$&5d4I&7C`(} zum*hlRbkA9<8k7cSb4eo#=G4SU5C%hE~xreywi$m5l5O`@X+U2`S9uSo`{FvoW8H~ z?0VD{^}Gk3tKP7C zyP)gaYuRhj^?Fh5h6B(1qp3K^am}j9$6p0C&o}dGDe7K#uQ5g4;})gunSsohwDSj= z(qn#n2{Ca8i0_yFev)?ap{6t+KK*Ma`EWbC)s;}51CRdAMjW_(;&naq_pEw4Og+cb zuJp>Qiywa#)Ine0KUaW0R(;)C%{W>CTmD|f9AtYBjte@EzSdFWe24RDL2-7VQNJow zXB}c)oj3%H$rqHfZ&iJbq?zG-Ou0FZsg>?yd^ahtWx5X6$@8b^+r7SyDdOnJ>yBBI zF5i|ND;Yk)dTEMw+Q+jd9e)+AU&o4$&-GuHL)n_FmoBq!*8G2xl(ofjmlowdsxNm@ zm2UZB(UxzyzIpO16xD>sN#oX7mu2=*e`Ox^?#u3&A+qhtA2_Hd?*4RJeh&w)D#Ahc zGH~?VY+w3^1_#2ajOxCf3J@z|(Kha({_0%n$-Cn7YHS{roBV ztRMbVP%PjpUz0B{Z_g-xBh&Xg;O~aAr*HYQh;p7+e@#CAD%i96yqdgLP+9WK zZ_u^Rv+bd~bXh&U+utNQ30J5{_jrkQzwjk?Wz9waXIJl1L+E&JP;8`qm7nsEG8 zP|JM%-E9`#tanUeYFf_=()I1M{9Qyh>ur=SC_3y@_=fBoOo~3mUeMO`_bIB`svVcP zsBAqYy`5>onW|duEnL6h+sXQe1Xa@>8jVT5HWL?f9<9eQS72+HH%7D#i|Di+uy~n9 zGZ23jl(=t<{KtrX&a*f%$$6CCQQv%5w9@wK!!WzjeGF}tSiDf_=f zwB6@FXzN|dey!*H<9wtZ)f_ zP2cMCoE2YQ>pavym`6QX^zzglZJg~aKIEY8t^5V$;KM~Y=voFo>zxG_|3CM*fH!{58XPMr@JQLk%J&$(4p|<9 zn){NZreAyRhK^(Aa4hJ2IijPVkk*9auY%HB zcR|BfFOMo3>UGX8=&W(9Tn~r5z82B3#T64PS|c6`k3|%0VU?xO>llTOMj5^yQAmrb zEEQj$`VB!P>qYXIidKe#a$D=^Q@<(cg?M|{dgXln)YdrcNtZx|k2AI5F15gu|F=Z` zUFv{CT1SHaCq(|;Yk=?W=eGroaI#TrhtX55a*jPRJ6fwZ<+s)W{Z&vKeC_l}Nn5-` z--QNv+Ua*93SHKbr=5N`qR@RU`Nq%h2`a7RE7w|RrDq0f95epIpm*PAY8%__mN~U5 zO~F^5A20=eS$ljZKegQ6TkF(YO|4wz$F^QaJ3S8N`JtjV*Jl4s!~F8M7G3;RP@{eQ z+m9kj{5G?EP+Yih?1Gw4ich7eiRa7X0+pAduWUa~Q4^0dbWt`RwWm|mwuV=Qjc%wp z`U$p5|4Bqmc6Z^_R(OEfTEDzqYhRlXX)N4=+TxpY{gkQlWe420FbY<>rTI>ce?(iRq zn)^A^v4{B5^7Fm_^epGE9wnccZ1W1uC`x%+o_^{V5v@&dgPSI`kW%}lpw!(=-#4=V zFXulNcI=8NT>?joZg#{SdJ@W?&AgS?2ty3LnG+L8}YL%6iZ>=B1 zREGI6d%1Pe1udW5=%Sd`rrK=h(y(3MeeLF2d+KV;FfR$O?SiUrjNeC7ZM13~_9W5` zC5MITQP8}7H6^rDgGlMV!1reEb7CqyO=`tECtcBV=;1PyYCi|P0fS&!jr7@y?QhYO z6SHXHF>H`rP?;WJ(nOy=UYo`;^t$fq(6JB2UOf&p=`pdX@m8zB6W*>$=ood`=5cXM zab$L+IT$u4_w22;uN-YnnT0G}kDf9fWKop83#J&|&gLByd3W#NnBwR}qM4W07T*l! zxiKA_0Cm|n`&#-T2A%2pEMCP(ExJpW%eUuqXiN{6NyMNdmU^4a<<~-L$P$yDOC`&f z(6MjAJNJi~6s0iv5`)p`%9hVJ@*J+I)%o1AyE%{VcGVFvrG*?-eXEBf-4uu0nACT( zdhpRb%1sxGn7uQdF6z?P7LR7S+e2|HRw|BMB^l&OYpPFoj*;|uIi?n82C0SA(qjds zx#o_Et>|NRgtML5ZYVi+kNCyh=f#v>Fc;2+Nm8Zd=c}*dm=?OR(R#B!jK`IDvEJ=Y zl5cK%d_+&`#zO8B_)57nqB=KoS-rWYXQWr~j62JCVd$u}yT%#@@; z@=`%grBmHj>AG^9N1g!vSZ+~NH}$&GM$c$|il#QwT#z#fpB35)lN#n?Sd(8FP7Pp2 zJKY@F-PhYqDScjUPR*ptmQYwWZ@gx5Ppvr}TI9>tsBgSIEtC3iIN1*OV#mBIx;|;2 zo=G>exTSkIpOxboUb=WBysHxXBzNZNOve3qumo)8T+E~`hr6N$4m6<%EI z-i>j&V{ZABu0`J&!8sN+vG(kCp6}`P&b6p5M6c(wl~`#|<9o42g_W0~XW!>MO^0o7 zVTZcy@+-p0u4ae6GmlkFFTJH&x=g)}GlAz}d|EANwCkNv%?rDcp6?z`Pm0pcSs10E z0}E$(9@_O@k7FP5B$RRu(>4v_*ih9rhbt{rp9h)VEPCQ*giW+;f8yJ#SevA|0Q7vC z()Kw2uJE4qdO?kg)vZSQ z=GN!ORMNsLs}(*v7X$}Vb-Fslb2F4FoH8n@EFIsR?D 3) - n = 3; - eventSelectNum = n; - - } - k8BaseEvent() - { - pme = PME::Instance(); - - for(int i = 0; i< k8NUM_COUNTERS; i++) - { - eventSelect[i].flat = 0; - - } - eventSelectNum = 0; - - m_eventMask = 0; - event_id = 0; - name = 0; - revRequired = 'A'; - - - } - - void SetCaptureMode(PrivilegeCapture priv) - { - PerfEvtSel & select = eventSelect[eventSelectNum]; - StopCounter(); - - switch (priv) - { - case OS_Only: - select.USR = 0; - select.OS = 1; - break; - - case USR_Only: - select.USR = 1; - select.OS = 0; - break; - - case OS_and_USR: - select.USR = 1; - select.OS = 1; - break; - } - - - select.UnitMask = m_eventMask; - select.EventMask = event_id; - - - int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum; - pme->WriteMSR(selectPort, select.flat); - } - - - void SetFiltering(CompareState compareEnable, - CompareMethod compareMethod, - uint8 threshold, - EdgeState edgeEnable) - { - - PerfEvtSel & select = eventSelect[eventSelectNum]; - - StopCounter(); - - if (compareEnable == CompareDisable) - select.Threshold = 0; - else - select.Threshold = threshold; - - select.Complement = compareMethod; - - select.Edge = edgeEnable; - - int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum; - pme->WriteMSR(selectPort, select.flat); - - - } - - - void StartCounter() - { - PerfEvtSel & select = eventSelect[eventSelectNum]; - - select.Enable = 1; - int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum; - - pme->WriteMSR(selectPort, select.flat); - - } - void StopCounter() - { - PerfEvtSel & select = eventSelect[eventSelectNum]; - select.Enable = 0; - int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum; - - pme->WriteMSR(selectPort, select.flat); - } - - - - void ClearCounter() - { - PerfEvtSel & select = eventSelect[eventSelectNum]; - - int counterPort = MSR_K8_PERFCTR0 + eventSelectNum; - - pme->WriteMSR(counterPort, 0ui64 ); // clear - } - - void WriteCounter(int64 value) - { - - PerfEvtSel & select = eventSelect[eventSelectNum]; - - int counterPort = MSR_K8_PERFCTR0 + eventSelectNum; - pme->WriteMSR(counterPort, value); // clear - } - - int64 ReadCounter() - { - -#if PME_DEBUG - PerfEvtSel & select = eventSelect[eventSelectNum]; - - if (select.USR == 0 && select.OS == 0) - return -1; // no area to collect, use SetCaptureMode - - if (select.EventMask == 0) - return -2; // no event mask set - - if (eventSelectNum < 0 || eventSelectNum > 3) - return -3; // counter not legal - - // check revision - -#endif - - // ReadMSR should work here too, but RDPMC should be faster - //ReadMSR(counterPort, int64); - - // we need to copy this into a temp for some reason - int temp = eventSelectNum; - _asm - { - mov ecx, temp - RDPMC - } - - } - - -}; -#pragma warning( default : 4035 ) - - - - -typedef union EVENT_MASK(k8_dispatched_fpu_ops) -{ - // event 0 - struct - { - uint16 AddPipeOps:1; // Add pipe ops excluding junk ops" }, - uint16 MulPipeOps:1; // Multiply pipe ops excluding junk ops" },, - uint16 StoreOps:1; // Store pipe ops excluding junk ops" }, - uint16 AndPipeOpsJunk:1; // Add pipe junk ops" },, - uint16 MulPipeOpsJunk:1; // Multiply pipe junk ops" }, - uint16 StoreOpsJunk:1; // Store pipe junk ops" } } - }; - uint16 flat; -} EVENT_MASK(k8_dispatched_fpu_ops); - -class k8Event_DISPATCHED_FPU_OPS : public k8BaseEvent -{ -public: - - k8Event_DISPATCHED_FPU_OPS() - { - eventMask = (EVENT_MASK(k8_dispatched_fpu_ops) *)&m_eventMask; - - event_id = 0x00; - unitEncode = FP; - name = _T("Dispatched FPU ops"); - revRequired = 'B'; - } - EVENT_MASK(k8_dispatched_fpu_ops) * eventMask; - -}; - -////////////////////////////////////////////////////////// - - - -class k8Event_NO_FPU_OPS : public k8BaseEvent -{ -public: - - k8Event_NO_FPU_OPS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - event_id = 0x01; - unitEncode = FP; - - name = _T("Cycles with no FPU ops retired"); - revRequired = 'B'; - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - -////////////////////////////////////////////////////////// - -class k8Event_FAST_FPU_OPS : public k8BaseEvent -{ -public: - - k8Event_FAST_FPU_OPS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - event_id = 0x02; - unitEncode = FP; - - name = _T("Dispatched FPU ops that use the fast flag interface"); - revRequired = 'B'; - - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - -////////////////////////////////////////////////////////// - - -typedef union EVENT_MASK(k8_segment_register_load) -{ - - struct - { - uint16 ES:1; - uint16 CS:1; - uint16 SS:1; - uint16 DS:1; - uint16 FS:1; - uint16 GS:1; - uint16 HS:1; - }; - uint16 flat; -} EVENT_MASK(k8_segment_register_load); - - -class k8Event_SEG_REG_LOAD : public k8BaseEvent -{ -public: - - k8Event_SEG_REG_LOAD() - { - eventMask = (EVENT_MASK(k8_segment_register_load) *)&m_eventMask; - name = _T("Segment register load"); - event_id = 0x20; - unitEncode = LS; - - } - EVENT_MASK(k8_segment_register_load) * eventMask; - -}; - - -class k8Event_SELF_MODIFY_RESYNC : public k8BaseEvent -{ -public: - - k8Event_SELF_MODIFY_RESYNC() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Microarchitectural resync caused by self modifying code"); - event_id = 0x21; - unitEncode = LS; - - } - EVENT_MASK(NULL_MASK) * eventMask; - - -}; -class k8Event_LS_RESYNC_BY_SNOOP : public k8BaseEvent -{ -public: - - k8Event_LS_RESYNC_BY_SNOOP() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - event_id = 0x22; - unitEncode = LS; - - name = _T("Microarchitectural resync caused by snoop"); - } - EVENT_MASK(NULL_MASK) * eventMask; - - -}; -class k8Event_LS_BUFFER_FULL : public k8BaseEvent -{ -public: - - k8Event_LS_BUFFER_FULL() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("LS Buffer 2 Full"); - event_id = 0x23; - unitEncode = LS; - - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - -typedef union EVENT_MASK(k8_locked_op) -{ - - - struct - { - uint16 NumLockInstr : 1; //Number of lock instructions executed - uint16 NumCyclesInRequestGrant : 1; //Number of cycles spent in the lock request/grant stage - - uint16 NumCyclesForLock:1; - /*Number of cycles a lock takes to complete once it is - non-speculative and is the oldest load/store operation - (non-speculative cycles in Ls2 entry 0)*/ - - - }; - uint16 flat; - - -} EVENT_MASK(k8_locked_op); - - - -class k8Event_LOCKED_OP : public k8BaseEvent -{ -public: - - EVENT_MASK(k8_locked_op) * eventMask; - - k8Event_LOCKED_OP() - { - eventMask = (EVENT_MASK(k8_locked_op) *)&m_eventMask; - name = _T("Locked operation"); - event_id = 0x24; - unitEncode = LS; - - revRequired = 'C'; - } - - -}; - -class k8Event_OP_LATE_CANCEL : public k8BaseEvent -{ -public: - - k8Event_OP_LATE_CANCEL() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Microarchitectural late cancel of an operation"); - event_id = 0x25; - unitEncode = LS; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("OP_LATE_CANCEL"); - - -}; -class k8Event_CFLUSH_RETIRED : public k8BaseEvent -{ -public: - - k8Event_CFLUSH_RETIRED() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Retired CFLUSH instructions"); - event_id = 0x26; - unitEncode = LS; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("CFLUSH_RETIRED"); - - -}; -class k8Event_CPUID_RETIRED : public k8BaseEvent -{ -public: - - k8Event_CPUID_RETIRED() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Retired CPUID instructions"); - event_id = 0x27; - unitEncode = LS; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("CPUID_RETIRED"); - - -}; - -typedef union EVENT_MASK( k8_cache) -{ - - struct - { - uint16 Invalid:1; - uint16 Exclusive:1; - uint16 Shared:1; - uint16 Owner:1; - uint16 Modified:1; - }; - uint16 flat; - -}EVENT_MASK( k8_cache); - /* 0x40-0x47: from K7 official event set */ - - -class k8Event_DATA_CACHE_ACCESSES : public k8BaseEvent -{ - k8Event_DATA_CACHE_ACCESSES() - { - - event_id = 0x40; - unitEncode = DC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - //_T("DATA_CACHE_ACCESSES"), - name = _T("Data cache accesses"); - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - -class k8Event_DATA_CACHE_MISSES : public k8BaseEvent -{ - k8Event_DATA_CACHE_MISSES() - { - - event_id = 0x41; - unitEncode = DC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - //_T("DATA_CACHE_MISSES"), - name = _T("Data cache misses"); - } - EVENT_MASK(NULL_MASK) * eventMask; -}; - -class k8Event_DATA_CACHE_REFILLS_FROM_L2 : public k8BaseEvent -{ - k8Event_DATA_CACHE_REFILLS_FROM_L2() - { - - event_id = 0x42; - unitEncode = DC; - - eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask; - - - name = _T("Data cache refills from L2"); - } - EVENT_MASK(k8_cache) * eventMask; - -}; - -class k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM : public k8BaseEvent -{ - k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM() - { - - event_id = 0x43; - unitEncode = DC; - - - eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask; - - //UM(k7_um_moesi), - //_T("DATA_CACHE_REFILLS_FROM_SYSTEM"), - name = _T("Data cache refills from system"); - } - EVENT_MASK(k8_cache) * eventMask; - -}; - -class k8Event_DATA_CACHE_WRITEBACKS : public k8BaseEvent -{ - k8Event_DATA_CACHE_WRITEBACKS() - { - - event_id = 0x44; - unitEncode = DC; - - eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask; - - //UM(k7_um_moesi), - //_T("DATA_CACHE_WRITEBACKS"), - name = _T("Data cache writebacks"); - } - EVENT_MASK(k8_cache) * eventMask; - - -}; - -class k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS : public k8BaseEvent -{ - k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS() - { - - event_id = 0x45; - unitEncode = DC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - name = _T("L1 DTLB misses and L2 DTLB hits"); - } - EVENT_MASK(NULL_MASK) * eventMask; - - -}; - -class k8Event_L1_AND_L2_DTLB_MISSES : public k8BaseEvent -{ - k8Event_L1_AND_L2_DTLB_MISSES() - { - - event_id = 0x46; - unitEncode = DC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - name = _T("L1 and L2 DTLB misses") ; - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - -class k8Event_MISALIGNED_DATA_REFERENCES : public k8BaseEvent -{ - k8Event_MISALIGNED_DATA_REFERENCES() - { - - event_id = 0x47; - unitEncode = DC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - //NULL, _T("MISALIGNED_DATA_REFERENCES"), - name = _T("Misaligned data references"); - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - - -class k8Event_ACCESS_CANCEL_LATE : public k8BaseEvent -{ -public: - - k8Event_ACCESS_CANCEL_LATE() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Microarchitectural late cancel of an access"); - event_id = 0x48; - unitEncode = DC; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("ACCESS_CANCEL_LATE"); - - -}; -class k8Event_ACCESS_CANCEL_EARLY : public k8BaseEvent -{ -public: - - k8Event_ACCESS_CANCEL_EARLY() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Microarchitectural early cancel of an access"); - event_id = 0x49; - unitEncode = DC; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("ACCESS_CANCEL_EARLY"); - - -}; -typedef union EVENT_MASK( k8_ecc) -{ - struct - { - uint16 ScrubberError : 1; // Scrubber error" }, - uint16 PiggybackScrubberErrors : 1; // Piggyback scrubber errors" } } - }; - uint16 flat; - -}EVENT_MASK( k8_ecc); - - -class k8Event_ECC_BIT_ERR : public k8BaseEvent -{ -public: - - k8Event_ECC_BIT_ERR() - { - eventMask = (EVENT_MASK(k8_ecc) *)&m_eventMask; - name = _T("One bit ECC error recorded found by scrubber"); - event_id = 0x4A; - unitEncode = DC; - - } - EVENT_MASK(k8_ecc) * eventMask; - // name = _T("ECC_BIT_ERR"); - - -}; - -// 4B -typedef union EVENT_MASK( k8_distpatch_prefetch_instructions) -{ - struct - { - uint16 Load : 1; - uint16 Store : 1; - uint16 NTA : 1; - }; - uint16 flat; - - -}EVENT_MASK( k8_distpatch_prefetch_instructions); - -class k8Event_DISPATCHED_PRE_INSTRS : public k8BaseEvent -{ -public: - - k8Event_DISPATCHED_PRE_INSTRS() - { - eventMask = (EVENT_MASK(k8_distpatch_prefetch_instructions) *)&m_eventMask; - name = _T("Dispatched prefetch instructions"); - event_id = 0x4B; - unitEncode = DC; - - } - EVENT_MASK(k8_distpatch_prefetch_instructions) * eventMask; - // name = _T("DISPATCHED_PRE_INSTRS"); - - /* 0x4C: added in Revision C */ - -}; - - - -typedef union EVENT_MASK( k8_lock_accesses) -{ - struct - { - uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" }, - uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } } - }; - uint16 flat; - -}EVENT_MASK( k8_lock_accesses); - - - -class k8Event_LOCK_ACCESSES : public k8BaseEvent -{ -public: - - k8Event_LOCK_ACCESSES() - { - eventMask = (EVENT_MASK(k8_lock_accesses) *)&m_eventMask; - name = _T("DCACHE accesses by locks") ; - event_id = 0x4C; - unitEncode = DC; - - revRequired = 'C'; - } - EVENT_MASK(k8_lock_accesses) * eventMask; - - -}; - - -class k8Event_CYCLES_PROCESSOR_IS_RUNNING : public k8BaseEvent -{ -public: - - k8Event_CYCLES_PROCESSOR_IS_RUNNING() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Cycles processor is running (not in HLT or STPCLK)"); - event_id = 0x76; - unitEncode = BU; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("CYCLES_PROCESSOR_IS_RUNNING"); /* undocumented *; - - -}; - - -typedef union EVENT_MASK( k8_internal_L2_request) -{ - struct - { - uint16 ICFill:1; // IC fill" }, - uint16 DCFill:1; // DC fill" }, - uint16 TLBReload:1; // TLB reload" }, - uint16 TagSnoopRequest:1; // Tag snoop request" }, - uint16 CancelledRequest:1; // Cancelled request" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_internal_L2_request); - -class k8Event_BU_INT_L2_REQ : public k8BaseEvent -{ -public: - - k8Event_BU_INT_L2_REQ() - { - eventMask = (EVENT_MASK(k8_internal_L2_request) *)&m_eventMask; - name = _T("Internal L2 request"); - unitEncode = BU; - event_id = 0x7D; - } - - EVENT_MASK(k8_internal_L2_request) * eventMask; -} ; - - // name = _T("BU_INT_L2_REQ"); - - - -// 7E -typedef union EVENT_MASK( k8_fill_request_missed_L2) -{ - - struct - { - uint16 ICFill:1; // IC fill" }, - uint16 DCFill:1; // DC fill" }, - uint16 TLBReload:1; // TLB reload" }, - }; - uint16 flat; - -} EVENT_MASK( k8_fill_request_missed_L2); - - -class k8Event_BU_FILL_REQ : public k8BaseEvent -{ -public: - - k8Event_BU_FILL_REQ() - { - eventMask = (EVENT_MASK(k8_fill_request_missed_L2) *)&m_eventMask; - name = _T("Fill request that missed in L2"); - event_id = 0x7E; - unitEncode = BU; - - } - EVENT_MASK(k8_fill_request_missed_L2) * eventMask; - // name = _T("BU_FILL_REQ"); - - - -}; - - - - -// 7F -typedef union EVENT_MASK( k8_fill_into_L2) -{ - - struct - { - uint16 DirtyL2Victim:1; // Dirty L2 victim - uint16 VictimFromL2:1; // Victim from L2 - }; - uint16 flat; - -}EVENT_MASK( k8_fill_into_L2); - -class k8Event_BU_FILL_L2 : public k8BaseEvent -{ -public: - - k8Event_BU_FILL_L2() - { - eventMask = (EVENT_MASK(k8_fill_into_L2) *)&m_eventMask; - name = _T("Fill into L2"); - event_id = 0x7F; - unitEncode = BU; - - } - EVENT_MASK(k8_fill_into_L2) * eventMask; - // name = _T("BU_FILL_L2"); - - -}; - -class k8Event_INSTRUCTION_CACHE_FETCHES : public k8BaseEvent -{ -public: - k8Event_INSTRUCTION_CACHE_FETCHES() - { - event_id = 0x80; - unitEncode = IC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - name = _T("Instruction cache fetches"); - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - -class k8Event_INSTRUCTION_CACHE_MISSES : public k8BaseEvent -{ -public: - k8Event_INSTRUCTION_CACHE_MISSES() - { - event_id = 0x81; - unitEncode = IC; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - //0xF, NULL, _T("INSTRUCTION_CACHE_MISSES"), - name = _T("Instruction cache misses"); - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - -class k8Event_IC_REFILL_FROM_L2 : public k8BaseEvent -{ -public: - - k8Event_IC_REFILL_FROM_L2() - { - eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask; - name = _T("Refill from L2"); - event_id = 0x82; - unitEncode = IC; - - } - EVENT_MASK(k8_cache) * eventMask; - // name = _T("IC_REFILL_FROM_L2"); - - - -}; -class k8Event_IC_REFILL_FROM_SYS : public k8BaseEvent -{ -public: - - k8Event_IC_REFILL_FROM_SYS() - { - eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask; - name = _T("Refill from system"); - event_id = 0x83; - unitEncode = IC; - - } - EVENT_MASK(k8_cache) * eventMask; - // name = _T("IC_REFILL_FROM_SYS"); - - - -}; -class k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS : public k8BaseEvent -{ -public: - k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS() - { - - event_id = 0x84; - unitEncode = IC; - - name = _T("L1 ITLB misses (and L2 ITLB hits)"); - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - - } - EVENT_MASK(NULL_MASK) * eventMask; - - -}; - -class k8Event_L1_AND_L2_ITLB_MISSES : public k8BaseEvent -{ -public: - k8Event_L1_AND_L2_ITLB_MISSES() - { - event_id = 0x85; - unitEncode = IC; - - name = _T("(L1 and) L2 ITLB misses"); - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - - - -class k8Event_IC_RESYNC_BY_SNOOP : public k8BaseEvent -{ -public: - - k8Event_IC_RESYNC_BY_SNOOP() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - event_id = 0x86; - unitEncode = IC; - - name = _T("Microarchitectural resync caused by snoop"); - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("IC_RESYNC_BY_SNOOP"); - /* similar to 0x22; but IC unit instead of LS unit */ - - - -}; -class k8Event_IC_FETCH_STALL : public k8BaseEvent -{ -public: - - k8Event_IC_FETCH_STALL() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Instruction fetch stall"); - event_id = 0x87; - unitEncode = IC; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("IC_FETCH_STALL"); - - - -}; -class k8Event_IC_STACK_HIT : public k8BaseEvent -{ -public: - - k8Event_IC_STACK_HIT() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Return stack hit"); - event_id = 0x88; - unitEncode = IC; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("IC_STACK_HIT"); - - - -}; -class k8Event_IC_STACK_OVERFLOW : public k8BaseEvent -{ -public: - - k8Event_IC_STACK_OVERFLOW() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Return stack overflow"); - event_id = 0x89; - unitEncode = IC; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("IC_STACK_OVERFLOW"); - - - - -}; - - /* 0xC0-0xC7: from K7 official event set */ -class k8Event_RETIRED_INSTRUCTIONS : public k8BaseEvent -{ -public: - k8Event_RETIRED_INSTRUCTIONS() - { - event_id = 0xC0; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - //0xF, NULL, _T("RETIRED_INSTRUCTIONS"), - name = _T("Retired instructions (includes exceptions, interrupts, resyncs)"); - } - EVENT_MASK(NULL_MASK) * eventMask; -}; - -class k8Event_RETIRED_OPS : public k8BaseEvent -{ -public: - k8Event_RETIRED_OPS() - { - event_id = 0xC1; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_OPS"), - name = _T("Retired Ops") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_BRANCHES : public k8BaseEvent -{ -public: - k8Event_RETIRED_BRANCHES() - { - event_id = 0xC2; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_BRANCHES"), - name = _T("Retired branches (conditional, unconditional, exceptions, interrupts)") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_BRANCHES_MISPREDICTED : public k8BaseEvent -{ -public: - k8Event_RETIRED_BRANCHES_MISPREDICTED() - { - event_id = 0xC3; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_BRANCHES_MISPREDICTED"), - name = _T("Retired branches mispredicted") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_TAKEN_BRANCHES : public k8BaseEvent -{ -public: - k8Event_RETIRED_TAKEN_BRANCHES() - { - event_id = 0xC4; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES"), - name = _T("Retired taken branches") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED : public k8BaseEvent -{ -public: - k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED() - { - event_id = 0xC5; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES_MISPREDICTED"), - name = _T("Retired taken branches mispredicted") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_FAR_CONTROL_TRANSFERS : public k8BaseEvent -{ -public: - k8Event_RETIRED_FAR_CONTROL_TRANSFERS() - { - event_id = 0xC6; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_FAR_CONTROL_TRANSFERS"), - name = _T("Retired far control transfers") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; -class k8Event_RETIRED_RESYNC_BRANCHES : public k8BaseEvent -{ -public: - k8Event_RETIRED_RESYNC_BRANCHES() - { - event_id = 0xC7; - unitEncode = FR; - - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - //0xF, NULL, _T("RETIRED_RESYNC_BRANCHES"), - name = _T("Retired resync branches (only non-control transfer branches counted)") ; - } - EVENT_MASK(NULL_MASK) * eventMask; -}; - -class k8Event_RETIRED_NEAR_RETURNS : public k8BaseEvent -{ -public: - - k8Event_RETIRED_NEAR_RETURNS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Retired near returns"); - event_id = 0xC8; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - - - -}; -class k8Event_RETIRED_RETURNS_MISPREDICT : public k8BaseEvent -{ -public: - - k8Event_RETIRED_RETURNS_MISPREDICT() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Retired near returns mispredicted"); - event_id = 0xC9; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("RETIRED_RETURNS_MISPREDICT"); - - -}; -class k8Event_RETIRED_BRANCH_MISCOMPARE : public k8BaseEvent -{ -public: - - k8Event_RETIRED_BRANCH_MISCOMPARE() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Retired taken branches mispredicted due to address miscompare"); - event_id = 0xCA; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("RETIRED_BRANCH_MISCOMPARE"); - - -}; - - - /* Revision B and later */ - -typedef union EVENT_MASK( k8_retired_fpu_instr) -{ - struct - { - uint16 DirtyL2Victim:1; // x87 instructions - uint16 CombinedMMX_3DNow:1; // Combined MMX & 3DNow! instructions" }, - uint16 CombinedPackedSSE_SSE2:1; // Combined packed SSE and SSE2 instructions" }, - uint16 CombinedScalarSSE_SSE2:1; // Combined scalar SSE and SSE2 instructions" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_retired_fpu_instr); - - -class k8Event_RETIRED_FPU_INSTRS : public k8BaseEvent -{ -public: - - k8Event_RETIRED_FPU_INSTRS() - { - eventMask = (EVENT_MASK(k8_retired_fpu_instr) *)&m_eventMask; - event_id = 0xCB; - unitEncode = FR; - - name = _T("Retired FPU instructions"); - revRequired = 'B'; - } - EVENT_MASK(k8_retired_fpu_instr) * eventMask; - /* Revision B and later */ - - - -}; - -// CC -typedef union EVENT_MASK( k8_retired_fastpath_double_op_instr ) -{ - - struct - { - uint16 LowOpPosition0:1; // With low op in position 0" }, - uint16 LowOpPosition1:1; // With low op in position 1" }, - uint16 LowOpPosition2:1; // With low op in position 2" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_retired_fastpath_double_op_instr); - -class k8Event_RETIRED_FASTPATH_INSTRS : public k8BaseEvent -{ -public: - - k8Event_RETIRED_FASTPATH_INSTRS() - { - eventMask = (EVENT_MASK(k8_retired_fastpath_double_op_instr) *)&m_eventMask; - event_id = 0xCC; - unitEncode = FR; - - name = _T("Retired fastpath double op instructions"); - revRequired = 'B'; - - } - EVENT_MASK(k8_retired_fastpath_double_op_instr) * eventMask; - - -}; - -class k8Event_INTERRUPTS_MASKED_CYCLES : public k8BaseEvent -{ -public: - k8Event_INTERRUPTS_MASKED_CYCLES() - { - event_id = 0xCD; - unitEncode = FR; - - //0xF, NULL, _T("INTERRUPTS_MASKED_CYCLES"), - name = _T("Interrupts masked cycles (IF=0)") ; - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; -class k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES : public k8BaseEvent -{ -public: - k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES() - { - event_id = 0xCE; - unitEncode = FR; - - //0xF, NULL, _T("INTERRUPTS_MASKED_WHILE_PENDING_CYCLES"), - name = _T("Interrupts masked while pending cycles (INTR while IF=0)") ; - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; -class k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS : public k8BaseEvent -{ -public: - k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS() - { - event_id = 0xCF; - unitEncode = FR; - - //0xF, NULL, _T("NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS"), - name = _T("Number of taken hardware interrupts") ; - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - } - EVENT_MASK(NULL_MASK) * eventMask; - -}; - - -class k8Event_DECODER_EMPTY : public k8BaseEvent -{ -public: - - k8Event_DECODER_EMPTY() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Nothing to dispatch (decoder empty)"); - event_id = 0xD0; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DECODER_EMPTY"); - - -}; -class k8Event_DISPATCH_STALLS : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALLS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stalls (events 0xD2-0xDA combined)"); - event_id = 0xD1; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALLS"); - - - -}; -class k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall from branch abort to retire"); - event_id = 0xD2; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_FROM_BRANCH_ABORT"); - - - -}; -class k8Event_DISPATCH_STALL_SERIALIZATION : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_SERIALIZATION() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall for serialization"); - event_id = 0xD3; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_SERIALIZATION"); - - -}; -class k8Event_DISPATCH_STALL_SEG_LOAD : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_SEG_LOAD() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall for segment load"); - event_id = 0xD4; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_SEG_LOAD"); - - - -}; -class k8Event_DISPATCH_STALL_REORDER_BUFFER : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_REORDER_BUFFER() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when reorder buffer is full"); - event_id = 0xD5; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_REORDER_BUFFER"); - - -}; -class k8Event_DISPATCH_STALL_RESERVE_STATIONS : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_RESERVE_STATIONS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when reservation stations are full"); - event_id = 0xD6; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_RESERVE_STATIONS"); - - -}; -class k8Event_DISPATCH_STALL_FPU : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_FPU() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when FPU is full"); - event_id = 0xD7; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_FPU"); - - -}; -class k8Event_DISPATCH_STALL_LS : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_LS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when LS is full"); - event_id = 0xD8; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_LS"); - - -}; -class k8Event_DISPATCH_STALL_QUIET_WAIT : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_QUIET_WAIT() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when waiting for all to be quiet"); - event_id = 0xD9; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_QUIET_WAIT"); - - - -}; -class k8Event_DISPATCH_STALL_PENDING : public k8BaseEvent -{ -public: - - k8Event_DISPATCH_STALL_PENDING() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Dispatch stall when far control transfer or resync branch is pending"); - event_id = 0xDA; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DISPATCH_STALL_PENDING"); - - - -}; - - -typedef union EVENT_MASK( k8_fpu_exceptions) -{ - - - - struct - { - uint16 x87ReclassMicrofaults:1; // x87 reclass microfaults" }, - uint16 SSERetypeMicrofaults:1; // SSE retype microfaults" }, - uint16 SSEReclassMicrofaults:1; // SSE reclass microfaults" }, - uint16 SSE_x87Microtraps:1; // SSE and x87 microtraps" } } - }; - uint16 flat; - - - -}EVENT_MASK( k8_fpu_exceptions); - -class k8Event_FPU_EXCEPTIONS : public k8BaseEvent -{ -public: - - k8Event_FPU_EXCEPTIONS() - { - eventMask = (EVENT_MASK(k8_fpu_exceptions) *)&m_eventMask; - event_id = 0xDB; - unitEncode = FR; - - name = _T("FPU exceptions"); - revRequired = 'B'; - - } - EVENT_MASK(k8_fpu_exceptions) * eventMask; - // name = _T("FPU_EXCEPTIONS"); - /* Revision B and later */ - - - -}; -class k8Event_DR0_BREAKPOINTS : public k8BaseEvent -{ -public: - - k8Event_DR0_BREAKPOINTS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Number of breakpoints for DR0"); - event_id = 0xDC; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DR0_BREAKPOINTS"); - - - -}; -class k8Event_DR1_BREAKPOINTS : public k8BaseEvent -{ -public: - - k8Event_DR1_BREAKPOINTS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Number of breakpoints for DR1"); - event_id = 0xDD; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DR1_BREAKPOINTS"); - - - -}; -class k8Event_DR2_BREAKPOINTS : public k8BaseEvent -{ -public: - - k8Event_DR2_BREAKPOINTS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Number of breakpoints for DR2"); - event_id = 0xDE; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DR2_BREAKPOINTS"); - - -}; -class k8Event_DR3_BREAKPOINTS : public k8BaseEvent -{ -public: - - k8Event_DR3_BREAKPOINTS() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Number of breakpoints for DR3"); - event_id = 0xDF; - unitEncode = FR; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DR3_BREAKPOINTS"); - - -}; - - - -// E0 -typedef union EVENT_MASK( k8_page_access_event) -{ - struct - { - uint16 PageHit:1; // Page hit" }, - uint16 PageMiss:1; // Page miss" }, - uint16 PageConflict:1; // Page conflict" } } - }; - uint16 flat; - -}EVENT_MASK( k8_page_access_event); - -class k8Event_MEM_PAGE_ACCESS : public k8BaseEvent -{ -public: - - k8Event_MEM_PAGE_ACCESS() - { - eventMask = (EVENT_MASK(k8_page_access_event) *)&m_eventMask; - name = _T("Memory controller page access"); - event_id = 0xE0; - unitEncode = NB; - - } - EVENT_MASK(k8_page_access_event) * eventMask; - // name = _T("MEM_PAGE_ACCESS"); - - -}; -class k8Event_MEM_PAGE_TBL_OVERFLOW : public k8BaseEvent -{ -public: - - k8Event_MEM_PAGE_TBL_OVERFLOW() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Memory controller page table overflow"); - event_id = 0xE1; - unitEncode = NB; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("MEM_PAGE_TBL_OVERFLOW"); - - -}; -class k8Event_DRAM_SLOTS_MISSED : public k8BaseEvent -{ -public: - - k8Event_DRAM_SLOTS_MISSED() - { - eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask; - name = _T("Memory controller DRAM command slots missed (in MemClks)"); - event_id = 0xE2; - unitEncode = NB; - - } - EVENT_MASK(NULL_MASK) * eventMask; - // name = _T("DRAM_SLOTS_MISSED"); - - -}; - - -// e3 -typedef union EVENT_MASK( k8_turnaround) -{ - - struct - { - uint16 DIMMTurnaround:1; //DIMM turnaround" }, - uint16 ReadToWriteTurnaround:1; //Read to write turnaround" }, - uint16 WriteToReadTurnaround:1; //Write to read turnaround" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_turnaround); - -class k8Event_MEM_TURNAROUND : public k8BaseEvent -{ -public: - - k8Event_MEM_TURNAROUND() - { - eventMask = (EVENT_MASK(k8_turnaround) *)&m_eventMask; - name = _T("Memory controller turnaround"); - event_id = 0xE3; - unitEncode = NB; - - } - EVENT_MASK(k8_turnaround) * eventMask; - // name = _T("MEM_TURNAROUND"); - - -}; - - - - -// E4 -typedef union EVENT_MASK( k8_bypass_counter_saturation) -{ - struct - { - uint16 MEM_HighPriorityBypass:1; // Memory controller high priority bypass" }, - uint16 MEM_LowPriorityBypass:1; // Memory controller low priority bypass" }, - uint16 DRAM_InterfaceBypass:1; // DRAM controller interface bypass" }, - uint16 DRAM_QueueBypass:1; // DRAM controller queue bypass" } } - }; - uint16 flat; - -}EVENT_MASK( k8_bypass_counter_saturation); - -class k8Event_MEM_BYPASS_SAT : public k8BaseEvent -{ -public: - - k8Event_MEM_BYPASS_SAT() - { - eventMask = (EVENT_MASK(k8_bypass_counter_saturation) *)&m_eventMask; - name = _T("Memory controller bypass counter saturation"); - event_id = 0xE4; - unitEncode = NB; - - } - EVENT_MASK(k8_bypass_counter_saturation) * eventMask; - // name = _T("MEM_BYPASS_SAT"); - - -}; - - - -//EB -typedef union EVENT_MASK( k8_sized_commands) -{ - - struct - { - uint16 NonPostWrSzByte:1; // NonPostWrSzByte" }, - uint16 NonPostWrSzDword:1; // NonPostWrSzDword" }, - uint16 PostWrSzByte:1; // PostWrSzByte" }, - uint16 PostWrSzDword:1; // PostWrSzDword" }, - uint16 RdSzByte:1; // RdSzByte" }, - uint16 RdSzDword:1; // RdSzDword" }, - uint16 RdModWr:1; // RdModWr" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_sized_commands); - - -class k8Event_SIZED_COMMANDS : public k8BaseEvent -{ -public: - - k8Event_SIZED_COMMANDS() - { - eventMask = (EVENT_MASK(k8_sized_commands) *)&m_eventMask; - name = _T("Sized commands"); - event_id = 0xEB; - unitEncode = NB; - - } - EVENT_MASK(k8_sized_commands) * eventMask; - // name = _T("SIZED_COMMANDS"); - - -}; - -typedef union EVENT_MASK( k8_probe_result) -{ - struct - { - uint16 ProbeMiss:1; // Probe miss" }, - uint16 ProbeHit:1; // Probe hit" }, - uint16 ProbeHitDirtyWithoutMemoryCancel:1; // Probe hit dirty without memory cancel" }, - uint16 ProbeHitDirtyWithMemoryCancel:1; // Probe hit dirty with memory cancel" } } - uint16 UpstreamDisplayRefreshReads:1; // Rev D and later - uint16 UpstreamNonDisplayRefreshReads:1; // Rev D and later - uint16 UpstreamWrites:1; // Rev D and later - }; - uint16 flat; - - -}EVENT_MASK( k8_probe_result); - - -class k8Event_PROBE_RESULT : public k8BaseEvent -{ -public: - - k8Event_PROBE_RESULT() - { - eventMask = (EVENT_MASK(k8_probe_result) *)&m_eventMask; - name = _T("Probe result"); - event_id = 0xEC; - unitEncode = NB; - - } - EVENT_MASK(k8_probe_result) * eventMask; - // name = _T("PROBE_RESULT"); - - -}; - -typedef union EVENT_MASK( k8_ht) -{ - - struct - { - uint16 CommandSent:1; //Command sent" }, - uint16 DataSent:1; //Data sent" }, - uint16 BufferReleaseSent:1; //Buffer release sent" - uint16 NopSent:1; //Nop sent" } } - }; - uint16 flat; - - -}EVENT_MASK( k8_ht); - - -class k8Event_HYPERTRANSPORT_BUS0_WIDTH : public k8BaseEvent -{ -public: - - k8Event_HYPERTRANSPORT_BUS0_WIDTH() - { - eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask; - name = _T("Hypertransport (tm) bus 0 bandwidth"); - event_id = 0xF6; - unitEncode = NB; - - } - EVENT_MASK(k8_ht) * eventMask; - // name = _T("HYPERTRANSPORT_BUS0_WIDTH"); - - -}; -class k8Event_HYPERTRANSPORT_BUS1_WIDTH : public k8BaseEvent -{ -public: - - k8Event_HYPERTRANSPORT_BUS1_WIDTH() - { - eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask; - name = _T("Hypertransport (tm) bus 1 bandwidth"); - event_id = 0xF7; - unitEncode = NB; - - } - EVENT_MASK(k8_ht) * eventMask; - // name = _T("HYPERTRANSPORT_BUS1_WIDTH"); - - -}; -class k8Event_HYPERTRANSPORT_BUS2_WIDTH : public k8BaseEvent -{ -public: - - k8Event_HYPERTRANSPORT_BUS2_WIDTH() - { - eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask; - name = _T("Hypertransport (tm) bus 2 bandwidth"); - event_id = 0xF8; - unitEncode = NB; - - } - EVENT_MASK(k8_ht) * eventMask; - // name = _T("HYPERTRANSPORT_BUS2_WIDTH"); - -}; - -// -//typedef union EVENT_MASK( perfctr_event_set k8_common_event_set) -//{ -// -// .cpu_type = PERFCTR_X86_AMD_K8, -// .event_prefix = _T("K8_"), -// .include = &k7_official_event_set, -// .nevents = ARRAY_SIZE(k8_common_events), -// .events = k8_common_events, -//}EVENT_MASK( perfctr_event_set k8_common_event_set); -// -//typedef union EVENT_MASK( perfctr_event k8_events[]) -//{ -// -// { 0x24, 0xF, UM(NULL), _T("LOCKED_OP"), /* unit mask changed in Rev. C */ -// _T("Locked operation") }, -//}EVENT_MASK( perfctr_event k8_events[]); - - - - -//const struct perfctr_event_set perfctr_k8_event_set) -//{ -// -// .cpu_type = PERFCTR_X86_AMD_K8, -// .event_prefix = _T("K8_"), -// .include = &k8_common_event_set, -// .nevents = ARRAY_SIZE(k8_events), -// .events = k8_events, -//}; -// -/* - * K8 Revision C. Starts at CPUID 0xF58 for Opteron/Athlon64FX and - * CPUID 0xF48 for Athlon64. (CPUID 0xF51 is Opteron Revision B3.) - */ - - - - - - - - -// -//typedef union EVENT_MASK( k8_lock_accesses) -//{ -// struct -// { -// uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" }, -// uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } } -// }; -// uint16 flat; -// -//}EVENT_MASK( k8_lock_accesses); -// - -#endif // K8PERFORMANCECOUNTERS_H diff --git a/Resources/NetHook/tier0/P4PerformanceCounters.h b/Resources/NetHook/tier0/P4PerformanceCounters.h deleted file mode 100644 index d4487785..00000000 --- a/Resources/NetHook/tier0/P4PerformanceCounters.h +++ /dev/null @@ -1,322 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef P4PERFORMANCECOUNTERS_H -#define P4PERFORMANCECOUNTERS_H - -#pragma once -// Pentium 4 support - -/* - http://developer.intel.com/design/Pentium4/documentation.htm - - IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture - - IA-32 Intel Architecture Software Developer's Manual Volume 2A: Instruction Set Reference, A-M - - IA-32 Intel Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z - - IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming Guide - - - From Mikael Pettersson's perfctr: - - http://user.it.uu.se/~mikpe/linux/perfctr/ - - * Known quirks: - - OVF_PMI+FORCE_OVF counters must have an ireset value of -1. - This allows the regular overflow check to also handle FORCE_OVF - counters. Not having this restriction would lead to MAJOR - complications in the driver's "detect overflow counters" code. - There is no loss of functionality since the ireset value doesn't - affect the counter's PMI rate for FORCE_OVF counters. - - - In experiments with FORCE_OVF counters, and regular OVF_PMI - counters with small ireset values between -8 and -1, it appears - that the faulting instruction is subjected to a new PMI before - it can complete, ad infinitum. This occurs even though the driver - clears the CCCR (and in testing also the ESCR) and invokes a - user-space signal handler before restoring the CCCR and resuming - the instruction. -*/ - -#define NCOUNTERS 18 - -// The 18 counters -enum Counters -{ - MSR_BPU_COUNTER0, - MSR_BPU_COUNTER1, - MSR_BPU_COUNTER2, - MSR_BPU_COUNTER3, - MSR_MS_COUNTER0, - MSR_MS_COUNTER1, - MSR_MS_COUNTER2, - MSR_MS_COUNTER3, - MSR_FLAME_COUNTER0, - MSR_FLAME_COUNTER1, - MSR_FLAME_COUNTER2, - MSR_FLAME_COUNTER3, - MSR_IQ_COUNTER0, - MSR_IQ_COUNTER1, - MSR_IQ_COUNTER2, - MSR_IQ_COUNTER3, - MSR_IQ_COUNTER4, - MSR_IQ_COUNTER5 -}; - -// register base for counters -#define MSR_COUNTER_BASE 0x300 - -// register base for CCCR register -#define MSR_CCCR_BASE 0x360 - -#pragma pack(push, 1) -// access to these bits is through the methods -typedef union ESCR -{ - struct - { - uint64 Reserved0_1 : 2; // - uint64 USR : 1; // - uint64 OS : 1; // - uint64 TagEnable : 1; // - uint64 TagValue : 4; // - uint64 EventMask : 16; // from event select - uint64 ESCREventSelect : 6; // 31:25 class of event - uint64 Reserved31 : 1; // - - uint64 Reserved32_63 : 32; // - }; - uint64 flat; - -} ESCR; - -typedef union CCCR -{ - struct - { - uint64 Reserved0_11 : 12;// 0 -11 - uint64 Enable : 1; // 12 - uint64 CCCRSelect : 3; // 13-15 - uint64 Reserved16_17 : 2; // 16 17 - - uint64 Compare : 1; // 18 - uint64 Complement : 1; // 19 - uint64 Threshold : 4; // 20-23 - uint64 Edge : 1; // 24 - uint64 FORCE_OVF : 1; // 25 - uint64 OVF_PMI : 1; // 26 - uint64 Reserved27_29 : 3; // 27-29 - uint64 Cascade : 1; // 30 - uint64 OVF : 1; // 31 - - uint64 Reserved32_63 : 32; // - }; - uint64 flat; - -} CCCR; - -#pragma pack(pop) - -extern const unsigned short cccr_escr_map[NCOUNTERS][8]; - -enum P4TagState -{ - TagDisable, // - TagEnable, // -}; - -enum P4ForceOverflow -{ - ForceOverflowDisable, - ForceOverflowEnable, -}; - -enum P4OverflowInterrupt -{ - OverflowInterruptDisable, - OverflowInterruptEnable, -}; - -// Turn off the no return value warning in ReadCounter. -#pragma warning( disable : 4035 ) -class P4BaseEvent -{ - int m_counter; - -protected: - - void SetCounter(int counter) - { - m_counter = counter; - cccrPort = MSR_CCCR_BASE + m_counter; - counterPort = MSR_COUNTER_BASE + m_counter; - escrPort = cccr_escr_map[m_counter][cccr.CCCRSelect]; - } - -public: - - unsigned short m_eventMask; - const tchar *description; - PME *pme; - ESCR escr; - CCCR cccr; - int counterPort; - int cccrPort; - int escrPort; - - P4BaseEvent() - { - pme = PME::Instance(); - m_eventMask = 0; - description = _T(""); - escr.flat = 0; - cccr.flat = 0; - cccr.Reserved16_17 = 3; // must be set - escrPort = 0; - m_counter = -1; - } - - void StartCounter() - { - cccr.Enable = 1; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void StopCounter() - { - cccr.Enable = 0; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void ClearCounter() - { - pme->WriteMSR( counterPort, 0ui64 ); // clear - } - - void WriteCounter( int64 value ) - { - pme->WriteMSR( counterPort, value ); // clear - } - - int64 ReadCounter() - { -#if PME_DEBUG - if ( escr.USR == 0 && escr.OS == 0 ) - return -1; // no area to collect, use SetCaptureMode - - if ( escr.EventMask == 0 ) - return -2; // no event mask set - - if ( m_counter == -1 ) - return -3; // counter not legal -#endif - - // ReadMSR should work here too, but RDPMC should be faster - int64 value = 0; - pme->ReadMSR( counterPort, &value ); - return value; -#if 0 - // we need to copy this into a temp for some reason - int temp = m_counter; - _asm - { - mov ecx, temp - RDPMC - } -#endif - } - - void SetCaptureMode( PrivilegeCapture priv ) - { - switch ( priv ) - { - case OS_Only: - { - escr.USR = 0; - escr.OS = 1; - break; - } - case USR_Only: - { - escr.USR = 1; - escr.OS = 0; - break; - } - case OS_and_USR: - { - escr.USR = 1; - escr.OS = 1; - break; - } - } - - escr.EventMask = m_eventMask; - pme->WriteMSR( escrPort, escr.flat ); - } - - void SetTagging( P4TagState tagEnable, uint8 tagValue ) - { - escr.TagEnable = tagEnable; - escr.TagValue = tagValue; - pme->WriteMSR( escrPort, escr.flat ); - } - - void SetFiltering( CompareState compareEnable, CompareMethod compareMethod, uint8 threshold, EdgeState edgeEnable ) - { - cccr.Compare = compareEnable; - cccr.Complement = compareMethod; - cccr.Threshold = threshold; - cccr.Edge = edgeEnable; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void SetOverflowEnables( P4ForceOverflow overflowEnable, P4OverflowInterrupt overflowInterruptEnable ) - { - cccr.FORCE_OVF = overflowEnable; - cccr.OVF_PMI = overflowInterruptEnable; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void SetOverflow() - { - cccr.OVF = 1; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void ClearOverflow() - { - cccr.OVF = 0; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - bool isOverflow() - { - CCCR cccr_temp; - pme->ReadMSR( cccrPort, &cccr_temp.flat ); - return cccr_temp.OVF; - } - - void SetCascade() - { - cccr.Cascade = 1; - pme->WriteMSR( cccrPort, cccr.flat ); - } - - void ClearCascade() - { - cccr.Cascade = 0; - pme->WriteMSR( cccrPort, cccr.flat ); - } -}; -#pragma warning( default : 4035 ) - -#include "EventMasks.h" -#include "EventModes.h" - -#endif // P4PERFORMANCECOUNTERS_H diff --git a/Resources/NetHook/tier0/P5P6PerformanceCounters.h b/Resources/NetHook/tier0/P5P6PerformanceCounters.h deleted file mode 100644 index 5a0a5e66..00000000 --- a/Resources/NetHook/tier0/P5P6PerformanceCounters.h +++ /dev/null @@ -1,225 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef P5P6PERFORMANCECOUNTERS_H -#define P5P6PERFORMANCECOUNTERS_H - -// defined for < Pentium 4 - -//--------------------------------------------------------------------------- -// Format of the performance event IDs within this header file in case you -// wish to add any additional events that may not be present here. -// -// BITS 0-8 Unit Mask, Unsed on P5 processors -// BIT 9 Set if event can be set on counter 0 -// BIT 10 Set if event can be set on counter 1 -// BITS 11-15 Unused Set to zero -// BITS 16-23 Event Select ID, Only bits 16-21 used on P5 Family -// BITS 24-27 Unused set to zero -// BITS 28-32 Process family that the event belong to, as returned by -// the CPUID instruction. -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// PENTIUM PERFORMANCE COUNTERS. -//--------------------------------------------------------------------------- -#define P5_DTCRD 0x50000300 //Data Cache Reads -#define P5_DWRIT 0x50010300 //Data Cache Writes -#define P5_DTTLB 0x50020300 //Data TLB Miss -#define P5_DTRMS 0x50030300 //Data Read Misses -#define P5_DWRMS 0x50040300 //Data Write Miss -#define P5_WHLCL 0x50050300 //Write (Hit) to M- or E-state line -#define P5_DCLWB 0x50060300 //Data Cache Lines Written Back -#define P5_DCSNP 0x50070300 //External Snoops -#define P5_DCSHT 0x50080300 //Data Cache Snoop Hits -#define P5_MAIBP 0x50090300 //Memory Access in Both Pipes -#define P5_BANKS 0x500A0300 //Bank Conflicts -#define P5_MISAL 0x500B0300 //Misaligned Data Memory Reference -#define P5_COCRD 0x500C0300 //Code Cache Reads -#define P5_COTLB 0x500D0300 //Code TLB Misses -#define P5_COCMS 0x500E0300 //Code Cache Misses -#define P5_ANYSG 0x500F0300 //Any Segment Register Loaded -#define P5_BRANC 0x50120300 //Branches -#define P5_BTBHT 0x50130300 //BTB Hits -#define P5_TBRAN 0x50140300 //Taken Branch or BTB hit -#define P5_PFLSH 0x50150300 //Pipeline flushes -#define P5_INSTR 0x50160300 //Instructions Executed -#define P5_INSTV 0x50170300 //Instructions Executed in the V-Pipe (Pairing) -#define P5_CLOCL 0x50180300 //Bus active -#define P5_PSDWR 0x50190300 //Full write buffers -#define P5_PSWDR 0x501A0300 //Waiting for Data Memory Read -#define P5_NCLSW 0x501B0300 //Clocks stalled writing an E or M state line -#define P5_IORWC 0x501D0300 //I/O Read or Write Cycle -#define P5_NOCMR 0x501E0300 //Non-Cacheable Memory Reads -#define P5_PSLDA 0x501F0300 //Clocks stalled due to AGI -#define P5_FLOPS 0x50220300 //Floating Point Operations -#define P5_DBGR0 0x50230300 //Breakpoint match on DR0 -#define P5_DBGR1 0x50240300 //Breakpoint match on DR1 -#define P5_DBGR2 0x50250300 //Breakpoint match on DR2 -#define P5_DBGR3 0x50260300 //Breakpoint match on DR3 -#define P5_HWINT 0x50270300 //Hardware interrupts -#define P5_DTRWR 0x50280300 //Data reads or writes -#define P5_DTRWM 0x50290300 //Data read or write miss -#define P5_BOLAT 0x502A0100 //Bus ownership latency -#define P5_BOTFR 0x502A0200 //Bus ownership transfer -#define P5_MMXA1 0x502B0100 //MMX Instruction Executed in U-pipe -#define P5_MMXA2 0x502B0200 //MMX Instruction Executed in V-pipe -#define P5_MMXMS 0x502C0100 //Cache M state line sharing -#define P5_MMSLS 0x502C0200 //Cache line sharing -#define P5_MMXB1 0x502D0100 //EMMS Instructions Executed -#define P5_MMXB2 0x502D0200 //Transition from MMX to FP instructions -#define P5_NOCMW 0x502E0200 //Non-Cacheable Memory Writes -#define P5_MMXC1 0x502F0100 //Saturated MMX Instructions Executed -#define P5_MMXC2 0x502F0200 //Saturations Performed -#define P5_MMXHS 0x50300100 //Cycles Not in HALT State -#define P5_MMXD2 0x50310100 //MMX Data Read -#define P5_MMXFP 0x50320100 //Floating Point Stalls -#define P5_MMXTB 0x50320200 //Taken Branches -#define P5_MMXD0 0x50330100 //D1 Starvation and FIFO Empty -#define P5_MMXD1 0x50330200 //D1 Starvation and one instruction in FIFO -#define P5_MMXE1 0x50340100 //MMX Data Writes -#define P5_MMXE2 0x50340200 //MMX Data Write Misses -#define P5_MMXWB 0x50350100 //Pipeline flushes, wrong branch prediction -#define P5_MMXWJ 0x50350200 //Pipeline flushes, branch prediction WB-stage -#define P5_MMXF1 0x50360100 //Misaligned MMX Data Memory Reference -#define P5_MMXF2 0x50360200 //Pipeline Stalled Waiting for MMX data read -#define P5_MMXRI 0x50370100 //Returns Predicted Incorrectly -#define P5_MMXRP 0x50370200 //Returns Predicted -#define P5_MMXG1 0x50380100 //MMX Multiply Unit Interlock -#define P5_MMXG2 0x50380200 //MOVD/MOVQ store stall, previous operation -#define P5_MMXRT 0x50390100 //Returns -#define P5_MMXRO 0x50390200 //RSB Overflows -#define P5_MMXBF 0x503A0100 //BTB False entries -#define P5_MMXBM 0x503A0200 //BTB misprediction on a Not-Taken Branch -#define P5_PXDWR 0x503B0100 //stalled due MMX Full write buffers -#define P5_PXZWR 0x503B0200 //stalled on MMX write to E or M state line - -#define P5_CLOCK 0x503F0300 //Special value to count clocks on P5 - - -//--------------------------------------------------------------------------- -// PENTIUM PRO / PENTIUM II PERFORMANCE COUNTERS. -//--------------------------------------------------------------------------- -#define P6_STRBB 0x60030300 //Store Buffer Block -#define P6_STBDC 0x60040300 //Store Buffer Drain Cycles -#define P6_MISMM 0x60050300 //Misaligned Data Memory Reference -#define P6_SEGLD 0x60060300 //Segment register loads -#define P6_FPOPE 0x60100100 //FP Computational Op. (COUNTER 0 ONLY) -#define P6_FPEOA 0x60110200 //FP Microcode Exceptions (COUNTER 1 ONLY) -#define P6_FMULT 0x60120200 //Multiplies (COUNTER 1 ONLY) -#define P6_FPDIV 0x60130200 //Divides (COUNTER 1 ONLY) -#define P6_DBUSY 0x60140200 //Cycles Divider Busy (COUNTER 1 ONLY) -#define P6_L2STR 0x60210300 //L2 address strobes => address bus utilization -#define P6_L2BBS 0x60220300 //Cycles L2 Bus Busy -#define P6_L2BBT 0x60230300 //Cycles L2 Bus Busy transferring data to CPU -#define P6_L2ALO 0x60240300 //L2 Lines Allocated -#define P6_L2MAL 0x60250300 //L2 M-state Lines Allocated -#define P6_L2CEV 0x60260300 //L2 Lines Evicted -#define P6_L2MEV 0x60270300 //L2 M-state Lines Evicted -#define P6_L2MCF 0x60280301 //L2 Cache Instruction Fetch Misses -#define P6_L2FET 0x6028030F //L2 Cache Instruction Fetches -#define P6_L2DRM 0x60290301 //L2 Cache Read Misses -#define P6_L2DMR 0x6029030F //L2 Cache Reads -#define P6_L2DWM 0x602A0301 //L2 Cache Write Misses -#define P6_L2DMW 0x602A030F //L2 Cache Writes -#define P6_L2CMS 0x602E0301 //L2 Cache Request Misses -#define P6_L2DCR 0x602E030F //L2 Cache Requests -#define P6_DMREF 0x60430300 //Data Memory References -#define P6_DCALO 0x6045030F //L1 Lines Allocated -#define P6_DCMAL 0x60460300 //L1 M-state Data Cache Lines Allocated -#define P6_DCMEV 0x60470300 //L1 M-state Data Cache Lines Evicted -#define P6_DCOUT 0x60480300 //L1 Misses outstanding -#define P6_TSMCD 0x60520300 //Time Self-Modifiying Code Detected -#define P6_BRWRA 0x60600300 //External Bus Cycles While Receive Active -#define P6_BRDCD 0x60600300 //External Bus Request Outstanding -#define P6_BRBNR 0x60610300 //External Bus Cycles While BNR Asserted -#define P6_BUSBS 0x60620300 //External Bus Cycles-DRDY Asserted (busy) -#define P6_BLOCK 0x60630300 //External Bus Cycles-LOCK signal asserted -#define P6_BBRCV 0x60640300 //External Bus Cycles-Processor receiving data -#define P6_BURST 0x60650300 //External Bus Burst Read Operations -#define P6_BRINV 0x60660300 //External Bus Read for Ownership Transaction -#define P6_BMLEV 0x60670300 //External Bus Writeback M-state Evicted -#define P6_BBIFT 0x60680300 //External Bus Burst Instruction Fetches -#define P6_BINVL 0x60690300 //External Bus Invalidate Transactions -#define P6_BPRBT 0x606A0300 //External Bus Partial Read Transactions -#define P6_BPTMO 0x606B0300 //External Bus Partial Memory Transactions -#define P6_BUSIO 0x606C0300 //External Bus I/O Bus Transactions -#define P6_BUSDF 0x606D0300 //External Bus Deferred Transactions -#define P6_BUSTB 0x606E0300 //External Bus Burst Transactions -#define P6_BMALL 0x606F0300 //External Bus Memory Transactions -#define P6_BSALL 0x60700300 //External Bus Transactions -#define P6_CLOCK 0x60790300 //Clockticks -#define P6_BRHIT 0x607A0300 //External Bus Cycles While HIT Asserted -#define P6_BRHTM 0x607B0300 //External Bus Cycles While HITM Asserted -#define P6_BRSST 0x607E0300 //External Bus Cycles While Snoop Stalled -#define P6_CMREF 0x60800300 //Total Instruction Fetches -#define P6_TOIFM 0x60810300 //Total Instruction Fetch Misses -#define P6_INTLB 0x60850300 //Instructions TLB Misses -#define P6_CSFET 0x60860300 //Cycles Instruction Fetch Stalled -#define P6_FTSTL 0x60870300 //Cycles Instruction Fetch stalled -#define P6_RSTAL 0x60A20300 //Resource Related Stalls -#define P6_MMXIE 0x60B00300 //MMX Instructions Executed -#define P6_SAISE 0x60B10300 //Saturated Arithmetic Instructions Executed -#define P6_PORT0 0x60B20301 //MMX micro-ops executed on Port 0 -#define P6_PORT1 0x60B20302 //MMX micro-ops executed on Port 1 -#define P6_PORT2 0x60B20304 //MMX micro-ops executed on Port 2 -#define P6_PORT3 0x60B20308 //MMX micro-ops executed on Port 3 -#define P6_MMXPA 0x60B30300 //MMX Packed Arithmetic -#define P6_MMXPM 0x60B30301 //MMX Packed Multiply -#define P6_MMXPS 0x60B30302 //MMX Packed Shift -#define P6_MMXPO 0x60B30304 //MMX Packed Operations -#define P6_MMXUO 0x60B30308 //MMX Unpacked Operations -#define P6_MMXPL 0x60B30310 //MMX Packed Logical -#define P6_INSTR 0x60C00300 //Instructions Retired -#define P6_FPOPS 0x60C10100 //FP operations retired (COUNTER 0 ONLY) -#define P6_UOPSR 0x60C20300 //Micro-Ops Retired -#define P6_BRRET 0x60C40300 //Branch Instructions Retired -#define P6_BRMSR 0x60C50300 //Branch Mispredictions Retired -#define P6_MASKD 0x60C60300 //Clocks while interrupts masked -#define P6_MSKPN 0x60C70300 //Clocks while interrupt is pending -#define P6_HWINT 0x60C80300 //Hardware Interrupts Received -#define P6_BTAKR 0x60C90300 //Taken Branch Retired -#define P6_BTAKM 0x60CA0300 //Taken Branch Mispredictions -#define P6_FPMMX 0x60CC0301 //Transitions from Floating Point to MMX -#define P6_MMXFP 0x60CC0300 //Transitions from MMX to Floating Point -#define P6_SIMDA 0x60CD0300 //SIMD Assists (EMMS Instructions Executed) -#define P6_MMXIR 0x60CE0300 //MMX Instructions Retired -#define P6_SAISR 0x60CF0300 //Saturated Arithmetic Instructions Retired -#define P6_INSTD 0x60D00300 //Instructions Decoded -#define P6_NPRTL 0x60D20300 //Renaming Stalls -#define P6_SRSES 0x60D40301 //Segment Rename Stalls - ES -#define P6_SRSDS 0x60D40302 //Segment Rename Stalls - DS -#define P6_SRSFS 0x60D40304 //Segment Rename Stalls - FS -#define P6_SRSGS 0x60D40308 //Segment Rename Stalls - GS -#define P6_SRSXS 0x60D4030F //Segment Rename Stalls - ES DS FS GS -#define P6_SRNES 0x60D50301 //Segment Renames - ES -#define P6_SRNDS 0x60D50302 //Segment Renames - DS -#define P6_SRNFS 0x60D50304 //Segment Renames - FS -#define P6_SRNGS 0x60D50308 //Segment Renames - GS -#define P6_SRNXS 0x60D5030F //Segment Renames - ES DS FS GS -#define P6_BRDEC 0x60E00300 //Branch Instructions Decoded -#define P6_BTBMS 0x60E20301 //BTB Misses -#define P6_RETDC 0x60E40300 //Bogus Branches -#define P6_BACLR 0x60E60300 //BACLEARS Asserted (Testing) - - - - - - -// INTEL -#define PENTIUM_FAMILY 5 // define for pentium -#define PENTIUMPRO_FAMILY 6 // define for pentium pro -#define PENTIUM4_FAMILY 15 // define for pentium 4 - - -// AMD -#define K6_FAMILY 5 -#define K8_FAMILY 6 -#define EXTENDED_FAMILY 15 // AMD 64 and AMD Opteron - -#endif // P5P6PERFORMANCECOUNTERS_H diff --git a/Resources/NetHook/tier0/PMELib.h b/Resources/NetHook/tier0/PMELib.h deleted file mode 100644 index d989a5f8..00000000 --- a/Resources/NetHook/tier0/PMELib.h +++ /dev/null @@ -1,195 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef PMELIB_H -#define PMELIB_H - -#include "Windows.h" -#include "tier0/platform.h" - -// Get rid of a bunch of STL warnings! -#pragma warning( push, 3 ) -#pragma warning( disable : 4018 ) - -#define VERSION "1.0.2" - -// uncomment this list to add some runtime checks -//#define PME_DEBUG - -#include "tier0/valve_off.h" -#include -#include "tier0/valve_on.h" - -using namespace std; - -// RDTSC Instruction macro -#define RDTSC(var) \ -_asm RDTSC \ -_asm mov DWORD PTR var,eax \ -_asm mov DWORD PTR var+4,edx - -// RDPMC Instruction macro -#define RDPMC(counter, var) \ -_asm mov ecx, counter \ -_asm RDPMC \ -_asm mov DWORD PTR var,eax \ -_asm mov DWORD PTR var+4,edx - -// RDPMC Instruction macro, for performance counter 1 (ecx = 1) -#define RDPMC0(var) \ -_asm mov ecx, 0 \ -_asm RDPMC \ -_asm mov DWORD PTR var,eax \ -_asm mov DWORD PTR var+4,edx - -#define RDPMC1(var) \ -_asm mov ecx, 1 \ -_asm RDPMC \ -_asm mov DWORD PTR var,eax \ -_asm mov DWORD PTR var+4,edx - -#define EVENT_TYPE(mode) EventType##mode -#define EVENT_MASK(mode) EventMask##mode - -#include "ia32detect.h" - -enum ProcessPriority -{ - ProcessPriorityNormal, - ProcessPriorityHigh, -}; - -enum PrivilegeCapture -{ - OS_Only, // ring 0, kernel level - USR_Only, // app level - OS_and_USR, // all levels -}; - -enum CompareMethod -{ - CompareGreater, // - CompareLessEqual, // -}; - -enum EdgeState -{ - RisingEdgeDisabled, // - RisingEdgeEnabled, // -}; - -enum CompareState -{ - CompareDisable, // - CompareEnable, // -}; - -// Singletion Class -class PME : public ia32detect -{ -public: -//private: - - static PME* _singleton; - - HANDLE hFile; - bool bDriverOpen; - double m_CPUClockSpeed; - - //ia32detect detect; - HRESULT Init(); - HRESULT Close(); - -protected: - - PME() - { - hFile = NULL; - bDriverOpen = FALSE; - m_CPUClockSpeed = 0; - Init(); - } - -public: - - static PME* Instance(); // gives back a real object - - ~PME() - { - Close(); - } - - double GetCPUClockSpeedSlow( void ); - double GetCPUClockSpeedFast( void ); - - HRESULT SelectP5P6PerformanceEvent( uint32 dw_event, uint32 dw_counter, bool b_user, bool b_kernel ); - - HRESULT ReadMSR( uint32 dw_reg, int64 * pi64_value ); - HRESULT ReadMSR( uint32 dw_reg, uint64 * pi64_value ); - - HRESULT WriteMSR( uint32 dw_reg, const int64 & i64_value ); - HRESULT WriteMSR( uint32 dw_reg, const uint64 & i64_value ); - - void SetProcessPriority( ProcessPriority priority ) - { - switch( priority ) - { - case ProcessPriorityNormal: - { - SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS); - SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_NORMAL); - break; - } - case ProcessPriorityHigh: - { - SetPriorityClass (GetCurrentProcess(),REALTIME_PRIORITY_CLASS); - SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_HIGHEST); - break; - } - } - } - - //--------------------------------------------------------------------------- - // Return the family of the processor - //--------------------------------------------------------------------------- - CPUVendor GetVendor(void) - { - return vendor; - } - - int GetProcessorFamily(void) - { - return version.Family; - } - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE - -}; - -#include "P5P6PerformanceCounters.h" -#include "P4PerformanceCounters.h" -#include "K8PerformanceCounters.h" - -enum PerfErrors -{ - E_UNKNOWN_CPU_VENDOR = -1, - E_BAD_COUNTER = -2, - E_UNKNOWN_CPU = -3, - E_CANT_OPEN_DRIVER = -4, - E_DRIVER_ALREADY_OPEN = -5, - E_DRIVER_NOT_OPEN = -6, - E_DISABLED = -7, - E_BAD_DATA = -8, - E_CANT_CLOSE = -9, - E_ILLEGAL_OPERATION = -10, -}; - -#pragma warning( pop ) - -#endif // PMELIB_H \ No newline at end of file diff --git a/Resources/NetHook/tier0/afxmem_override.cpp b/Resources/NetHook/tier0/afxmem_override.cpp deleted file mode 100644 index c1abbd23..00000000 --- a/Resources/NetHook/tier0/afxmem_override.cpp +++ /dev/null @@ -1,460 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -// File extracted from MFC due to symbol conflicts - -// This is a part of the Microsoft Foundation Classes C++ library. -// Copyright (C) Microsoft Corporation -// All rights reserved. -// -// This source code is only intended as a supplement to the -// Microsoft Foundation Classes Reference and related -// electronic documentation provided with the library. -// See these sources for detailed information regarding the -// Microsoft Foundation Classes product. - -#include "stdafx.h" - -#ifdef AFX_CORE1_SEG -#pragma code_seg(AFX_CORE1_SEG) -#endif - - -///////////////////////////////////////////////////////////////////////////// -// Debug memory globals and implementation helpers - -#ifdef _DEBUG // most of this file is for debugging - -void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine); -#if _MSC_VER >= 1210 -void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine); -#endif - -///////////////////////////////////////////////////////////////////////////// -// test allocation routines - -void* PASCAL CObject::operator new(size_t nSize) -{ -#ifdef _AFX_NO_DEBUG_CRT - return ::operator new(nSize); -#else - return ::operator new(nSize, _AFX_CLIENT_BLOCK, NULL, 0); -#endif // _AFX_NO_DEBUG_CRT -} - -void PASCAL CObject::operator delete(void* p) -{ -#ifdef _AFX_NO_DEBUG_CRT - free(p); -#else - _free_dbg(p, _AFX_CLIENT_BLOCK); -#endif -} - -#if _MSC_VER >= 1200 -void PASCAL CObject::operator delete(void* p, void*) -{ -#ifdef _AFX_NO_DEBUG_CRT - free(p); -#else - _free_dbg(p, _AFX_CLIENT_BLOCK); -#endif -} -#endif - -#ifndef _AFX_NO_DEBUG_CRT - -void* __cdecl operator new(size_t nSize, LPCSTR lpszFileName, int nLine) -{ - return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine); -} - -#if _MSC_VER >= 1210 -void* __cdecl operator new[](size_t nSize, LPCSTR lpszFileName, int nLine) -{ - return ::operator new[](nSize, _NORMAL_BLOCK, lpszFileName, nLine); -} -#endif - -#if _MSC_VER >= 1200 -void __cdecl operator delete(void* pData, LPCSTR /* lpszFileName */, - int /* nLine */) -{ - ::operator delete(pData); -} -#endif - -#if _MSC_VER >= 1210 -void __cdecl operator delete[](void* pData, LPCSTR /* lpszFileName */, - int /* nLine */) -{ - ::operator delete(pData); -} -#endif - -void* PASCAL -CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine) -{ - return ::operator new(nSize, _AFX_CLIENT_BLOCK, lpszFileName, nLine); -} - -#if _MSC_VER >= 1200 -void PASCAL -CObject::operator delete(void *pObject, LPCSTR /* lpszFileName */, - int /* nLine */) -{ -#ifdef _AFX_NO_DEBUG_CRT - free(pObject); -#else - _free_dbg(pObject, _AFX_CLIENT_BLOCK); -#endif -} -#endif - -void* AFXAPI AfxAllocMemoryDebug(size_t nSize, BOOL bIsObject, LPCSTR lpszFileName, int nLine) -{ - return _malloc_dbg(nSize, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK, - lpszFileName, nLine); -} - -void AFXAPI AfxFreeMemoryDebug(void* pbData, BOOL bIsObject) -{ - _free_dbg(pbData, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK); -} - -///////////////////////////////////////////////////////////////////////////// -// allocation failure hook, tracking turn on - -BOOL AFXAPI _AfxDefaultAllocHook(size_t, BOOL, LONG) - { return TRUE; } - -AFX_STATIC_DATA AFX_ALLOC_HOOK pfnAllocHook = _AfxDefaultAllocHook; - -AFX_STATIC_DATA _CRT_ALLOC_HOOK pfnCrtAllocHook = NULL; -#if _MSC_VER >= 1200 -int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize, - int nBlockUse, long lRequest, const unsigned char * szFilename, int nLine) -#else -int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize, - int nBlockUse, long lRequest, const char * szFilename, int nLine) -#endif -{ -#if _MSC_VER >= 1200 - if (nAllocType != _HOOK_ALLOC) - return (pfnCrtAllocHook)(nAllocType, pvData, nSize, - nBlockUse, lRequest, (const unsigned char*) szFilename, nLine); - if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest)) - return (pfnCrtAllocHook)(nAllocType, pvData, nSize, - nBlockUse, lRequest, (const unsigned char*) szFilename, nLine); -#else - if (nAllocType != _HOOK_ALLOC) - return (pfnCrtAllocHook)(nAllocType, pvData, nSize, - nBlockUse, lRequest, szFilename, nLine); - if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest)) - return (pfnCrtAllocHook)(nAllocType, pvData, nSize, - nBlockUse, lRequest, szFilename, nLine); -#endif - return FALSE; -} - -AFX_ALLOC_HOOK AFXAPI AfxSetAllocHook(AFX_ALLOC_HOOK pfnNewHook) -{ - if (pfnCrtAllocHook == NULL) - pfnCrtAllocHook = _CrtSetAllocHook(_AfxAllocHookProxy); - - AFX_ALLOC_HOOK pfnOldHook = pfnAllocHook; - pfnAllocHook = pfnNewHook; - return pfnOldHook; -} - -// This can be set to TRUE to override all AfxEnableMemoryTracking calls, -// allowing all allocations, even MFC internal allocations to be tracked. -BOOL _afxMemoryLeakOverride = FALSE; - -BOOL AFXAPI AfxEnableMemoryTracking(BOOL bTrack) -{ - if (_afxMemoryLeakOverride) - return TRUE; - - int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - if (bTrack) - _CrtSetDbgFlag(nOldState | _CRTDBG_ALLOC_MEM_DF); - else - _CrtSetDbgFlag(nOldState & ~_CRTDBG_ALLOC_MEM_DF); - return nOldState & _CRTDBG_ALLOC_MEM_DF; -} - -///////////////////////////////////////////////////////////////////////////// -// stop on a specific memory request - -// Obsolete API -void AFXAPI AfxSetAllocStop(LONG lRequestNumber) -{ - _CrtSetBreakAlloc(lRequestNumber); -} - -BOOL AFXAPI AfxCheckMemory() - // check all of memory (look for memory tromps) -{ - return _CrtCheckMemory(); -} - -// -- true if block of exact size, allocated on the heap -// -- set *plRequestNumber to request number (or 0) -BOOL AFXAPI AfxIsMemoryBlock(const void* pData, UINT nBytes, - LONG* plRequestNumber) -{ - return _CrtIsMemoryBlock(pData, nBytes, plRequestNumber, NULL, NULL); -} - -///////////////////////////////////////////////////////////////////////////// -// CMemoryState - -CMemoryState::CMemoryState() -{ - memset(this, 0, sizeof(*this)); -} - -void CMemoryState::UpdateData() -{ - for(int i = 0; i < nBlockUseMax; i++) - { - m_lCounts[i] = m_memState.lCounts[i]; - m_lSizes[i] = m_memState.lSizes[i]; - } - m_lHighWaterCount = m_memState.lHighWaterCount; - m_lTotalCount = m_memState.lTotalCount; -} - -// fills 'this' with the difference, returns TRUE if significant -BOOL CMemoryState::Difference(const CMemoryState& oldState, - const CMemoryState& newState) -{ - int nResult = _CrtMemDifference(&m_memState, &oldState.m_memState, &newState.m_memState); - UpdateData(); - return nResult != 0; -} - -void CMemoryState::DumpStatistics() const -{ - _CrtMemDumpStatistics(&m_memState); -} - -// -- fill with current memory state -void CMemoryState::Checkpoint() -{ - _CrtMemCheckpoint(&m_memState); - UpdateData(); -} - -// Dump objects created after this memory state was checkpointed -// Will dump all objects if this memory state wasn't checkpointed -// Dump all objects, report about non-objects also -// List request number in {} -void CMemoryState::DumpAllObjectsSince() const -{ - _CrtMemDumpAllObjectsSince(&m_memState); -} - -///////////////////////////////////////////////////////////////////////////// -// Enumerate all objects allocated in the diagnostic memory heap - -struct _AFX_ENUM_CONTEXT -{ - void (*m_pfn)(CObject*,void*); - void* m_pContext; -}; - -AFX_STATIC void _AfxDoForAllObjectsProxy(void* pObject, void* pContext) -{ - _AFX_ENUM_CONTEXT* p = (_AFX_ENUM_CONTEXT*)pContext; - (*p->m_pfn)((CObject*)pObject, p->m_pContext); -} - -void AFXAPI -AfxDoForAllObjects(void (AFX_CDECL *pfn)(CObject*, void*), void* pContext) -{ - if (pfn == NULL) - { - AfxThrowInvalidArgException(); - } - _AFX_ENUM_CONTEXT context; - context.m_pfn = pfn; - context.m_pContext = pContext; - _CrtDoForAllClientObjects(_AfxDoForAllObjectsProxy, &context); -} - -///////////////////////////////////////////////////////////////////////////// -// Automatic debug memory diagnostics - -BOOL AFXAPI AfxDumpMemoryLeaks() -{ - return _CrtDumpMemoryLeaks(); -} - -#endif // _AFX_NO_DEBUG_CRT -#endif // _DEBUG - -///////////////////////////////////////////////////////////////////////////// -// Non-diagnostic memory routines - -int AFX_CDECL AfxNewHandler(size_t /* nSize */) -{ - AfxThrowMemoryException(); -} - -#pragma warning(disable: 4273) - -#ifndef _AFXDLL -_PNH _afxNewHandler = &AfxNewHandler; -#endif - -_PNH AFXAPI AfxGetNewHandler(void) -{ -#ifdef _AFXDLL - AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); - return pState->m_pfnNewHandler; -#else - return _afxNewHandler; -#endif -} - -_PNH AFXAPI AfxSetNewHandler(_PNH pfnNewHandler) -{ -#ifdef _AFXDLL - AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); - _PNH pfnOldHandler = pState->m_pfnNewHandler; - pState->m_pfnNewHandler = pfnNewHandler; - return pfnOldHandler; -#else - _PNH pfnOldHandler = _afxNewHandler; - _afxNewHandler = pfnNewHandler; - return pfnOldHandler; -#endif -} - -AFX_STATIC_DATA const _PNH _pfnUninitialized = (_PNH)-1; - -void* __cdecl operator new(size_t nSize) -{ - void* pResult; -#ifdef _AFXDLL - _PNH pfnNewHandler = _pfnUninitialized; -#endif - for (;;) - { -#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG) - pResult = _malloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0); -#else - pResult = malloc(nSize); -#endif - if (pResult != NULL) - return pResult; - -#ifdef _AFXDLL - if (pfnNewHandler == _pfnUninitialized) - { - AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); - pfnNewHandler = pState->m_pfnNewHandler; - } - if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0) - break; -#else - if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0) - break; -#endif - } - return pResult; -} - -void __cdecl operator delete(void* p) -{ -#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG) - _free_dbg(p, _NORMAL_BLOCK); -#else - free(p); -#endif -} - -#if _MSC_VER >= 1210 -void* __cdecl operator new[](size_t nSize) -{ - return ::operator new(nSize); -} - -void __cdecl operator delete[](void* p) -{ - ::operator delete(p); -} -#endif - -#ifdef _DEBUG - -void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine) -{ -#ifdef _AFX_NO_DEBUG_CRT - UNUSED_ALWAYS(nType); - UNUSED_ALWAYS(lpszFileName); - UNUSED_ALWAYS(nLine); - return ::operator new(nSize); -#else - void* pResult; -#ifdef _AFXDLL - _PNH pfnNewHandler = _pfnUninitialized; -#endif - for (;;) - { - pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine); - if (pResult != NULL) - return pResult; - -#ifdef _AFXDLL - if (pfnNewHandler == _pfnUninitialized) - { - AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); - pfnNewHandler = pState->m_pfnNewHandler; - } - if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0) - break; -#else - if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0) - break; -#endif - } - return pResult; -#endif -} - -#if 0 -#if _MSC_VER >= 1200 -void __cdecl operator delete(void* p, int nType, LPCSTR /* lpszFileName */, int /* nLine */) -{ -#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG) - _free_dbg(p, nType); -#else - free(p); -#endif -} -#endif // _MSC_VER >= 1200 -#endif - -#if _MSC_VER >= 1210 -void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine) -{ - return ::operator new(nSize, nType, lpszFileName, nLine); -} -#if 0 -void __cdecl operator delete[](void* p, int nType, LPCSTR lpszFileName, int nLine) -{ - ::operator delete(p, nType, lpszFileName, nLine); -} -#endif -#endif // _MSC_VER >= 1210 - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// diff --git a/Resources/NetHook/tier0/basetypes.h b/Resources/NetHook/tier0/basetypes.h deleted file mode 100644 index 541b69d7..00000000 --- a/Resources/NetHook/tier0/basetypes.h +++ /dev/null @@ -1,372 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef BASETYPES_H -#define BASETYPES_H - -#include "commonmacros.h" -#include "wchartypes.h" - -#include "tier0/valve_off.h" - -#ifdef _WIN32 -#pragma once -#endif - - -#include "protected_things.h" - -// There's a different version of this file in the xbox codeline -// so the PC version built in the xbox branch includes things like -// tickrate changes. -#include "xbox_codeline_defines.h" - -#ifdef IN_XBOX_CODELINE -#define XBOX_CODELINE_ONLY() -#else -#define XBOX_CODELINE_ONLY() Error_Compiling_Code_Only_Valid_in_Xbox_Codeline -#endif - -// stdio.h -#ifndef NULL -#define NULL 0 -#endif - - -#ifdef _LINUX -typedef unsigned int uintptr_t; -#endif - -#define ExecuteNTimes( nTimes, x ) \ - { \ - static int __executeCount=0;\ - if ( __executeCount < nTimes )\ - { \ - x; \ - ++__executeCount; \ - } \ - } - - -#define ExecuteOnce( x ) ExecuteNTimes( 1, x ) - - -template -inline T AlignValue( T val, unsigned alignment ) -{ - return (T)( ( (uintptr_t)val + alignment - 1 ) & ~( alignment - 1 ) ); -} - - -// Pad a number so it lies on an N byte boundary. -// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4 -#define PAD_NUMBER(number, boundary) \ - ( ((number) + ((boundary)-1)) / (boundary) ) * (boundary) - -// In case this ever changes -#define M_PI 3.14159265358979323846 - -#include "valve_minmax_on.h" - -#if !defined(_X360) -#define fpmin min -#define fpmax max -#endif - -#ifdef __cplusplus - template< class T > - inline T clamp( T const &val, T const &minVal, T const &maxVal ) - { - if( val < minVal ) - return minVal; - else if( val > maxVal ) - return maxVal; - else - return val; - } -#endif - -#ifndef FALSE -#define FALSE 0 -#define TRUE (!FALSE) -#endif - - -typedef int BOOL; -typedef int qboolean; -typedef unsigned long ULONG; -typedef unsigned char BYTE; -typedef unsigned char byte; -typedef unsigned short word; - -typedef unsigned int uintptr_t; - - -enum ThreeState_t -{ - TRS_FALSE, - TRS_TRUE, - TRS_NONE, -}; - -typedef float vec_t; - - -// FIXME: this should move -#ifndef __cplusplus -#define true TRUE -#define false FALSE -#endif - -//----------------------------------------------------------------------------- -// look for NANs, infinities, and underflows. -// This assumes the ANSI/IEEE 754-1985 standard -//----------------------------------------------------------------------------- - -#ifdef __cplusplus - -inline unsigned long& FloatBits( vec_t& f ) -{ - return *reinterpret_cast(&f); -} - -inline unsigned long const& FloatBits( vec_t const& f ) -{ - return *reinterpret_cast(&f); -} - -inline vec_t BitsToFloat( unsigned long i ) -{ - return *reinterpret_cast(&i); -} - -inline bool IsFinite( vec_t f ) -{ - return ((FloatBits(f) & 0x7F800000) != 0x7F800000); -} - -inline unsigned long FloatAbsBits( vec_t f ) -{ - return FloatBits(f) & 0x7FFFFFFF; -} - -inline float FloatMakeNegative( vec_t f ) -{ - return BitsToFloat( FloatBits(f) | 0x80000000 ); -} - -#if defined( WIN32 ) - -//#include -// Just use prototype from math.h -#ifdef __cplusplus -extern "C" -{ -#endif - double __cdecl fabs(double); -#ifdef __cplusplus -} -#endif - -// In win32 try to use the intrinsic fabs so the optimizer can do it's thing inline in the code -#pragma intrinsic( fabs ) -// Also, alias float make positive to use fabs, too -// NOTE: Is there a perf issue with double<->float conversion? -inline float FloatMakePositive( vec_t f ) -{ - return (float)fabs( f ); -} -#else -inline float FloatMakePositive( vec_t f ) -{ - return BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); -} -#endif - -inline float FloatNegate( vec_t f ) -{ - return BitsToFloat( FloatBits(f) ^ 0x80000000 ); -} - - -#define FLOAT32_NAN_BITS (unsigned long)0x7FC00000 // not a number! -#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS ) - -#define VEC_T_NAN FLOAT32_NAN - -#endif - -// FIXME: why are these here? Hardly anyone actually needs them. -struct color24 -{ - byte r, g, b; -}; - -typedef struct color32_s -{ - bool operator!=( const struct color32_s &other ) const; - - byte r, g, b, a; -} color32; - -inline bool color32::operator!=( const color32 &other ) const -{ - return r != other.r || g != other.g || b != other.b || a != other.a; -} - -struct colorVec -{ - unsigned r, g, b, a; -}; - - -#ifndef NOTE_UNUSED -#define NOTE_UNUSED(x) (x = x) // for pesky compiler / lint warnings -#endif -#ifdef __cplusplus - -struct vrect_t -{ - int x,y,width,height; - vrect_t *pnext; -}; - -#endif - - -//----------------------------------------------------------------------------- -// MaterialRect_t struct - used for DrawDebugText -//----------------------------------------------------------------------------- -struct Rect_t -{ - int x, y; - int width, height; -}; - - -//----------------------------------------------------------------------------- -// Interval, used by soundemittersystem + the game -//----------------------------------------------------------------------------- -struct interval_t -{ - float start; - float range; -}; - - -//----------------------------------------------------------------------------- -// Declares a type-safe handle type; you can't assign one handle to the next -//----------------------------------------------------------------------------- - -// 32-bit pointer handles. - -// Typesafe 8-bit and 16-bit handles. -template< class HandleType > -class CBaseIntHandle -{ -public: - - inline bool operator==( const CBaseIntHandle &other ) { return m_Handle == other.m_Handle; } - inline bool operator!=( const CBaseIntHandle &other ) { return m_Handle != other.m_Handle; } - - // Only the code that doles out these handles should use these functions. - // Everyone else should treat them as a transparent type. - inline HandleType GetHandleValue() { return m_Handle; } - inline void SetHandleValue( HandleType val ) { m_Handle = val; } - - typedef HandleType HANDLE_TYPE; - -protected: - - HandleType m_Handle; -}; - -template< class DummyType > -class CIntHandle16 : public CBaseIntHandle< unsigned short > -{ -public: - inline CIntHandle16() {} - - static inline CIntHandle16 MakeHandle( HANDLE_TYPE val ) - { - return CIntHandle16( val ); - } - -protected: - inline CIntHandle16( HANDLE_TYPE val ) - { - m_Handle = val; - } -}; - - -template< class DummyType > -class CIntHandle32 : public CBaseIntHandle< unsigned long > -{ -public: - inline CIntHandle32() {} - - static inline CIntHandle32 MakeHandle( HANDLE_TYPE val ) - { - return CIntHandle32( val ); - } - -protected: - inline CIntHandle32( HANDLE_TYPE val ) - { - m_Handle = val; - } -}; - - -// NOTE: This macro is the same as windows uses; so don't change the guts of it -#define DECLARE_HANDLE_16BIT(name) typedef CIntHandle16< struct name##__handle * > name; -#define DECLARE_HANDLE_32BIT(name) typedef CIntHandle32< struct name##__handle * > name; - -#define DECLARE_POINTER_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name -#define FORWARD_DECLARE_HANDLE(name) typedef struct name##__ *name - -// @TODO: Find a better home for this -#if !defined(_STATIC_LINKED) && !defined(PUBLISH_DLL_SUBSYSTEM) -// for platforms built with dynamic linking, the dll interface does not need spoofing -#define PUBLISH_DLL_SUBSYSTEM() -#endif - -#define UID_PREFIX generated_id_ -#define UID_CAT1(a,c) a ## c -#define UID_CAT2(a,c) UID_CAT1(a,c) -#define EXPAND_CONCAT(a,c) UID_CAT1(a,c) -#ifdef _MSC_VER -#define UNIQUE_ID UID_CAT2(UID_PREFIX,__COUNTER__) -#else -#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__) -#endif - -// this allows enumerations to be used as flags, and still remain type-safe! -#define DEFINE_ENUM_BITWISE_OPERATORS( Type ) \ - inline Type operator| ( Type a, Type b ) { return Type( int( a ) | int( b ) ); } \ - inline Type operator& ( Type a, Type b ) { return Type( int( a ) & int( b ) ); } \ - inline Type operator^ ( Type a, Type b ) { return Type( int( a ) ^ int( b ) ); } \ - inline Type operator<< ( Type a, int b ) { return Type( int( a ) << b ); } \ - inline Type operator>> ( Type a, int b ) { return Type( int( a ) >> b ); } \ - inline Type &operator|= ( Type &a, Type b ) { return a = a | b; } \ - inline Type &operator&= ( Type &a, Type b ) { return a = a & b; } \ - inline Type &operator^= ( Type &a, Type b ) { return a = a ^ b; } \ - inline Type &operator<<=( Type &a, int b ) { return a = a << b; } \ - inline Type &operator>>=( Type &a, int b ) { return a = a >> b; } \ - inline Type operator~( Type a ) { return Type( ~int( a ) ); } - -// defines increment/decrement operators for enums for easy iteration -#define DEFINE_ENUM_INCREMENT_OPERATORS( Type ) \ - inline Type &operator++( Type &a ) { return a = Type( int( a ) + 1 ); } \ - inline Type &operator--( Type &a ) { return a = Type( int( a ) - 1 ); } \ - inline Type operator++( Type &a, int ) { Type t = a; ++a; return t; } \ - inline Type operator--( Type &a, int ) { Type t = a; --a; return t; } - -#include "tier0/valve_on.h" - -#endif // BASETYPES_H diff --git a/Resources/NetHook/tier0/commonmacros.h b/Resources/NetHook/tier0/commonmacros.h deleted file mode 100644 index e8813f8f..00000000 --- a/Resources/NetHook/tier0/commonmacros.h +++ /dev/null @@ -1,144 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMONMACROS_H -#define COMMONMACROS_H - -#ifdef _WIN32 -#pragma once -#endif - -// ------------------------------------------------------- -// -// commonmacros.h -// -// This should contain ONLY general purpose macros that are -// appropriate for use in engine/launcher/all tools -// -// ------------------------------------------------------- - -// Makes a 4-byte "packed ID" int out of 4 characters -#define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) ) - -// Compares a string with a 4-byte packed ID constant -#define STRING_MATCHES_ID( p, id ) ( (*((int *)(p)) == (id) ) ? true : false ) -#define ID_TO_STRING( id, p ) ( (p)[3] = (((id)>>24) & 0xFF), (p)[2] = (((id)>>16) & 0xFF), (p)[1] = (((id)>>8) & 0xFF), (p)[0] = (((id)>>0) & 0xFF) ) - -#define Q_ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) - -#define SETBITS(iBitVector, bits) ((iBitVector) |= (bits)) -#define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits)) -#define FBitSet(iBitVector, bit) ((iBitVector) & (bit)) - -inline bool IsPowerOfTwo( int value ) -{ - return (value & ( value - 1 )) == 0; -} - -#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it -#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__" -#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form - -// Using ARRAYSIZE implementation from winnt.h: -#ifdef ARRAYSIZE -#undef ARRAYSIZE -#endif - -// Return the number of elements in a statically sized array. -// DWORD Buffer[100]; -// RTL_NUMBER_OF(Buffer) == 100 -// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc. -// -#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0])) - -#if defined(__cplusplus) && \ - !defined(MIDL_PASS) && \ - !defined(RC_INVOKED) && \ - !defined(_PREFAST_) && \ - (_MSC_FULL_VER >= 13009466) && \ - !defined(SORTPP_PASS) - -// From crtdefs.h -#if !defined(UNALIGNED) -#if defined(_M_IA64) || defined(_M_AMD64) -#define UNALIGNED __unaligned -#else -#define UNALIGNED -#endif -#endif - -// RtlpNumberOf is a function that takes a reference to an array of N Ts. -// -// typedef T array_of_T[N]; -// typedef array_of_T &reference_to_array_of_T; -// -// RtlpNumberOf returns a pointer to an array of N chars. -// We could return a reference instead of a pointer but older compilers do not accept that. -// -// typedef char array_of_char[N]; -// typedef array_of_char *pointer_to_array_of_char; -// -// sizeof(array_of_char) == N -// sizeof(*pointer_to_array_of_char) == N -// -// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T); -// -// We never even call RtlpNumberOf, we just take the size of dereferencing its return type. -// We do not even implement RtlpNumberOf, we just decare it. -// -// Attempts to pass pointers instead of arrays to this macro result in compile time errors. -// That is the point. -extern "C++" // templates cannot be declared to have 'C' linkage -template -char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; - -#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))) - -// This does not work with: -// -// void Foo() -// { -// struct { int x; } y[2]; -// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation -// } -// -// You must instead do: -// -// struct Foo1 { int x; }; -// -// void Foo() -// { -// Foo1 y[2]; -// RTL_NUMBER_OF_V2(y); // ok -// } -// -// OR -// -// void Foo() -// { -// struct { int x; } y[2]; -// RTL_NUMBER_OF_V1(y); // ok -// } -// -// OR -// -// void Foo() -// { -// struct { int x; } y[2]; -// _ARRAYSIZE(y); // ok -// } - -#else -#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A) -#endif - -// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2 -// _ARRAYSIZE is a version useful for anonymous types -#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) -#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) - -#endif // COMMONMACROS_H \ No newline at end of file diff --git a/Resources/NetHook/tier0/dbg.h b/Resources/NetHook/tier0/dbg.h deleted file mode 100644 index 66f29a0a..00000000 --- a/Resources/NetHook/tier0/dbg.h +++ /dev/null @@ -1,714 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ========// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef DBG_H -#define DBG_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "basetypes.h" -#include "dbgflag.h" -#include "platform.h" -#include -#include -#include - -#ifdef _LINUX -#define __cdecl -#endif - -//----------------------------------------------------------------------------- -// dll export stuff -//----------------------------------------------------------------------------- -#ifndef STATIC_TIER0 - -#ifdef TIER0_DLL_EXPORT -#define DBG_INTERFACE DLL_EXPORT -#define DBG_OVERLOAD DLL_GLOBAL_EXPORT -#define DBG_CLASS DLL_CLASS_EXPORT -#else -#define DBG_INTERFACE DLL_IMPORT -#define DBG_OVERLOAD DLL_GLOBAL_IMPORT -#define DBG_CLASS DLL_CLASS_IMPORT -#endif - -#else // BUILD_AS_DLL - -#define DBG_INTERFACE extern -#define DBG_OVERLOAD -#define DBG_CLASS -#endif // BUILD_AS_DLL - - -class Color; - - -//----------------------------------------------------------------------------- -// Usage model for the Dbg library -// -// 1. Spew. -// -// Spew can be used in a static and a dynamic mode. The static -// mode allows us to display assertions and other messages either only -// in debug builds, or in non-release builds. The dynamic mode allows us to -// turn on and off certain spew messages while the application is running. -// -// Static Spew messages: -// -// Assertions are used to detect and warn about invalid states -// Spews are used to display a particular status/warning message. -// -// To use an assertion, use -// -// Assert( (f == 5) ); -// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) ); -// AssertFunc( (f == 5), BadFunc() ); -// AssertEquals( f, 5 ); -// AssertFloatEquals( f, 5.0f, 1e-3 ); -// -// The first will simply report that an assertion failed on a particular -// code file and line. The second version will display a print-f formatted message -// along with the file and line, the third will display a generic message and -// will also cause the function BadFunc to be executed, and the last two -// will report an error if f is not equal to 5 (the last one asserts within -// a particular tolerance). -// -// To use a warning, use -// -// Warning("Oh I feel so %s all over\n", "yummy"); -// -// Warning will do its magic in only Debug builds. To perform spew in *all* -// builds, use RelWarning. -// -// Three other spew types, Msg, Log, and Error, are compiled into all builds. -// These error types do *not* need two sets of parenthesis. -// -// Msg( "Isn't this exciting %d?", 5 ); -// Error( "I'm just thrilled" ); -// -// Dynamic Spew messages -// -// It is possible to dynamically turn spew on and off. Dynamic spew is -// identified by a spew group and priority level. To turn spew on for a -// particular spew group, use SpewActivate( "group", level ). This will -// cause all spew in that particular group with priority levels <= the -// level specified in the SpewActivate function to be printed. Use DSpew -// to perform the spew: -// -// DWarning( "group", level, "Oh I feel even yummier!\n" ); -// -// Priority level 0 means that the spew will *always* be printed, and group -// '*' is the default spew group. If a DWarning is encountered using a group -// whose priority has not been set, it will use the priority of the default -// group. The priority of the default group is initially set to 0. -// -// Spew output -// -// The output of the spew system can be redirected to an externally-supplied -// function which is responsible for outputting the spew. By default, the -// spew is simply printed using printf. -// -// To redirect spew output, call SpewOutput. -// -// SpewOutputFunc( OutputFunc ); -// -// This will cause OutputFunc to be called every time a spew message is -// generated. OutputFunc will be passed a spew type and a message to print. -// It must return a value indicating whether the debugger should be invoked, -// whether the program should continue running, or whether the program -// should abort. -// -// 2. Code activation -// -// To cause code to be run only in debug builds, use DBG_CODE: -// An example is below. -// -// DBG_CODE( -// { -// int x = 5; -// ++x; -// } -// ); -// -// Code can be activated based on the dynamic spew groups also. Use -// -// DBG_DCODE( "group", level, -// { int x = 5; ++x; } -// ); -// -// 3. Breaking into the debugger. -// -// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK -// -// DBG_BREAK(); -// -// You can force a break in any build (release or debug) using -// -// DebuggerBreak(); -//----------------------------------------------------------------------------- - -/* Various types of spew messages */ -// I'm sure you're asking yourself why SPEW_ instead of DBG_ ? -// It's because DBG_ is used all over the place in windows.h -// For example, DBG_CONTINUE is defined. Feh. -enum SpewType_t -{ - SPEW_MESSAGE = 0, - SPEW_WARNING, - SPEW_ASSERT, - SPEW_ERROR, - SPEW_LOG, - - SPEW_TYPE_COUNT -}; - -enum SpewRetval_t -{ - SPEW_DEBUGGER = 0, - SPEW_CONTINUE, - SPEW_ABORT -}; - -/* type of externally defined function used to display debug spew */ -typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg ); - -/* Used to redirect spew output */ -DBG_INTERFACE void SpewOutputFunc( SpewOutputFunc_t func ); - -/* Used to get the current spew output function */ -DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void ); - -/* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */ -DBG_INTERFACE const tchar* GetSpewOutputGroup( void ); -DBG_INTERFACE int GetSpewOutputLevel( void ); -DBG_INTERFACE const Color& GetSpewOutputColor( void ); - -/* Used to manage spew groups and subgroups */ -DBG_INTERFACE void SpewActivate( const tchar* pGroupName, int level ); -DBG_INTERFACE bool IsSpewActive( const tchar* pGroupName, int level ); - -/* Used to display messages, should never be called directly. */ -DBG_INTERFACE void _SpewInfo( SpewType_t type, const tchar* pFile, int line ); -DBG_INTERFACE SpewRetval_t _SpewMessage( const tchar* pMsg, ... ); -DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, const tchar* pMsg, ... ); -DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, const tchar* pMsg, ... ); -DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line ); -DBG_INTERFACE bool ShouldUseNewAssertDialog(); - -DBG_INTERFACE bool SetupWin32ConsoleIO(); - -// Returns true if they want to break in the debugger. -DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression ); - -/* Used to define macros, never use these directly. */ - -#define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \ - do { \ - if (!(_exp)) \ - { \ - _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \ - SpewRetval_t ret = _SpewMessage("%s", _msg); \ - _executeExp; \ - if ( ret == SPEW_DEBUGGER) \ - { \ - if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \ - DebuggerBreak(); \ - if ( _bFatal ) \ - _ExitOnFatalAssert( __TFILE__, __LINE__ ); \ - } \ - } \ - } while (0) - -#define _AssertMsgOnce( _exp, _msg, _bFatal ) \ - do { \ - static bool fAsserted; \ - if (!fAsserted ) \ - { \ - _AssertMsg( _exp, _msg, (fAsserted = true), _bFatal ); \ - } \ - } while (0) - -/* Spew macros... */ - -// AssertFatal macros -// AssertFatal is used to detect an unrecoverable error condition. -// If enabled, it may display an assert dialog (if DBGFLAG_ASSERTDLG is turned on or running under the debugger), -// and always terminates the application - -#ifdef DBGFLAG_ASSERTFATAL - -#define AssertFatal( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true ) -#define AssertFatalOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true ) -#define AssertFatalMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), true ) -#define AssertFatalMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, true ) -#define AssertFatalFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true ) -#define AssertFatalEquals( _exp, _expectedValue ) AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) ) -#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) AssertFatalMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) ) -#define VerifyFatal( _exp ) AssertFatal( _exp ) -#define VerifyEqualsFatal( _exp, _expectedValue ) AssertFatalEquals( _exp, _expectedValue ) - -#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 ))) -#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 ))) -#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 ))) -#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 ))) -#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 ))) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ))) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ))) -#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 ))) -#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 ))) -#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ))) - -#else // DBGFLAG_ASSERTFATAL - -#define AssertFatal( _exp ) ((void)0) -#define AssertFatalOnce( _exp ) ((void)0) -#define AssertFatalMsg( _exp, _msg ) ((void)0) -#define AssertFatalMsgOnce( _exp, _msg ) ((void)0) -#define AssertFatalFunc( _exp, _f ) ((void)0) -#define AssertFatalEquals( _exp, _expectedValue ) ((void)0) -#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) ((void)0) -#define VerifyFatal( _exp ) (_exp) -#define VerifyEqualsFatal( _exp, _expectedValue ) (_exp) - -#define AssertFatalMsg1( _exp, _msg, a1 ) ((void)0) -#define AssertFatalMsg2( _exp, _msg, a1, a2 ) ((void)0) -#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) ((void)0) -#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0) -#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) -#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) -#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0) -#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0) -#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0) - -#endif // DBGFLAG_ASSERTFATAL - -// Assert macros -// Assert is used to detect an important but survivable error. -// It's only turned on when DBGFLAG_ASSERT is true. - -#ifdef DBGFLAG_ASSERT - -#define Assert( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false ) -#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false ) -#define AssertOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false ) -#define AssertMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, false ) -#define AssertFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false ) -#define AssertEquals( _exp, _expectedValue ) AssertMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) ) -#define AssertFloatEquals( _exp, _expectedValue, _tol ) AssertMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) ) -#define Verify( _exp ) Assert( _exp ) -#define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue ) - -#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) ) -#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) ) -#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) ) -#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) ) -#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) ) -#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) ) -#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )) ) -#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )) ) -#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )) ) - -#else // DBGFLAG_ASSERT - -#define Assert( _exp ) ((void)0) -#define AssertOnce( _exp ) ((void)0) -#define AssertMsg( _exp, _msg ) ((void)0) -#define AssertMsgOnce( _exp, _msg ) ((void)0) -#define AssertFunc( _exp, _f ) ((void)0) -#define AssertEquals( _exp, _expectedValue ) ((void)0) -#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0) -#define Verify( _exp ) (_exp) -#define VerifyEquals( _exp, _expectedValue ) (_exp) - -#define AssertMsg1( _exp, _msg, a1 ) ((void)0) -#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0) -#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0) -#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0) -#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0) -#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) -#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0) -#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0) -#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0) -#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0) - -#endif // DBGFLAG_ASSERT - - -#if !defined( _X360 ) || !defined( _RETAIL ) - -/* These are always compiled in */ -DBG_INTERFACE void Msg( const tchar* pMsg, ... ); -DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, const tchar *pMsg, ... ); - -DBG_INTERFACE void Warning( const tchar *pMsg, ... ); -DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, const tchar *pMsg, ... ); - -DBG_INTERFACE void Log( const tchar *pMsg, ... ); -DBG_INTERFACE void DLog( const tchar *pGroupName, int level, const tchar *pMsg, ... ); - -DBG_INTERFACE void Error( const tchar *pMsg, ... ); - -#else - -inline void Msg( ... ) {} -inline void DMsg( ... ) {} -inline void Warning( const tchar *pMsg, ... ) {} -inline void DWarning( ... ) {} -inline void Log( ... ) {} -inline void DLog( ... ) {} -inline void Error( ... ) {} - -#endif - -// You can use this macro like a runtime assert macro. -// If the condition fails, then Error is called with the message. This macro is called -// like AssertMsg, where msg must be enclosed in parenthesis: -// -// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) ); -#define ErrorIfNot( condition, msg ) \ - if ( (condition) ) \ - ; \ - else \ - { \ - Error msg; \ - } - -#if !defined( _X360 ) || !defined( _RETAIL ) - -/* A couple of super-common dynamic spew messages, here for convenience */ -/* These looked at the "developer" group */ -DBG_INTERFACE void DevMsg( int level, const tchar* pMsg, ... ); -DBG_INTERFACE void DevWarning( int level, const tchar *pMsg, ... ); -DBG_INTERFACE void DevLog( int level, const tchar *pMsg, ... ); - -/* default level versions (level 1) */ -DBG_OVERLOAD void DevMsg( const tchar* pMsg, ... ); -DBG_OVERLOAD void DevWarning( const tchar *pMsg, ... ); -DBG_OVERLOAD void DevLog( const tchar *pMsg, ... ); - -/* These looked at the "console" group */ -DBG_INTERFACE void ConColorMsg( int level, const Color& clr, const tchar* pMsg, ... ); -DBG_INTERFACE void ConMsg( int level, const tchar* pMsg, ... ); -DBG_INTERFACE void ConWarning( int level, const tchar *pMsg, ... ); -DBG_INTERFACE void ConLog( int level, const tchar *pMsg, ... ); - -/* default console version (level 1) */ -DBG_OVERLOAD void ConColorMsg( const Color& clr, const tchar* pMsg, ... ); -DBG_OVERLOAD void ConMsg( const tchar* pMsg, ... ); -DBG_OVERLOAD void ConWarning( const tchar *pMsg, ... ); -DBG_OVERLOAD void ConLog( const tchar *pMsg, ... ); - -/* developer console version (level 2) */ -DBG_INTERFACE void ConDColorMsg( const Color& clr, const tchar* pMsg, ... ); -DBG_INTERFACE void ConDMsg( const tchar* pMsg, ... ); -DBG_INTERFACE void ConDWarning( const tchar *pMsg, ... ); -DBG_INTERFACE void ConDLog( const tchar *pMsg, ... ); - -/* These looked at the "network" group */ -DBG_INTERFACE void NetMsg( int level, const tchar* pMsg, ... ); -DBG_INTERFACE void NetWarning( int level, const tchar *pMsg, ... ); -DBG_INTERFACE void NetLog( int level, const tchar *pMsg, ... ); - -void ValidateSpew( class CValidator &validator ); - -#else - -inline void DevMsg( ... ) {} -inline void DevWarning( ... ) {} -inline void DevLog( ... ) {} -inline void ConMsg( ... ) {} -inline void ConLog( ... ) {} -inline void NetMsg( ... ) {} -inline void NetWarning( ... ) {} -inline void NetLog( ... ) {} - -#endif - -DBG_INTERFACE void COM_TimestampedLog( char const *fmt, ... ); - -/* Code macros, debugger interface */ - -#ifdef _DEBUG - -#define DBG_CODE( _code ) if (0) ; else { _code } -#define DBG_CODE_NOSCOPE( _code ) _code -#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {} -#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */ - -#else /* not _DEBUG */ - -#define DBG_CODE( _code ) ((void)0) -#define DBG_CODE_NOSCOPE( _code ) -#define DBG_DCODE( _g, _l, _code ) ((void)0) -#define DBG_BREAK() ((void)0) - -#endif /* _DEBUG */ - -//----------------------------------------------------------------------------- - -#ifndef _RETAIL -class CScopeMsg -{ -public: - CScopeMsg( const char *pszScope ) - { - m_pszScope = pszScope; - Msg( "%s { ", pszScope ); - } - ~CScopeMsg() - { - Msg( "} %s", m_pszScope ); - } - const char *m_pszScope; -}; -#define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg ) -#else -#define SCOPE_MSG( msg ) -#endif - - -//----------------------------------------------------------------------------- -// Macro to assist in asserting constant invariants during compilation - -#ifdef _DEBUG -#define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;} -#define ASSERT_INVARIANT( pred ) static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) } -#else -#define COMPILE_TIME_ASSERT( pred ) -#define ASSERT_INVARIANT( pred ) -#endif - -#ifdef _DEBUG -template -inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource) -{ - Assert( static_cast(pSource) == dynamic_cast(pSource) ); - return static_cast(pSource); -} -#else -#define assert_cast static_cast -#endif - -//----------------------------------------------------------------------------- -// Templates to assist in validating pointers: - -// Have to use these stubs so we don't have to include windows.h here. -DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 ); -DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 ); -DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 ); - -DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF ); -template inline void AssertValidReadPtr( T* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); } -template inline void AssertValidWritePtr( T* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); } -template inline void AssertValidReadWritePtr( T* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); } - -#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this)) - -//----------------------------------------------------------------------------- -// Macro to protect functions that are not reentrant - -#ifdef _DEBUG -class CReentryGuard -{ -public: - CReentryGuard(int *pSemaphore) - : m_pSemaphore(pSemaphore) - { - ++(*m_pSemaphore); - } - - ~CReentryGuard() - { - --(*m_pSemaphore); - } - -private: - int *m_pSemaphore; -}; - -#define ASSERT_NO_REENTRY() \ - static int fSemaphore##__LINE__; \ - Assert( !fSemaphore##__LINE__ ); \ - CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ ) -#else -#define ASSERT_NO_REENTRY() -#endif - -//----------------------------------------------------------------------------- -// -// Purpose: Inline string formatter -// - -#include "tier0/valve_off.h" -class CDbgFmtMsg -{ -public: - CDbgFmtMsg(const tchar *pszFormat, ...) - { - va_list arg_ptr; - - va_start(arg_ptr, pszFormat); - _vsntprintf(m_szBuf, sizeof(m_szBuf)-1, pszFormat, arg_ptr); - va_end(arg_ptr); - - m_szBuf[sizeof(m_szBuf)-1] = 0; - } - - operator const tchar *() const - { - return m_szBuf; - } - -private: - tchar m_szBuf[256]; -}; -#include "tier0/valve_on.h" - -//----------------------------------------------------------------------------- -// -// Purpose: Embed debug info in each file. -// -#if defined( _WIN32 ) && !defined( _X360 ) - - #ifdef _DEBUG - #pragma comment(compiler) - #endif - -#endif - -//----------------------------------------------------------------------------- -// -// Purpose: Wrap around a variable to create a simple place to put a breakpoint -// - -#ifdef _DEBUG - -template< class Type > -class CDataWatcher -{ -public: - const Type& operator=( const Type &val ) - { - return Set( val ); - } - - const Type& operator=( const CDataWatcher &val ) - { - return Set( val.m_Value ); - } - - const Type& Set( const Type &val ) - { - // Put your breakpoint here - m_Value = val; - return m_Value; - } - - Type& GetForModify() - { - return m_Value; - } - - const Type& operator+=( const Type &val ) - { - return Set( m_Value + val ); - } - - const Type& operator-=( const Type &val ) - { - return Set( m_Value - val ); - } - - const Type& operator/=( const Type &val ) - { - return Set( m_Value / val ); - } - - const Type& operator*=( const Type &val ) - { - return Set( m_Value * val ); - } - - const Type& operator^=( const Type &val ) - { - return Set( m_Value ^ val ); - } - - const Type& operator|=( const Type &val ) - { - return Set( m_Value | val ); - } - - const Type& operator++() - { - return (*this += 1); - } - - Type operator--() - { - return (*this -= 1); - } - - Type operator++( int ) // postfix version.. - { - Type val = m_Value; - (*this += 1); - return val; - } - - Type operator--( int ) // postfix version.. - { - Type val = m_Value; - (*this -= 1); - return val; - } - - // For some reason the compiler only generates type conversion warnings for this operator when used like - // CNetworkVarBase = 0x1 - // (it warns about converting from an int to an unsigned char). - template< class C > - const Type& operator&=( C val ) - { - return Set( m_Value & val ); - } - - operator const Type&() const - { - return m_Value; - } - - const Type& Get() const - { - return m_Value; - } - - const Type* operator->() const - { - return &m_Value; - } - - Type m_Value; - -}; - -#else - -template< class Type > -class CDataWatcher -{ -private: - CDataWatcher(); // refuse to compile in non-debug builds -}; - -#endif - -//----------------------------------------------------------------------------- - -#endif /* DBG_H */ diff --git a/Resources/NetHook/tier0/dbgflag.h b/Resources/NetHook/tier0/dbgflag.h deleted file mode 100644 index d34cfd46..00000000 --- a/Resources/NetHook/tier0/dbgflag.h +++ /dev/null @@ -1,65 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This file sets all of our debugging flags. It should be -// called before all other header files. -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef DBGFLAG_H -#define DBGFLAG_H -#ifdef _WIN32 -#pragma once -#endif - - -// Here are all the flags we support: -// DBGFLAG_MEMORY: Enables our memory debugging system, which overrides malloc & free -// DBGFLAG_MEMORY_NEWDEL: Enables new / delete tracking for memory debug system. Requires DBGFLAG_MEMORY to be enabled. -// DBGFLAG_VALIDATE: Enables our recursive validation system for checking integrity and memory leaks -// DBGFLAG_ASSERT: Turns Assert on or off (when off, it isn't compiled at all) -// DBGFLAG_ASSERTFATAL: Turns AssertFatal on or off (when off, it isn't compiled at all) -// DBGFLAG_ASSERTDLG: Turns assert dialogs on or off and debug breaks on or off when not under the debugger. -// (Dialogs will always be on when process is being debugged.) -// DBGFLAG_STRINGS: Turns on hardcore string validation (slow but safe) - -#undef DBGFLAG_MEMORY -#undef DBGFLAG_MEMORY_NEWDEL -#undef DBGFLAG_VALIDATE -#undef DBGFLAG_ASSERT -#undef DBGFLAG_ASSERTFATAL -#undef DBGFLAG_ASSERTDLG -#undef DBGFLAG_STRINGS - -//----------------------------------------------------------------------------- -// Default flags for debug builds -//----------------------------------------------------------------------------- -#ifdef _DEBUG - -#define DBGFLAG_MEMORY -#ifdef _SERVER // only enable new & delete tracking for server; on client it conflicts with CRT mem leak tracking -#define DBGFLAG_MEMORY_NEWDEL -#endif -#ifdef STEAM -#define DBGFLAG_VALIDATE -#endif -#define DBGFLAG_ASSERT -#define DBGFLAG_ASSERTFATAL -#define DBGFLAG_ASSERTDLG -#define DBGFLAG_STRINGS - - -//----------------------------------------------------------------------------- -// Default flags for release builds -//----------------------------------------------------------------------------- -#else // _DEBUG - -#ifdef STEAM -#define DBGFLAG_ASSERT -#endif -#define DBGFLAG_ASSERTFATAL // note: fatal asserts are enabled in release builds -#define DBGFLAG_ASSERTDLG - -#endif // _DEBUG - -#endif // DBGFLAG_H diff --git a/Resources/NetHook/tier0/fasttimer.h b/Resources/NetHook/tier0/fasttimer.h deleted file mode 100644 index 80b55b5a..00000000 --- a/Resources/NetHook/tier0/fasttimer.h +++ /dev/null @@ -1,591 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef FASTTIMER_H -#define FASTTIMER_H -#ifdef _WIN32 -#pragma once -#endif - -#include -#include "tier0/platform.h" - -PLATFORM_INTERFACE int64 g_ClockSpeed; -PLATFORM_INTERFACE unsigned long g_dwClockSpeed; -#if defined( _X360 ) && defined( _CERT ) -PLATFORM_INTERFACE unsigned long g_dwFakeFastCounter; -#endif - -PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier; -PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier; -PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier; - -class CCycleCount -{ -friend class CFastTimer; - -public: - CCycleCount(); - CCycleCount( int64 cycles ); - - void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900). - - void Init(); // Set to zero. - void Init( float initTimeMsec ); - void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); } - void Init( int64 cycles ); - bool IsLessThan( CCycleCount const &other ) const; // Compare two counts. - - // Convert to other time representations. These functions are slow, so it's preferable to call them - // during display rather than inside a timing block. - unsigned long GetCycles() const; - int64 GetLongCycles() const; - - unsigned long GetMicroseconds() const; - uint64 GetUlMicroseconds() const; - double GetMicrosecondsF() const; - void SetMicroseconds( unsigned long nMicroseconds ); - - unsigned long GetMilliseconds() const; - double GetMillisecondsF() const; - - double GetSeconds() const; - - CCycleCount& operator+=( CCycleCount const &other ); - - // dest = rSrc1 + rSrc2 - static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together. - - // dest = rSrc1 - rSrc2 - static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together. - - static int64 GetTimestamp(); - - int64 m_Int64; -}; - -class CClockSpeedInit -{ -public: - CClockSpeedInit() - { - Init(); - } - - static void Init() - { -#if defined( _X360 ) && !defined( _CERT ) - PMCStart(); - PMCInitIntervalTimer( 0 ); -#endif - const CPUInformation& pi = GetCPUInformation(); - - g_ClockSpeed = pi.m_Speed; - g_dwClockSpeed = (unsigned long)g_ClockSpeed; - - g_ClockSpeedMicrosecondsMultiplier = 1000000.0 / (double)g_ClockSpeed; - g_ClockSpeedMillisecondsMultiplier = 1000.0 / (double)g_ClockSpeed; - g_ClockSpeedSecondsMultiplier = 1.0f / (double)g_ClockSpeed; - } -}; - -class CFastTimer -{ -public: - // These functions are fast to call and should be called from your sampling code. - void Start(); - void End(); - - const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls. - CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap. - - // Return number of cycles per second on this processor. - static inline unsigned long GetClockSpeed(); - -private: - CCycleCount m_Duration; -#ifdef DEBUG_FASTTIMER - bool m_bRunning; // Are we currently running? -#endif -}; - - -// This is a helper class that times whatever block of code it's in -class CTimeScope -{ -public: - CTimeScope( CFastTimer *pTimer ); - ~CTimeScope(); - -private: - CFastTimer *m_pTimer; -}; - -inline CTimeScope::CTimeScope( CFastTimer *pTotal ) -{ - m_pTimer = pTotal; - m_pTimer->Start(); -} - -inline CTimeScope::~CTimeScope() -{ - m_pTimer->End(); -} - -// This is a helper class that times whatever block of code it's in and -// adds the total (int microseconds) to a global counter. -class CTimeAdder -{ -public: - CTimeAdder( CCycleCount *pTotal ); - ~CTimeAdder(); - - void End(); - -private: - CCycleCount *m_pTotal; - CFastTimer m_Timer; -}; - -inline CTimeAdder::CTimeAdder( CCycleCount *pTotal ) -{ - m_pTotal = pTotal; - m_Timer.Start(); -} - -inline CTimeAdder::~CTimeAdder() -{ - End(); -} - -inline void CTimeAdder::End() -{ - if( m_pTotal ) - { - m_Timer.End(); - *m_pTotal += m_Timer.GetDuration(); - m_pTotal = 0; - } -} - - - -// -------------------------------------------------------------------------- // -// Simple tool to support timing a block of code, and reporting the results on -// program exit or at each iteration -// -// Macros used because dbg.h uses this header, thus Msg() is unavailable -// -------------------------------------------------------------------------- // - -#define PROFILE_SCOPE(name) \ - class C##name##ACC : public CAverageCycleCounter \ - { \ - public: \ - ~C##name##ACC() \ - { \ - Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \ - #name, \ - GetAverageMilliseconds(), \ - GetTotalMilliseconds(), \ - GetPeakMilliseconds(), \ - GetIters() ); \ - } \ - }; \ - static C##name##ACC name##_ACC; \ - CAverageTimeMarker name##_ATM( &name##_ACC ) - -#define TIME_SCOPE(name) \ - class CTimeScopeMsg_##name \ - { \ - public: \ - CTimeScopeMsg_##name() { m_Timer.Start(); } \ - ~CTimeScopeMsg_##name() \ - { \ - m_Timer.End(); \ - Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \ - } \ - private: \ - CFastTimer m_Timer; \ - } name##_TSM; - - -// -------------------------------------------------------------------------- // - -class CAverageCycleCounter -{ -public: - CAverageCycleCounter(); - - void Init(); - void MarkIter( const CCycleCount &duration ); - - unsigned GetIters() const; - - double GetAverageMilliseconds() const; - double GetTotalMilliseconds() const; - double GetPeakMilliseconds() const; - -private: - unsigned m_nIters; - CCycleCount m_Total; - CCycleCount m_Peak; - bool m_fReport; - const tchar *m_pszName; -}; - -// -------------------------------------------------------------------------- // - -class CAverageTimeMarker -{ -public: - CAverageTimeMarker( CAverageCycleCounter *pCounter ); - ~CAverageTimeMarker(); - -private: - CAverageCycleCounter *m_pCounter; - CFastTimer m_Timer; -}; - - -// -------------------------------------------------------------------------- // -// CCycleCount inlines. -// -------------------------------------------------------------------------- // - -inline CCycleCount::CCycleCount() -{ - Init( (int64)0 ); -} - -inline CCycleCount::CCycleCount( int64 cycles ) -{ - Init( cycles ); -} - -inline void CCycleCount::Init() -{ - Init( (int64)0 ); -} - -inline void CCycleCount::Init( float initTimeMsec ) -{ - if ( g_ClockSpeedMillisecondsMultiplier > 0 ) - Init( (int64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) ); - else - Init( (int64)0 ); -} - -inline void CCycleCount::Init( int64 cycles ) -{ - m_Int64 = cycles; -} - -#pragma warning(push) -#pragma warning(disable : 4189) // warning C4189: local variable is initialized but not referenced - -inline void CCycleCount::Sample() -{ -#if defined( _X360 ) -#if !defined( _CERT ) - // read the highest resolution timer directly (ticks at native 3.2GHz), bypassing any calls into PMC - // can only resolve 32 bits, rollover is ~1.32 secs - // based on PMCGetIntervalTimer() from the April 2007 XDK - int64 temp; - __asm - { - lis r11,08FFFh - ld r11,011E0h(r11) - rldicl r11,r11,32,32 - // unforunate can't get the inline assembler to write directly into desired target - std r11,temp - } - m_Int64 = temp; -#else - m_Int64 = ++g_dwFakeFastCounter; -#endif -#elif defined( _WIN32 ) - unsigned long* pSample = (unsigned long *)&m_Int64; - __asm - { - // force the cpu to synchronize the instruction queue - // NJS: CPUID can really impact performance in tight loops. - //cpuid - //cpuid - //cpuid - mov ecx, pSample - rdtsc - mov [ecx], eax - mov [ecx+4], edx - } -#elif defined( _LINUX ) - unsigned long* pSample = (unsigned long *)&m_Int64; - __asm__ __volatile__ ( - "rdtsc\n\t" - "movl %%eax, (%0)\n\t" - "movl %%edx, 4(%0)\n\t" - : /* no output regs */ - : "D" (pSample) - : "%eax", "%edx" ); -#endif -} - -#pragma warning(pop) - - -inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other ) -{ - m_Int64 += other.m_Int64; - return *this; -} - - -inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ) -{ - dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64; -} - -inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ) -{ - dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64; -} - -inline int64 CCycleCount::GetTimestamp() -{ - CCycleCount c; - c.Sample(); - return c.GetLongCycles(); -} - -inline bool CCycleCount::IsLessThan(CCycleCount const &other) const -{ - return m_Int64 < other.m_Int64; -} - - -inline unsigned long CCycleCount::GetCycles() const -{ - return (unsigned long)m_Int64; -} - -inline int64 CCycleCount::GetLongCycles() const -{ - return m_Int64; -} - -inline unsigned long CCycleCount::GetMicroseconds() const -{ - return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed); -} - -inline uint64 CCycleCount::GetUlMicroseconds() const -{ - return ((m_Int64 * 1000000) / g_ClockSpeed); -} - - -inline double CCycleCount::GetMicrosecondsF() const -{ - return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier ); -} - - -inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds ) -{ - m_Int64 = ((int64)nMicroseconds * g_ClockSpeed) / 1000000; -} - - -inline unsigned long CCycleCount::GetMilliseconds() const -{ - return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed); -} - - -inline double CCycleCount::GetMillisecondsF() const -{ - return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier ); -} - - -inline double CCycleCount::GetSeconds() const -{ - return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier ); -} - - -// -------------------------------------------------------------------------- // -// CFastTimer inlines. -// -------------------------------------------------------------------------- // -inline void CFastTimer::Start() -{ - m_Duration.Sample(); -#ifdef DEBUG_FASTTIMER - m_bRunning = true; -#endif -} - - -inline void CFastTimer::End() -{ - CCycleCount cnt; - cnt.Sample(); - if ( IsX360() ) - { - // have to handle rollover, hires timer is only accurate to 32 bits - // more than one overflow should not have occured, otherwise caller should use a slower timer - if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 ) - { - // rollover occured - cnt.m_Int64 += 0x100000000LL; - } - } - - m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64; - -#ifdef DEBUG_FASTTIMER - m_bRunning = false; -#endif -} - -inline CCycleCount CFastTimer::GetDurationInProgress() const -{ - CCycleCount cnt; - cnt.Sample(); - if ( IsX360() ) - { - // have to handle rollover, hires timer is only accurate to 32 bits - // more than one overflow should not have occured, otherwise caller should use a slower timer - if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 ) - { - // rollover occured - cnt.m_Int64 += 0x100000000LL; - } - } - - CCycleCount result; - result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64; - - return result; -} - - -inline unsigned long CFastTimer::GetClockSpeed() -{ - return g_dwClockSpeed; -} - - -inline CCycleCount const& CFastTimer::GetDuration() const -{ -#ifdef DEBUG_FASTTIMER - assert( !m_bRunning ); -#endif - return m_Duration; -} - - -// -------------------------------------------------------------------------- // -// CAverageCycleCounter inlines - -inline CAverageCycleCounter::CAverageCycleCounter() - : m_nIters( 0 ) -{ -} - -inline void CAverageCycleCounter::Init() -{ - m_Total.Init(); - m_Peak.Init(); - m_nIters = 0; -} - -inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration ) -{ - ++m_nIters; - m_Total += duration; - if ( m_Peak.IsLessThan( duration ) ) - m_Peak = duration; -} - -inline unsigned CAverageCycleCounter::GetIters() const -{ - return m_nIters; -} - -inline double CAverageCycleCounter::GetAverageMilliseconds() const -{ - if ( m_nIters ) - return (m_Total.GetMillisecondsF() / (double)m_nIters); - else - return 0; -} - -inline double CAverageCycleCounter::GetTotalMilliseconds() const -{ - return m_Total.GetMillisecondsF(); -} - -inline double CAverageCycleCounter::GetPeakMilliseconds() const -{ - return m_Peak.GetMillisecondsF(); -} - -// -------------------------------------------------------------------------- // - -inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter ) -{ - m_pCounter = pCounter; - m_Timer.Start(); -} - -inline CAverageTimeMarker::~CAverageTimeMarker() -{ - m_Timer.End(); - m_pCounter->MarkIter( m_Timer.GetDuration() ); -} - - -// CLimitTimer -// Use this to time whether a desired interval of time has passed. It's extremely fast -// to check while running. -class CLimitTimer -{ -public: - void SetLimit( uint64 m_cMicroSecDuration ); - bool BLimitReached( void ); - -private: - int64 m_lCycleLimit; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Initializes the limit timer with a period of time to measure. -// Input : cMicroSecDuration - How long a time period to measure -//----------------------------------------------------------------------------- -inline void CLimitTimer::SetLimit( uint64 m_cMicroSecDuration ) -{ - int64 dlCycles = ( ( uint64 ) m_cMicroSecDuration * ( int64 ) g_dwClockSpeed ) / ( int64 ) 1000000L; - CCycleCount cycleCount; - cycleCount.Sample( ); - m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles; -} - - -//----------------------------------------------------------------------------- -// Purpose: Determines whether our specified time period has passed -// Output: true if at least the specified time period has passed -//----------------------------------------------------------------------------- -inline bool CLimitTimer::BLimitReached( ) -{ - CCycleCount cycleCount; - cycleCount.Sample( ); - return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit ); -} - - - -#endif // FASTTIMER_H diff --git a/Resources/NetHook/tier0/ia32detect.h b/Resources/NetHook/tier0/ia32detect.h deleted file mode 100644 index a60bb1a5..00000000 --- a/Resources/NetHook/tier0/ia32detect.h +++ /dev/null @@ -1,351 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef IA32DETECT_H -#define IA32DETECT_H - -/* - This section from http://iss.cs.cornell.edu/ia32.htm - - - */ -typedef unsigned bit; - -enum CPUVendor -{ - INTEL, - AMD, - UNKNOWN_VENDOR -}; -class ia32detect -{ -public: - - enum type_t - { - type_OEM, - type_OverDrive, - type_Dual, - type_reserved - }; - - enum brand_t - { - brand_na, - brand_Celeron, - brand_PentiumIII, - brand_PentiumIIIXeon, - brand_reserved1, - brand_reserved2, - brand_PentiumIIIMobile, - brand_reserved3, - brand_Pentium4, - brand_invalid - }; - -# pragma pack(push, 1) - - struct version_t - { - bit Stepping : 4; - bit Model : 4; - bit Family : 4; - bit Type : 2; - bit Reserved1 : 2; - bit XModel : 4; - bit XFamily : 8; - bit Reserved2 : 4; - }; - - struct misc_t - { - byte Brand; - byte CLFLUSH; - byte Reserved; - byte APICId; - }; - - struct feature_t - { - bit FPU : 1; // Floating Point Unit On-Chip - bit VME : 1; // Virtual 8086 Mode Enhancements - bit DE : 1; // Debugging Extensions - bit PSE : 1; // Page Size Extensions - bit TSC : 1; // Time Stamp Counter - bit MSR : 1; // Model Specific Registers - bit PAE : 1; // Physical Address Extension - bit MCE : 1; // Machine Check Exception - bit CX8 : 1; // CMPXCHG8 Instruction - bit APIC : 1; // APIC On-Chip - bit Reserved1 : 1; - bit SEP : 1; // SYSENTER and SYSEXIT instructions - bit MTRR : 1; // Memory Type Range Registers - bit PGE : 1; // PTE Global Bit - bit MCA : 1; // Machine Check Architecture - bit CMOV : 1; // Conditional Move Instructions - bit PAT : 1; // Page Attribute Table - bit PSE36 : 1; // 32-bit Page Size Extension - bit PSN : 1; // Processor Serial Number - bit CLFSH : 1; // CLFLUSH Instruction - bit Reserved2 : 1; - bit DS : 1; // Debug Store - bit ACPI : 1; // Thermal Monitor and Software Controlled Clock Facilities - bit MMX : 1; // Intel MMX Technology - bit FXSR : 1; // FXSAVE and FXRSTOR Instructions - bit SSE : 1; // Intel SSE Technology - bit SSE2 : 1; // Intel SSE2 Technology - bit SS : 1; // Self Snoop - bit HTT : 1; // Hyper Threading - bit TM : 1; // Thermal Monitor - bit Reserved3 : 1; - bit PBE : 1; // Pending Brk. EN. - }; - -# pragma pack(pop) - - tstring vendor_name; - CPUVendor vendor; - tstring brand; - version_t version; - misc_t misc; - feature_t feature; - byte *cache; - - ia32detect () - { - - cache = 0; - uint32 m = init0(); - - uint32 *d = new uint32[m * 4]; - - for (uint32 i = 1; i <= m; i++) - { - uint32 *t = d + (i - 1) * 4; - - __asm - { - mov eax, i; - mov esi, t; - - cpuid; - - mov dword ptr [esi + 0x0], eax; - mov dword ptr [esi + 0x4], ebx; - mov dword ptr [esi + 0x8], ecx; - mov dword ptr [esi + 0xC], edx; - } - } - - if (m >= 1) - init1(d); - - if (m >= 2) - init2(d[4] & 0xFF); - - delete [] d; - - init0x80000000(); - - - //----------------------------------------------------------------------- - // Get the vendor of the processor - //----------------------------------------------------------------------- - if (_tcscmp(vendor_name.c_str(), _T("GenuineIntel")) == 0) - { - vendor = INTEL; - - } - else if (_tcscmp(vendor_name.c_str(), _T("AuthenticAMD")) == 0) - { - vendor = AMD; - - } - else - { - vendor = UNKNOWN_VENDOR; - } - } - - const tstring version_text () const - { - tchar b[128]; - - _stprintf(b, _T("%d.%d.%d %s XVersion(%d.%d)"), - version.Family, version.Model, version.Stepping, type_text(), version.XFamily, version.XModel); - - return tstring(b); - } - -protected: - - const tchar * type_text () const - { - static const tchar *text[] = - { - _T("Intel OEM Processor"), - _T("Intel OverDrive(R) Processor"), - _T("Intel Dual Processor"), - _T("reserved") - }; - - return text[version.Type]; - } - - const tstring brand_text () const - { - static const tchar *text[] = - { - _T("n/a"), - _T("Celeron"), - _T("Pentium III"), - _T("Pentium III Xeon"), - _T("reserved (4)"), - _T("reserved (5)"), - _T("Pentium III Mobile"), - _T("reserved (7)"), - _T("Pentium 4") - }; - - if (misc.Brand < brand_invalid) - return tstring(text[misc.Brand]); - else - { - tchar b[32]; - - _stprintf(b, _T("Brand %d (Update)"), misc.Brand); - - return tstring(b); - } - } - -private: - - uint32 init0 () - { - uint32 m; - tchar s1[13]; - - s1[12] = '\0'; - - __asm - { - xor eax, eax; - cpuid; - mov m, eax; - mov dword ptr s1 + 0, ebx; - mov dword ptr s1 + 4, edx; - mov dword ptr s1 + 8, ecx; - } - - vendor_name = s1; - - return m; - } - - void init1 (uint32 *d) - { - version = *(version_t *)&d[0]; - misc = *(misc_t *)&d[1]; - feature = *(feature_t *)&d[3]; - } - - void process2 (uint32 d, bool c[]) - { - if ((d & 0x80000000) == 0) - for (int i = 0; i < 32; i += 8) - c[(d >> i) & 0xFF] = true; - } - - void init2 (byte count) - { - uint32 d[4]; - bool c[256]; - - for (int ci1 = 0; ci1 < 256; ci1++) - c[ci1] = false; - - for (int i = 0; i < count; i++) - { - __asm - { - mov eax, 2; - lea esi, d; - cpuid; - mov [esi + 0x0], eax; - mov [esi + 0x4], ebx; - mov [esi + 0x8], ecx; - mov [esi + 0xC], edx; - } - - if (i == 0) - d[0] &= 0xFFFFFF00; - - process2(d[0], c); - process2(d[1], c); - process2(d[2], c); - process2(d[3], c); - } - - int m = 0; - - for (int ci2 = 0; ci2 < 256; ci2++) - if (c[ci2]) - m++; - - cache = new byte[m]; - - m = 0; - - for (int ci3 = 1; ci3 < 256; ci3++) - if (c[ci3]) - cache[m++] = ci3; - - cache[m] = 0; - } - - void init0x80000000 () - { - uint32 m; - - __asm - { - mov eax, 0x80000000; - cpuid; - mov m, eax - } - - if ((m & 0x80000000) != 0) - { - uint32 *d = new uint32[(m - 0x80000000) * 4]; - - for (uint32 i = 0x80000001; i <= m; i++) - { - uint32 *t = d + (i - 0x80000001) * 4; - - __asm - { - mov eax, i; - mov esi, t; - cpuid; - mov dword ptr [esi + 0x0], eax; - mov dword ptr [esi + 0x4], ebx; - mov dword ptr [esi + 0x8], ecx; - mov dword ptr [esi + 0xC], edx; - } - } - - if (m >= 0x80000002) - brand = (tchar *)(d + 4); - - // note the assignment to brand above does a copy, we need to delete - delete[] d; - } - } -}; - -#endif // IA32DETECT_H diff --git a/Resources/NetHook/tier0/icommandline.h b/Resources/NetHook/tier0/icommandline.h deleted file mode 100644 index 54951caa..00000000 --- a/Resources/NetHook/tier0/icommandline.h +++ /dev/null @@ -1,53 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#ifndef TIER0_ICOMMANDLINE_H -#define TIER0_ICOMMANDLINE_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/platform.h" - - -//----------------------------------------------------------------------------- -// Purpose: Interface to engine command line -//----------------------------------------------------------------------------- -abstract_class ICommandLine -{ -public: - virtual void CreateCmdLine( const char *commandline ) = 0; - virtual void CreateCmdLine( int argc, char **argv ) = 0; - virtual const char *GetCmdLine( void ) const = 0; - - // Check whether a particular parameter exists - virtual const char *CheckParm( const char *psz, const char **ppszValue = 0 ) const = 0; - virtual void RemoveParm( const char *parm ) = 0; - virtual void AppendParm( const char *pszParm, const char *pszValues ) = 0; - - // Returns the argument after the one specified, or the default if not found - virtual const char *ParmValue( const char *psz, const char *pDefaultVal = 0 ) const = 0; - virtual int ParmValue( const char *psz, int nDefaultVal ) const = 0; - virtual float ParmValue( const char *psz, float flDefaultVal ) const = 0; - - // Gets at particular parameters - virtual int ParmCount() const = 0; - virtual int FindParm( const char *psz ) const = 0; // Returns 0 if not found. - virtual const char* GetParm( int nIndex ) const = 0; -}; - -//----------------------------------------------------------------------------- -// Gets a singleton to the commandline interface -// NOTE: The #define trickery here is necessary for backwards compat: -// this interface used to lie in the vstdlib library. -//----------------------------------------------------------------------------- -PLATFORM_INTERFACE ICommandLine *CommandLine_Tier0(); - -#if !defined( VSTDLIB_BACKWARD_COMPAT ) -#define CommandLine CommandLine_Tier0 -#endif - -#endif // TIER0_ICOMMANDLINE_H \ No newline at end of file diff --git a/Resources/NetHook/tier0/l2cache.h b/Resources/NetHook/tier0/l2cache.h deleted file mode 100644 index 77636599..00000000 --- a/Resources/NetHook/tier0/l2cache.h +++ /dev/null @@ -1,46 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// -#ifndef CL2CACHE_H -#define CL2CACHE_H -#ifdef _WIN32 -#pragma once -#endif - -class P4Event_BSQ_cache_reference; - -class CL2Cache -{ -public: - - CL2Cache(); - ~CL2Cache(); - - void Start( void ); - void End( void ); - - //------------------------------------------------------------------------- - // GetL2CacheMisses - //------------------------------------------------------------------------- - int GetL2CacheMisses( void ) - { - return m_iL2CacheMissCount; - } - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE - -private: - - int m_nID; - - P4Event_BSQ_cache_reference *m_pL2CacheEvent; - int64 m_i64Start; - int64 m_i64End; - int m_iL2CacheMissCount; -}; - -#endif // CL2CACHE_H \ No newline at end of file diff --git a/Resources/NetHook/tier0/mem.h b/Resources/NetHook/tier0/mem.h deleted file mode 100644 index 3c3b9e16..00000000 --- a/Resources/NetHook/tier0/mem.h +++ /dev/null @@ -1,45 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Memory allocation! -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef TIER0_MEM_H -#define TIER0_MEM_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include "tier0/platform.h" - -#if !defined(STATIC_TIER0) && !defined(_STATIC_LINKED) - -#ifdef TIER0_DLL_EXPORT -# define MEM_INTERFACE DLL_EXPORT -#else -# define MEM_INTERFACE DLL_IMPORT -#endif - -#else // BUILD_AS_DLL - -#define MEM_INTERFACE extern - -#endif // BUILD_AS_DLL - - - -//----------------------------------------------------------------------------- -// DLL-exported methods for particular kinds of memory -//----------------------------------------------------------------------------- -MEM_INTERFACE void *MemAllocScratch( int nMemSize ); -MEM_INTERFACE void MemFreeScratch(); - -#ifdef _LINUX -MEM_INTERFACE void ZeroMemory( void *mem, size_t length ); -#endif - - -#endif /* TIER0_MEM_H */ diff --git a/Resources/NetHook/tier0/memalloc.h b/Resources/NetHook/tier0/memalloc.h deleted file mode 100644 index b76b3f14..00000000 --- a/Resources/NetHook/tier0/memalloc.h +++ /dev/null @@ -1,353 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This header should never be used directly from leaf code!!! -// Instead, just add the file memoverride.cpp into your project and all this -// will automagically be used -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef TIER0_MEMALLOC_H -#define TIER0_MEMALLOC_H - -#ifdef _WIN32 -#pragma once -#endif - -// Define this in release to get memory tracking even in release builds -//#define USE_MEM_DEBUG 1 - -#if defined( _MEMTEST ) -#define USE_MEM_DEBUG 1 -#endif - -// Undefine this if using a compiler lacking threadsafe RTTI (like vc6) -#define MEM_DEBUG_CLASSNAME 1 - -#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) - -#include -#include "tier0/mem.h" - -struct _CrtMemState; - -#define MEMALLOC_VERSION 1 - -typedef size_t (*MemAllocFailHandler_t)( size_t ); - -//----------------------------------------------------------------------------- -// NOTE! This should never be called directly from leaf code -// Just use new,delete,malloc,free etc. They will call into this eventually -//----------------------------------------------------------------------------- -abstract_class IMemAlloc -{ -public: - // Release versions - virtual void *Alloc( size_t nSize ) = 0; - virtual void *Realloc( void *pMem, size_t nSize ) = 0; - virtual void Free( void *pMem ) = 0; - virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0; - - // Debug versions - virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0; - virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0; - virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0; - virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0; - - // Returns size of a particular allocation - virtual size_t GetSize( void *pMem ) = 0; - - // Force file + line information for an allocation - virtual void PushAllocDbgInfo( const char *pFileName, int nLine ) = 0; - virtual void PopAllocDbgInfo() = 0; - - // FIXME: Remove when we have our own allocator - // these methods of the Crt debug code is used in our codebase currently - virtual long CrtSetBreakAlloc( long lNewBreakAlloc ) = 0; - virtual int CrtSetReportMode( int nReportType, int nReportMode ) = 0; - virtual int CrtIsValidHeapPointer( const void *pMem ) = 0; - virtual int CrtIsValidPointer( const void *pMem, unsigned int size, int access ) = 0; - virtual int CrtCheckMemory( void ) = 0; - virtual int CrtSetDbgFlag( int nNewFlag ) = 0; - virtual void CrtMemCheckpoint( _CrtMemState *pState ) = 0; - - // FIXME: Make a better stats interface - virtual void DumpStats() = 0; - virtual void DumpStatsFileBase( char const *pchFileBase ) = 0; - - // FIXME: Remove when we have our own allocator - virtual void* CrtSetReportFile( int nRptType, void* hFile ) = 0; - virtual void* CrtSetReportHook( void* pfnNewHook ) = 0; - virtual int CrtDbgReport( int nRptType, const char * szFile, - int nLine, const char * szModule, const char * pMsg ) = 0; - - virtual int heapchk() = 0; - - virtual bool IsDebugHeap() = 0; - - virtual void GetActualDbgInfo( const char *&pFileName, int &nLine ) = 0; - virtual void RegisterAllocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0; - virtual void RegisterDeallocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0; - - virtual int GetVersion() = 0; - - virtual void CompactHeap() = 0; - - // Function called when malloc fails or memory limits hit to attempt to free up memory (can come in any thread) - virtual MemAllocFailHandler_t SetAllocFailHandler( MemAllocFailHandler_t pfnMemAllocFailHandler ) = 0; - - virtual void DumpBlockStats( void * ) = 0; - -#if defined( _MEMTEST ) - virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0; -#endif - - // Returns 0 if no failure, otherwise the size_t of the last requested chunk - virtual size_t MemoryAllocFailed() = 0; -}; - -//----------------------------------------------------------------------------- -// Singleton interface -//----------------------------------------------------------------------------- -MEM_INTERFACE IMemAlloc *g_pMemAlloc; - -//----------------------------------------------------------------------------- - -inline void *MemAlloc_AllocAligned( size_t size, size_t align ) -{ - unsigned char *pAlloc, *pResult; - - if (!IsPowerOfTwo(align)) - return NULL; - - align = (align > sizeof(void *) ? align : sizeof(void *)) - 1; - - if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL) - return NULL; - - pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align ); - ((unsigned char**)(pResult))[-1] = pAlloc; - - return (void *)pResult; -} - -inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile, int nLine ) -{ - unsigned char *pAlloc, *pResult; - - if (!IsPowerOfTwo(align)) - return NULL; - - align = (align > sizeof(void *) ? align : sizeof(void *)) - 1; - - if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL) - return NULL; - - pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align ); - ((unsigned char**)(pResult))[-1] = pAlloc; - - return (void *)pResult; -} - -inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align ) -{ - if ( !IsPowerOfTwo( align ) ) - return NULL; - - // Don't change alignment between allocation + reallocation. - if ( ( (size_t)ptr & ( align - 1 ) ) != 0 ) - return NULL; - - if ( !ptr ) - return MemAlloc_AllocAligned( size, align ); - - void *pAlloc, *pResult; - - // Figure out the actual allocation point - pAlloc = ptr; - pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *)); - pAlloc = *( (void **)pAlloc ); - - // See if we have enough space - size_t nOffset = (size_t)ptr - (size_t)pAlloc; - size_t nOldSize = g_pMemAlloc->GetSize( pAlloc ); - if ( nOldSize >= size + nOffset ) - return ptr; - - pResult = MemAlloc_AllocAligned( size, align ); - memcpy( pResult, ptr, nOldSize - nOffset ); - g_pMemAlloc->Free( pAlloc ); - return pResult; -} - -inline void MemAlloc_FreeAligned( void *pMemBlock ) -{ - void *pAlloc; - - if ( pMemBlock == NULL ) - return; - - pAlloc = pMemBlock; - - // pAlloc points to the pointer to starting of the memory block - pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *)); - - // pAlloc is the pointer to the start of memory block - pAlloc = *( (void **)pAlloc ); - g_pMemAlloc->Free( pAlloc ); -} - -inline size_t MemAlloc_GetSizeAligned( void *pMemBlock ) -{ - void *pAlloc; - - if ( pMemBlock == NULL ) - return 0; - - pAlloc = pMemBlock; - - // pAlloc points to the pointer to starting of the memory block - pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *)); - - // pAlloc is the pointer to the start of memory block - pAlloc = *((void **)pAlloc ); - return g_pMemAlloc->GetSize( pAlloc ) - ( (byte *)pMemBlock - (byte *)pAlloc ); -} - -//----------------------------------------------------------------------------- - -#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) -#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ ) -#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line ) -#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo() -#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) -#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) -#else -#define MEM_ALLOC_CREDIT_(tag) ((void)0) -#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0) -#define MemAlloc_PopAllocDbgInfo() ((void)0) -#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) -#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) -#endif - -//----------------------------------------------------------------------------- - -class CMemAllocAttributeAlloction -{ -public: - CMemAllocAttributeAlloction( const char *pszFile, int line ) - { - MemAlloc_PushAllocDbgInfo( pszFile, line ); - } - - ~CMemAllocAttributeAlloction() - { - MemAlloc_PopAllocDbgInfo(); - } -}; - -#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__) - -//----------------------------------------------------------------------------- - -#if defined(_WIN32) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) ) - - #pragma warning(disable:4290) - #pragma warning(push) - #include - - // MEM_DEBUG_CLASSNAME is opt-in. - // Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads - // simultaneously, it'll need a mutex. - #if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME) - #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() ) - #define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name()) - #else - #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ ) - #define MEM_ALLOC_CLASSNAME(type) (__FILE__) - #endif - - // MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example ) - #ifdef _MSC_VER - #define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ ) - #else - #define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__) - #endif - - #pragma warning(pop) -#else - #define MEM_ALLOC_CREDIT_CLASS() - #define MEM_ALLOC_CLASSNAME(type) NULL - #define MEM_ALLOC_CREDIT_FUNCTION() -#endif - -//----------------------------------------------------------------------------- - -#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) -struct MemAllocFileLine_t -{ - const char *pszFile; - int line; -}; - -#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \ - static CUtlMap g_##tag##Allocs( DefLessFunc( void *) ); \ - static const char *g_psz##tag##Alloc = strcpy( (char *)g_pMemAlloc->Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" ); - -#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \ - if ( !p ) \ - ; \ - else \ - { \ - MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \ - g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \ - if ( fileLine.pszFile != g_psz##tag##Alloc ) \ - { \ - g_##tag##Allocs.Insert( p, fileLine ); \ - } \ - \ - MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \ - } - -#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) \ - if ( !p ) \ - ; \ - else \ - { \ - MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \ - CUtlMap::IndexType_t iRecordedFileLine = g_##tag##Allocs.Find( p ); \ - if ( iRecordedFileLine != g_##tag##Allocs.InvalidIndex() ) \ - { \ - fileLine = g_##tag##Allocs[iRecordedFileLine]; \ - g_##tag##Allocs.RemoveAt( iRecordedFileLine ); \ - } \ - \ - MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \ - } - -#else - -#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) -#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0) -#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0) - -#endif - -//----------------------------------------------------------------------------- - -#endif // !STEAM && !NO_MALLOC_OVERRIDE - -//----------------------------------------------------------------------------- - -#if !defined(STEAM) && defined(NO_MALLOC_OVERRIDE) - -#define MEM_ALLOC_CREDIT_(tag) ((void)0) -#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__) -#define MEM_ALLOC_CREDIT_CLASS() -#define MEM_ALLOC_CLASSNAME(type) NULL - -#endif !STEAM && NO_MALLOC_OVERRIDE - -//----------------------------------------------------------------------------- - -#endif /* TIER0_MEMALLOC_H */ diff --git a/Resources/NetHook/tier0/memdbgoff.h b/Resources/NetHook/tier0/memdbgoff.h deleted file mode 100644 index 685e2001..00000000 --- a/Resources/NetHook/tier0/memdbgoff.h +++ /dev/null @@ -1,25 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This header, which must be the final line of a .h file, -// causes all crt methods to stop using debugging versions of the memory allocators. -// NOTE: Use memdbgon.h to re-enable memory debugging. -// -// $NoKeywords: $ -//=============================================================================// - -#ifdef MEM_OVERRIDE_ON - -#undef malloc -#undef realloc -#undef calloc -#undef free -#undef _expand -#undef _msize -#undef new -#undef _aligned_malloc -#undef _aligned_free -#undef _malloc_dbg - -#undef MEM_OVERRIDE_ON - -#endif diff --git a/Resources/NetHook/tier0/memdbgon.h b/Resources/NetHook/tier0/memdbgon.h deleted file mode 100644 index 59ad4675..00000000 --- a/Resources/NetHook/tier0/memdbgon.h +++ /dev/null @@ -1,243 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This header, which must be the final include in a .cpp (or .h) file, -// causes all crt methods to use debugging versions of the memory allocators. -// NOTE: Use memdbgoff.h to disable memory debugging. -// -// $NoKeywords: $ -//=============================================================================// - -// SPECIAL NOTE! This file must *not* use include guards; we need to be able -// to include this potentially multiple times (since we can deactivate debugging -// by including memdbgoff.h) - -#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) - -// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!! - -#if defined(_DEBUG) && !defined(USE_MEM_DEBUG) -#define USE_MEM_DEBUG 1 -#endif - -// If debug build or ndebug and not already included MS custom alloc files, or already included this file -#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H) - -#include "basetypes.h" -#ifdef _WIN32 -#include -#else -#include -#endif -#include -#include -#include "commonmacros.h" -#include "memalloc.h" - -#if defined(USE_MEM_DEBUG) - #if defined(_LINUX) - - #define _NORMAL_BLOCK 1 - - #include - #include - #include - #include - - #if !defined( DID_THE_OPERATOR_NEW ) - #define DID_THE_OPERATOR_NEW - inline void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ) - { - return g_pMemAlloc->Alloc( nSize, pFileName, nLine ); - } - inline void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ) - { - return g_pMemAlloc->Alloc( nSize, pFileName, nLine ); - } - #endif - - #else // defined(_LINUX) - - // Include crtdbg.h and make sure _DEBUG is set to 1. - #if !defined(_DEBUG) - #define _DEBUG 1 - #include - #undef _DEBUG - #else - #include - #endif // !defined(_DEBUG) - - #endif // defined(_LINUX) -#endif - -#include "tier0/memdbgoff.h" - -// -------------------------------------------------------- -// Debug/non-debug agnostic elements - -#define MEM_OVERRIDE_ON 1 - -#undef malloc -#undef realloc -#undef calloc -#undef _expand -#undef free -#undef _msize -#undef _aligned_malloc -#undef _aligned_free - -#ifndef MEMDBGON_H -inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nElementSize) -{ - memset(pMem, 0, nElementSize * nCount); - return pMem; -} -#endif - -#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s) -#define free(p) g_pMemAlloc->Free( p ) -#define _msize(p) g_pMemAlloc->GetSize( p ) -#define _expand(p, s) _expand_NoLongerSupported(p, s) -#define _aligned_free( p ) MemAlloc_FreeAligned( p ) - -// -------------------------------------------------------- -// Debug path -#if defined(USE_MEM_DEBUG) - -#define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__) -#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ ) -#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ ) - -#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) - -#if defined(__AFX_H__) && defined(DEBUG_NEW) - #define new DEBUG_NEW -#else - #undef new - #define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) - #define new MEMALL_DEBUG_NEW -#endif - -#undef _strdup -#undef strdup -#undef _wcsdup -#undef wcsdup - -#define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__) -#define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__) -#define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__) -#define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__) - -// Make sure we don't define strdup twice -#if !defined(MEMDBGON_H) - -inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigned nLine) -{ - char *pMemory; - - if (!pString) - return NULL; - - size_t len = strlen(pString) + 1; - if ((pMemory = (char *)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL) - { - return strcpy( pMemory, pString ); - } - - return NULL; -} - -inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName, unsigned nLine) -{ - wchar_t *pMemory; - - if (!pString) - return NULL; - - size_t len = (wcslen(pString) + 1); - if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL) - { - return wcscpy( pMemory, pString ); - } - - return NULL; -} - -#endif // DBMEM_DEFINED_STRDUP - -#else -// -------------------------------------------------------- -// Release path - -#define malloc(s) g_pMemAlloc->Alloc( s ) -#define realloc(p, s) g_pMemAlloc->Realloc( p, s ) -#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a ) - -#ifndef _malloc_dbg -#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) -#endif - -#undef new - -#undef _strdup -#undef strdup -#undef _wcsdup -#undef wcsdup - -#define _strdup(s) MemAlloc_StrDup(s) -#define strdup(s) MemAlloc_StrDup(s) -#define _wcsdup(s) MemAlloc_WcStrDup(s) -#define wcsdup(s) MemAlloc_WcStrDup(s) - -// Make sure we don't define strdup twice -#if !defined(MEMDBGON_H) - -inline char *MemAlloc_StrDup(const char *pString) -{ - char *pMemory; - - if (!pString) - return NULL; - - size_t len = strlen(pString) + 1; - if ((pMemory = (char *)g_pMemAlloc->Alloc(len)) != NULL) - { - return strcpy( pMemory, pString ); - } - - return NULL; -} - -inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString) -{ - wchar_t *pMemory; - - if (!pString) - return NULL; - - size_t len = (wcslen(pString) + 1); - if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL) - { - return wcscpy( pMemory, pString ); - } - - return NULL; -} - -#endif // DBMEM_DEFINED_STRDUP - -#endif // USE_MEM_DEBUG - -#define MEMDBGON_H // Defined here so can be used above - -#else - -#if defined(USE_MEM_DEBUG) -#ifndef _STATIC_LINKED -#pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build") -#else -#error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build" -#endif -#endif -#endif // _INC_CRTDBG - -#endif // !STEAM && !NO_MALLOC_OVERRIDE diff --git a/Resources/NetHook/tier0/memoverride.cpp b/Resources/NetHook/tier0/memoverride.cpp deleted file mode 100644 index 453ca48b..00000000 --- a/Resources/NetHook/tier0/memoverride.cpp +++ /dev/null @@ -1,1385 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Insert this file into all projects using the memory system -// It will cause that project to use the shader memory allocator -// -// $NoKeywords: $ -//=============================================================================// - - -#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) - -#undef PROTECTED_THINGS_ENABLE // allow use of _vsnprintf - -#if defined( _WIN32 ) && !defined( _X360 ) -#define WIN_32_LEAN_AND_MEAN -#include -#endif - -#include "tier0/dbg.h" -#include "tier0/memalloc.h" -#include -#include -#include "memdbgoff.h" - -// Tags this DLL as debug -#if defined( _DEBUG ) && !defined( _X360 ) -DLL_EXPORT void BuiltDebug() {} -#endif - -#ifdef _WIN32 -// ARG: crtdbg is necessary for certain definitions below, -// but it also redefines malloc as a macro in release. -// To disable this, we gotta define _DEBUG before including it.. BLEAH! -#define _DEBUG 1 -#include "crtdbg.h" -#ifdef NDEBUG -#undef _DEBUG -#endif - -// Turn this back off in release mode. -#ifdef NDEBUG -#undef _DEBUG -#endif -#elif _LINUX -#define __cdecl -#endif - -#if defined( _WIN32 ) && !defined( _X360 ) -const char *MakeModuleFileName() -{ - if ( g_pMemAlloc->IsDebugHeap() ) - { - char *pszModuleName = (char *)HeapAlloc( GetProcessHeap(), 0, MAX_PATH ); // small leak, debug only - - MEMORY_BASIC_INFORMATION mbi; - static int dummy; - VirtualQuery( &dummy, &mbi, sizeof(mbi) ); - - GetModuleFileName( reinterpret_cast(mbi.AllocationBase), pszModuleName, MAX_PATH ); - char *pDot = strrchr( pszModuleName, '.' ); - if ( pDot ) - { - char *pSlash = strrchr( pszModuleName, '\\' ); - if ( pSlash ) - { - pszModuleName = pSlash + 1; - *pDot = 0; - } - } - - return pszModuleName; - } - return NULL; -} - -static void *AllocUnattributed( size_t nSize ) -{ - static const char *pszOwner = MakeModuleFileName(); - - if ( !pszOwner ) - return g_pMemAlloc->Alloc(nSize); - else - return g_pMemAlloc->Alloc(nSize, pszOwner, 0); -} - -static void *ReallocUnattributed( void *pMem, size_t nSize ) -{ - static const char *pszOwner = MakeModuleFileName(); - - if ( !pszOwner ) - return g_pMemAlloc->Realloc(pMem, nSize); - else - return g_pMemAlloc->Realloc(pMem, nSize, pszOwner, 0); -} - -#else -#define MakeModuleFileName() NULL -inline void *AllocUnattributed( size_t nSize ) -{ - return g_pMemAlloc->Alloc(nSize); -} - -inline void *ReallocUnattributed( void *pMem, size_t nSize ) -{ - return g_pMemAlloc->Realloc(pMem, nSize); -} -#endif - -//----------------------------------------------------------------------------- -// Standard functions in the CRT that we're going to override to call our allocator -//----------------------------------------------------------------------------- -#if defined(_WIN32) && !defined(_STATIC_LINKED) -// this magic only works under win32 -// under linux this malloc() overrides the libc malloc() and so we -// end up in a recursion (as g_pMemAlloc->Alloc() calls malloc) -#if _MSC_VER >= 1400 -#define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT -#define FREE_CALL _CRTNOALIAS -#else -#define ALLOC_CALL -#define FREE_CALL -#endif - -extern "C" -{ - -ALLOC_CALL void *malloc( size_t nSize ) -{ - return AllocUnattributed( nSize ); -} - -FREE_CALL void free( void *pMem ) -{ - g_pMemAlloc->Free(pMem); -} - -ALLOC_CALL void *realloc( void *pMem, size_t nSize ) -{ - return ReallocUnattributed( pMem, nSize ); -} - -ALLOC_CALL void *calloc( size_t nCount, size_t nElementSize ) -{ - void *pMem = AllocUnattributed( nElementSize * nCount ); - memset(pMem, 0, nElementSize * nCount); - return pMem; -} - -} // end extern "C" - -//----------------------------------------------------------------------------- -// Non-standard MSVC functions that we're going to override to call our allocator -//----------------------------------------------------------------------------- -extern "C" -{ - -// 64-bit -#ifdef _WIN64 -void* __cdecl _malloc_base( size_t nSize ) -{ - return AllocUnattributed( nSize ); -} -#else -void *_malloc_base( size_t nSize ) -{ - return AllocUnattributed( nSize ); -} -#endif - -void *_calloc_base( size_t nSize ) -{ - void *pMem = AllocUnattributed( nSize ); - memset(pMem, 0, nSize); - return pMem; -} - -void *_realloc_base( void *pMem, size_t nSize ) -{ - return ReallocUnattributed( pMem, nSize ); -} - -void *_recalloc_base( void *pMem, size_t nSize ) -{ - void *pMemOut = ReallocUnattributed( pMem, nSize ); - memset(pMemOut, 0, nSize); - return pMemOut; -} - -void _free_base( void *pMem ) -{ - g_pMemAlloc->Free(pMem); -} - -void *__cdecl _expand_base( void *pMem, size_t nNewSize, int nBlockUse ) -{ - Assert( 0 ); - return NULL; -} - -// crt -void * __cdecl _malloc_crt(size_t size) -{ - return AllocUnattributed( size ); -} - -void * __cdecl _calloc_crt(size_t count, size_t size) -{ - return _calloc_base( count * size ); -} - -void * __cdecl _realloc_crt(void *ptr, size_t size) -{ - return _realloc_base( ptr, size ); -} - -void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size) -{ - return _recalloc_base( ptr, size * count ); -} - -ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size ) -{ - void *pMem = ReallocUnattributed( memblock, size * count ); - memset( pMem, 0, size * count ); - return pMem; -} - -size_t _msize_base( void *pMem ) -{ - return g_pMemAlloc->GetSize(pMem); -} - -size_t _msize( void *pMem ) -{ - return _msize_base(pMem); -} - -size_t msize( void *pMem ) -{ - return g_pMemAlloc->GetSize(pMem); -} - -void *__cdecl _heap_alloc( size_t nSize ) -{ - return AllocUnattributed( nSize ); -} - -void *__cdecl _nh_malloc( size_t nSize, int ) -{ - return AllocUnattributed( nSize ); -} - -void *__cdecl _expand( void *pMem, size_t nSize ) -{ - Assert( 0 ); - return NULL; -} - -unsigned int _amblksiz = 16; //BYTES_PER_PARA; - -#if _MSC_VER >= 1400 -HANDLE _crtheap = (HANDLE)1; // PatM Can't be 0 or CRT pukes -int __active_heap = 1; -#endif // _MSC_VER >= 1400 - -size_t __cdecl _get_sbh_threshold( void ) -{ - return 0; -} - -int __cdecl _set_sbh_threshold( size_t ) -{ - return 0; -} - -int _heapchk() -{ - return g_pMemAlloc->heapchk(); -} - -int _heapmin() -{ - return 1; -} - -int __cdecl _heapadd( void *, size_t ) -{ - return 0; -} - -int __cdecl _heapset( unsigned int ) -{ - return 0; -} - -size_t __cdecl _heapused( size_t *, size_t * ) -{ - return 0; -} - -#ifdef _WIN32 -int __cdecl _heapwalk( _HEAPINFO * ) -{ - return 0; -} -#endif - -} // end extern "C" - - -//----------------------------------------------------------------------------- -// Debugging functions that we're going to override to call our allocator -// NOTE: These have to be here for release + debug builds in case we -// link to a debug static lib!!! -//----------------------------------------------------------------------------- - -extern "C" -{ - -void *malloc_db( size_t nSize, const char *pFileName, int nLine ) -{ - return g_pMemAlloc->Alloc(nSize, pFileName, nLine); -} - -void free_db( void *pMem, const char *pFileName, int nLine ) -{ - g_pMemAlloc->Free(pMem, pFileName, nLine); -} - -void *realloc_db( void *pMem, size_t nSize, const char *pFileName, int nLine ) -{ - return g_pMemAlloc->Realloc(pMem, nSize, pFileName, nLine); -} - -} // end extern "C" - -//----------------------------------------------------------------------------- -// These methods are standard MSVC heap initialization + shutdown methods -//----------------------------------------------------------------------------- -extern "C" -{ - -#if !defined( _X360 ) - int __cdecl _heap_init() - { - return g_pMemAlloc != NULL; - } - - void __cdecl _heap_term() - { - } -#endif - -} -#endif - - -//----------------------------------------------------------------------------- -// Prevents us from using an inappropriate new or delete method, -// ensures they are here even when linking against debug or release static libs -//----------------------------------------------------------------------------- -#ifndef NO_MEMOVERRIDE_NEW_DELETE -void *__cdecl operator new( unsigned int nSize ) -{ - return AllocUnattributed( nSize ); -} - -void *__cdecl operator new( unsigned int nSize, int nBlockUse, const char *pFileName, int nLine ) -{ - return g_pMemAlloc->Alloc(nSize, pFileName, nLine); -} - -void __cdecl operator delete( void *pMem ) -{ - g_pMemAlloc->Free( pMem ); -} - -void *__cdecl operator new[] ( unsigned int nSize ) -{ - return AllocUnattributed( nSize ); -} - -void *__cdecl operator new[] ( unsigned int nSize, int nBlockUse, const char *pFileName, int nLine ) -{ - return g_pMemAlloc->Alloc(nSize, pFileName, nLine); -} - -void __cdecl operator delete[] ( void *pMem ) -{ - g_pMemAlloc->Free( pMem ); -} -#endif - - -//----------------------------------------------------------------------------- -// Override some debugging allocation methods in MSVC -// NOTE: These have to be here for release + debug builds in case we -// link to a debug static lib!!! -//----------------------------------------------------------------------------- -#ifndef _STATIC_LINKED -#ifdef _WIN32 - -// This here just hides the internal file names, etc of allocations -// made in the c runtime library -#define CRT_INTERNAL_FILE_NAME "C-runtime internal" - -class CAttibCRT -{ -public: - CAttibCRT(int nBlockUse) : m_nBlockUse(nBlockUse) - { - if (m_nBlockUse == _CRT_BLOCK) - { - g_pMemAlloc->PushAllocDbgInfo(CRT_INTERNAL_FILE_NAME, 0); - } - } - - ~CAttibCRT() - { - if (m_nBlockUse == _CRT_BLOCK) - { - g_pMemAlloc->PopAllocDbgInfo(); - } - } - -private: - int m_nBlockUse; -}; - - -#define AttribIfCrt() CAttibCRT _attrib(nBlockUse) -#elif defined(_LINUX) -#define AttribIfCrt() -#endif // _WIN32 - - -extern "C" -{ - -void *__cdecl _nh_malloc_dbg( size_t nSize, int nFlag, int nBlockUse, - const char *pFileName, int nLine ) -{ - AttribIfCrt(); - return g_pMemAlloc->Alloc(nSize, pFileName, nLine); -} - -void *__cdecl _malloc_dbg( size_t nSize, int nBlockUse, - const char *pFileName, int nLine ) -{ - AttribIfCrt(); - return g_pMemAlloc->Alloc(nSize, pFileName, nLine); -} - -void *__cdecl _calloc_dbg( size_t nNum, size_t nSize, int nBlockUse, - const char *pFileName, int nLine ) -{ - AttribIfCrt(); - void *pMem = g_pMemAlloc->Alloc(nSize * nNum, pFileName, nLine); - memset(pMem, 0, nSize * nNum); - return pMem; -} - -void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse, - const char *pFileName, int nLine ) -{ - AttribIfCrt(); - return g_pMemAlloc->Realloc(pMem, nNewSize, pFileName, nLine); -} - -void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse, - const char *pFileName, int nLine ) -{ - Assert( 0 ); - return NULL; -} - -void __cdecl _free_dbg( void *pMem, int nBlockUse ) -{ - AttribIfCrt(); - g_pMemAlloc->Free(pMem); -} - -size_t __cdecl _msize_dbg( void *pMem, int nBlockUse ) -{ -#ifdef _WIN32 - return _msize(pMem); -#elif _LINUX - Assert( "_msize_dbg unsupported" ); - return 0; -#endif -} - - -#ifdef _WIN32 - -#if defined(_DEBUG) && _MSC_VER >= 1300 -// X360TBD: aligned and offset allocations may be important on the 360 - -// aligned base -ALLOC_CALL void *__cdecl _aligned_malloc_base( size_t size, size_t align ) -{ - return MemAlloc_AllocAligned( size, align ); -} - -ALLOC_CALL void *__cdecl _aligned_realloc_base( void *ptr, size_t size, size_t align ) -{ - return MemAlloc_ReallocAligned( ptr, size, align ); -} - -ALLOC_CALL void *__cdecl _aligned_recalloc_base( void *ptr, size_t size, size_t align ) -{ - Error( "Unsupported function\n" ); - return NULL; -} - -FREE_CALL void __cdecl _aligned_free_base( void *ptr ) -{ - MemAlloc_FreeAligned( ptr ); -} - -// aligned -ALLOC_CALL void * __cdecl _aligned_malloc( size_t size, size_t align ) -{ - return _aligned_malloc_base(size, align); -} - -ALLOC_CALL void *__cdecl _aligned_realloc(void *memblock, size_t size, size_t align) -{ - return _aligned_realloc_base(memblock, size, align); -} - -ALLOC_CALL void * __cdecl _aligned_recalloc( void * memblock, size_t count, size_t size, size_t align ) -{ - return _aligned_recalloc_base(memblock, count * size, align); -} - -FREE_CALL void __cdecl _aligned_free( void *memblock ) -{ - _aligned_free_base(memblock); -} - -// aligned offset base -ALLOC_CALL void * __cdecl _aligned_offset_malloc_base( size_t size, size_t align, size_t offset ) -{ - Assert( IsPC() || 0 ); - return NULL; -} - -ALLOC_CALL void * __cdecl _aligned_offset_realloc_base( void * memblock, size_t size, size_t align, size_t offset) -{ - Assert( IsPC() || 0 ); - return NULL; -} - -ALLOC_CALL void * __cdecl _aligned_offset_recalloc_base( void * memblock, size_t size, size_t align, size_t offset) -{ - Assert( IsPC() || 0 ); - return NULL; -} - -// aligned offset -ALLOC_CALL void *__cdecl _aligned_offset_malloc(size_t size, size_t align, size_t offset) -{ - return _aligned_offset_malloc_base( size, align, offset ); -} - -ALLOC_CALL void *__cdecl _aligned_offset_realloc(void *memblock, size_t size, size_t align, size_t offset) -{ - return _aligned_offset_realloc_base( memblock, size, align, offset ); -} - -ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t count, size_t size, size_t align, size_t offset ) -{ - return _aligned_offset_recalloc_base( memblock, count * size, align, offset ); -} - -#endif // _MSC_VER >= 1400 - -#endif - -} // end extern "C" - - -//----------------------------------------------------------------------------- -// Override some the _CRT debugging allocation methods in MSVC -//----------------------------------------------------------------------------- -#ifdef _WIN32 - -extern "C" -{ - -int _CrtDumpMemoryLeaks(void) -{ - return 0; -} - -_CRT_DUMP_CLIENT _CrtSetDumpClient( _CRT_DUMP_CLIENT dumpClient ) -{ - return NULL; -} - -int _CrtSetDbgFlag( int nNewFlag ) -{ - return g_pMemAlloc->CrtSetDbgFlag( nNewFlag ); -} - -// 64-bit port. -#define AFNAME(var) __p_ ## var -#define AFRET(var) &var - -int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF; -int* AFNAME(_crtDbgFlag)(void) -{ - return AFRET(_crtDbgFlag); -} - -long _crtBreakAlloc; /* Break on this allocation */ -long* AFNAME(_crtBreakAlloc) (void) -{ - return AFRET(_crtBreakAlloc); -} - -void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse ) -{ - DebuggerBreak(); -} - -_CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook ) -{ - DebuggerBreak(); - return NULL; -} - -long __cdecl _CrtSetBreakAlloc( long lNewBreakAlloc ) -{ - return g_pMemAlloc->CrtSetBreakAlloc( lNewBreakAlloc ); -} - -int __cdecl _CrtIsValidHeapPointer( const void *pMem ) -{ - return g_pMemAlloc->CrtIsValidHeapPointer( pMem ); -} - -int __cdecl _CrtIsValidPointer( const void *pMem, unsigned int size, int access ) -{ - return g_pMemAlloc->CrtIsValidPointer( pMem, size, access ); -} - -int __cdecl _CrtCheckMemory( void ) -{ - // FIXME: Remove this when we re-implement the heap - return g_pMemAlloc->CrtCheckMemory( ); -} - -int __cdecl _CrtIsMemoryBlock( const void *pMem, unsigned int nSize, - long *plRequestNumber, char **ppFileName, int *pnLine ) -{ - DebuggerBreak(); - return 1; -} - -int __cdecl _CrtMemDifference( _CrtMemState *pState, const _CrtMemState * oldState, const _CrtMemState * newState ) -{ - DebuggerBreak(); - return FALSE; -} - -void __cdecl _CrtMemDumpStatistics( const _CrtMemState *pState ) -{ - DebuggerBreak(); -} - -void __cdecl _CrtMemCheckpoint( _CrtMemState *pState ) -{ - // FIXME: Remove this when we re-implement the heap - g_pMemAlloc->CrtMemCheckpoint( pState ); -} - -void __cdecl _CrtMemDumpAllObjectsSince( const _CrtMemState *pState ) -{ - DebuggerBreak(); -} - -void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pContext ) -{ - DebuggerBreak(); -} - - -//----------------------------------------------------------------------------- -// Methods in dbgrpt.cpp -//----------------------------------------------------------------------------- -long _crtAssertBusy = -1; - -int __cdecl _CrtSetReportMode( int nReportType, int nReportMode ) -{ - return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode ); -} - -_HFILE __cdecl _CrtSetReportFile( int nRptType, _HFILE hFile ) -{ - return (_HFILE)g_pMemAlloc->CrtSetReportFile( nRptType, hFile ); -} - -_CRT_REPORT_HOOK __cdecl _CrtSetReportHook( _CRT_REPORT_HOOK pfnNewHook ) -{ - return (_CRT_REPORT_HOOK)g_pMemAlloc->CrtSetReportHook( pfnNewHook ); -} - -int __cdecl _CrtDbgReport( int nRptType, const char * szFile, - int nLine, const char * szModule, const char * szFormat, ... ) -{ - static char output[1024]; - va_list args; - va_start( args, szFormat ); - _vsnprintf( output, sizeof( output )-1, szFormat, args ); - va_end( args ); - - return g_pMemAlloc->CrtDbgReport( nRptType, szFile, nLine, szModule, output ); -} - -#if _MSC_VER >= 1400 - -#if defined( _DEBUG ) - -// wrapper which passes no debug info; not available in debug -void __cdecl _invalid_parameter_noinfo(void) -{ - Assert(0); -} - -#endif /* defined( _DEBUG ) */ - -#if defined( _DEBUG ) || defined( USE_MEM_DEBUG ) - -int __cdecl __crtMessageWindowW( int nRptType, const wchar_t * szFile, const wchar_t * szLine, - const wchar_t * szModule, const wchar_t * szUserMessage ) -{ - Assert(0); - return 0; -} - -int __cdecl _CrtDbgReportV( int nRptType, const wchar_t *szFile, int nLine, - const wchar_t *szModule, const wchar_t *szFormat, va_list arglist ) -{ - Assert(0); - return 0; -} - -int __cdecl _CrtDbgReportW( int nRptType, const wchar_t *szFile, int nLine, - const wchar_t *szModule, const wchar_t *szFormat, ...) -{ - Assert(0); - return 0; -} - -int __cdecl _VCrtDbgReportA( int nRptType, const wchar_t * szFile, int nLine, - const wchar_t * szModule, const wchar_t * szFormat, va_list arglist ) -{ - Assert(0); - return 0; -} - -int __cdecl _CrtSetReportHook2( int mode, _CRT_REPORT_HOOK pfnNewHook ) -{ - _CrtSetReportHook( pfnNewHook ); - return 0; -} - - -#endif /* defined( _DEBUG ) || defined( USE_MEM_DEBUG ) */ - -extern "C" int __crtDebugCheckCount = FALSE; - -extern "C" int __cdecl _CrtSetCheckCount( int fCheckCount ) -{ - int oldCheckCount = __crtDebugCheckCount; - return oldCheckCount; -} - -extern "C" int __cdecl _CrtGetCheckCount( void ) -{ - return __crtDebugCheckCount; -} - -// aligned offset debug -extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n ) -{ - Assert( IsPC() || 0 ); - void *pMem = ReallocUnattributed( memblock, size * count ); - memset( pMem, 0, size * count ); - return pMem; -} - -extern "C" void * __cdecl _aligned_recalloc_dbg( void *memblock, size_t count, size_t size, size_t align, const char * f_name, int line_n ) -{ - return _aligned_offset_recalloc_dbg(memblock, count, size, align, 0, f_name, line_n); -} - -extern "C" void * __cdecl _recalloc_dbg ( void * memblock, size_t count, size_t size, int nBlockUse, const char * szFileName, int nLine ) -{ - return _aligned_offset_recalloc_dbg(memblock, count, size, 0, 0, szFileName, nLine); -} - -_CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void ) -{ - return NULL; -} - -#endif -int __cdecl _CrtReportBlockType(const void * pUserData) -{ - return 0; -} - - -} // end extern "C" -#endif // _WIN32 - -// Most files include this file, so when it's used it adds an extra .ValveDbg section, -// to help identify debug binaries. -#ifdef _WIN32 - #ifndef NDEBUG // _DEBUG - #pragma data_seg("ValveDBG") - volatile const char* DBG = "*** DEBUG STUB ***"; - #endif -#endif - -#endif - -// Extras added prevent dbgheap.obj from being included - DAL -#ifdef _WIN32 - -extern "C" -{ -size_t __crtDebugFillThreshold = 0; - -extern "C" void * __cdecl _heap_alloc_base (size_t size) { - assert(0); - return NULL; -} - - -void * __cdecl _heap_alloc_dbg( size_t nSize, int nBlockUse, const char * szFileName, int nLine) -{ - return _heap_alloc(nSize); -} - -// 64-bit -#ifdef _WIN64 -static void * __cdecl realloc_help( void * pUserData, size_t * pnNewSize, int nBlockUse,const char * szFileName, - int nLine, int fRealloc ) -{ - assert(0); // Shouldn't be needed - return NULL; -} -#else -static void * __cdecl realloc_help( void * pUserData, size_t nNewSize, int nBlockUse, const char * szFileName, - int nLine, int fRealloc) -{ - assert(0); // Shouldn't be needed - return NULL; -} -#endif - -void __cdecl _free_nolock( void * pUserData) -{ - // I don't think the second param is used in memoverride - _free_dbg(pUserData, 0); -} - -void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse) -{ - _free_dbg(pUserData, 0); -} - -_CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void) -{ - assert(0); - return NULL; -} - -static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize) -{ - int bOkay = TRUE; - return bOkay; -} - - -_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void) -{ - assert(0); - return NULL; -} - -#if _MSC_VER >= 1400 -static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead) -{ -} - -static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, _locale_t plocinfo) -{ -} -#endif -void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n) -{ - return _aligned_malloc(size, align); -} - -void * __cdecl _aligned_realloc_dbg( void *memblock, size_t size, size_t align, - const char * f_name, int line_n) -{ - return _aligned_realloc(memblock, size, align); -} - -void * __cdecl _aligned_offset_malloc_dbg( size_t size, size_t align, size_t offset, - const char * f_name, int line_n) -{ - return _aligned_offset_malloc(size, align, offset); -} - -void * __cdecl _aligned_offset_realloc_dbg( void * memblock, size_t size, size_t align, - size_t offset, const char * f_name, int line_n) -{ - return _aligned_offset_realloc(memblock, size, align, offset); -} - -void __cdecl _aligned_free_dbg( void * memblock) -{ - _aligned_free(memblock); -} - -size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold) -{ - assert(0); - return 0; -} - -//=========================================== -// NEW!!! 64-bit - -char * __cdecl _strdup ( const char * string ) -{ - int nSize = strlen(string) + 1; - char *pCopy = (char*)AllocUnattributed( nSize ); - if ( pCopy ) - memcpy( pCopy, string, nSize ); - return pCopy; -} - -#if 0 -_TSCHAR * __cdecl _tfullpath_dbg ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen, int nBlockUse, const char * szFileName, int nLine ) -{ - Assert(0); - return NULL; -} - -_TSCHAR * __cdecl _tfullpath ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen ) -{ - Assert(0); - return NULL; -} - -_TSCHAR * __cdecl _tgetdcwd_lk_dbg ( int drive, _TSCHAR *pnbuf, int maxlen, int nBlockUse, const char * szFileName, int nLine ) -{ - Assert(0); - return NULL; -} - -_TSCHAR * __cdecl _tgetdcwd_nolock ( int drive, _TSCHAR *pnbuf, int maxlen ) -{ - Assert(0); - return NULL; -} - -errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname, int nBlockUse, const char * szFileName, int nLine ) -{ - Assert(0); - return 0; -} - -errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname ) -{ - Assert(0); - return 0; -} - -_TSCHAR * __cdecl _ttempnam_dbg ( const _TSCHAR *dir, const _TSCHAR *pfx, int nBlockUse, const char * szFileName, int nLine ) -{ - Assert(0); - return 0; -} - -_TSCHAR * __cdecl _ttempnam ( const _TSCHAR *dir, const _TSCHAR *pfx ) -{ - Assert(0); - return 0; -} -#endif - -wchar_t * __cdecl _wcsdup_dbg ( const wchar_t * string, int nBlockUse, const char * szFileName, int nLine ) -{ - Assert(0); - return 0; -} - -wchar_t * __cdecl _wcsdup ( const wchar_t * string ) -{ - Assert(0); - return 0; -} - -} // end extern "C" - -#if _MSC_VER >= 1400 - -//----------------------------------------------------------------------------- -// XBox Memory Allocator Override -//----------------------------------------------------------------------------- -#if defined( _X360 ) -#if defined( _DEBUG ) || defined( USE_MEM_DEBUG ) -#include "UtlMap.h" - -MEMALLOC_DEFINE_EXTERNAL_TRACKING( XMem ); - -CThreadFastMutex g_XMemAllocMutex; - -void XMemAlloc_RegisterAllocation( void *p, DWORD dwAllocAttributes ) -{ - if ( !g_pMemAlloc ) - { - // core xallocs cannot be journaled until system is ready - return; - } - - AUTO_LOCK_FM( g_XMemAllocMutex ); - int size = XMemSize( p, dwAllocAttributes ); - MemAlloc_RegisterExternalAllocation( XMem, p, size ); -} - -void XMemAlloc_RegisterDeallocation( void *p, DWORD dwAllocAttributes ) -{ - if ( !g_pMemAlloc ) - { - // core xallocs cannot be journaled until system is ready - return; - } - - AUTO_LOCK_FM( g_XMemAllocMutex ); - int size = XMemSize( p, dwAllocAttributes ); - MemAlloc_RegisterExternalDeallocation( XMem, p, size ); -} - -#else - -#define XMemAlloc_RegisterAllocation( p, a ) ((void)0) -#define XMemAlloc_RegisterDeallocation( p, a ) ((void)0) - -#endif - -//----------------------------------------------------------------------------- -// XMemAlloc -// -// XBox Memory Allocator Override -//----------------------------------------------------------------------------- -LPVOID WINAPI XMemAlloc( SIZE_T dwSize, DWORD dwAllocAttributes ) -{ - LPVOID ptr; - XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes; - bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL ); - - if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI ) - { - MEM_ALLOC_CREDIT(); - switch ( pAttribs->dwAlignment ) - { - case XALLOC_ALIGNMENT_4: - ptr = g_pMemAlloc->Alloc( dwSize ); - break; - case XALLOC_ALIGNMENT_8: - ptr = MemAlloc_AllocAligned( dwSize, 8 ); - break; - case XALLOC_ALIGNMENT_DEFAULT: - case XALLOC_ALIGNMENT_16: - default: - ptr = MemAlloc_AllocAligned( dwSize, 16 ); - break; - } - if ( pAttribs->dwZeroInitialize != 0 ) - { - memset( ptr, 0, XMemSize( ptr, dwAllocAttributes ) ); - } - return ptr; - } - - ptr = XMemAllocDefault( dwSize, dwAllocAttributes ); - if ( ptr ) - { - XMemAlloc_RegisterAllocation( ptr, dwAllocAttributes ); - } - - return ptr; -} - -//----------------------------------------------------------------------------- -// XMemFree -// -// XBox Memory Allocator Override -//----------------------------------------------------------------------------- -VOID WINAPI XMemFree( PVOID pAddress, DWORD dwAllocAttributes ) -{ - if ( !pAddress ) - { - return; - } - - XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes; - bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL ); - - if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI ) - { - switch ( pAttribs->dwAlignment ) - { - case XALLOC_ALIGNMENT_4: - return g_pMemAlloc->Free( pAddress ); - default: - return MemAlloc_FreeAligned( pAddress ); - } - return; - } - - XMemAlloc_RegisterDeallocation( pAddress, dwAllocAttributes ); - - XMemFreeDefault( pAddress, dwAllocAttributes ); -} - -//----------------------------------------------------------------------------- -// XMemSize -// -// XBox Memory Allocator Override -//----------------------------------------------------------------------------- -SIZE_T WINAPI XMemSize( PVOID pAddress, DWORD dwAllocAttributes ) -{ - XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes; - bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL ); - - if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI ) - { - switch ( pAttribs->dwAlignment ) - { - case XALLOC_ALIGNMENT_4: - return g_pMemAlloc->GetSize( pAddress ); - default: - return MemAlloc_GetSizeAligned( pAddress ); - } - } - - return XMemSizeDefault( pAddress, dwAllocAttributes ); -} -#endif // _X360 - -#define MAX_LANG_LEN 64 /* max language name length */ -#define MAX_CTRY_LEN 64 /* max country name length */ -#define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */ -#define MAX_LC_LEN (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3) - -struct _is_ctype_compatible { - unsigned long id; - int is_clike; -}; -typedef struct setloc_struct { - /* getqloc static variables */ - char *pchLanguage; - char *pchCountry; - int iLcidState; - int iPrimaryLen; - BOOL bAbbrevLanguage; - BOOL bAbbrevCountry; - LCID lcidLanguage; - LCID lcidCountry; - /* expand_locale static variables */ - LC_ID _cacheid; - UINT _cachecp; - char _cachein[MAX_LC_LEN]; - char _cacheout[MAX_LC_LEN]; - /* _setlocale_set_cat (LC_CTYPE) static variable */ - struct _is_ctype_compatible _Lcid_c[5]; -} _setloc_struct, *_psetloc_struct; - -struct _tiddata { - unsigned long _tid; /* thread ID */ - - - uintptr_t _thandle; /* thread handle */ - - int _terrno; /* errno value */ - unsigned long _tdoserrno; /* _doserrno value */ - unsigned int _fpds; /* Floating Point data segment */ - unsigned long _holdrand; /* rand() seed value */ - char * _token; /* ptr to strtok() token */ - wchar_t * _wtoken; /* ptr to wcstok() token */ - unsigned char * _mtoken; /* ptr to _mbstok() token */ - - /* following pointers get malloc'd at runtime */ - char * _errmsg; /* ptr to strerror()/_strerror() buff */ - wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */ - char * _namebuf0; /* ptr to tmpnam() buffer */ - wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */ - char * _namebuf1; /* ptr to tmpfile() buffer */ - wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */ - char * _asctimebuf; /* ptr to asctime() buffer */ - wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */ - void * _gmtimebuf; /* ptr to gmtime() structure */ - char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */ - unsigned char _con_ch_buf[MB_LEN_MAX]; - /* ptr to putch() buffer */ - unsigned short _ch_buf_used; /* if the _con_ch_buf is used */ - - /* following fields are needed by _beginthread code */ - void * _initaddr; /* initial user thread address */ - void * _initarg; /* initial user thread argument */ - - /* following three fields are needed to support signal handling and - * runtime errors */ - void * _pxcptacttab; /* ptr to exception-action table */ - void * _tpxcptinfoptrs; /* ptr to exception info pointers */ - int _tfpecode; /* float point exception code */ - - /* pointer to the copy of the multibyte character information used by - * the thread */ - pthreadmbcinfo ptmbcinfo; - - /* pointer to the copy of the locale informaton used by the thead */ - pthreadlocinfo ptlocinfo; - int _ownlocale; /* if 1, this thread owns its own locale */ - - /* following field is needed by NLG routines */ - unsigned long _NLG_dwCode; - - /* - * Per-Thread data needed by C++ Exception Handling - */ - void * _terminate; /* terminate() routine */ - void * _unexpected; /* unexpected() routine */ - void * _translator; /* S.E. translator */ - void * _purecall; /* called when pure virtual happens */ - void * _curexception; /* current exception */ - void * _curcontext; /* current exception context */ - int _ProcessingThrow; /* for uncaught_exception */ - void * _curexcspec; /* for handling exceptions thrown from std::unexpected */ -#if defined (_M_IA64) || defined (_M_AMD64) - void * _pExitContext; - void * _pUnwindContext; - void * _pFrameInfoChain; - unsigned __int64 _ImageBase; -#if defined (_M_IA64) - unsigned __int64 _TargetGp; -#endif /* defined (_M_IA64) */ - unsigned __int64 _ThrowImageBase; - void * _pForeignException; -#elif defined (_M_IX86) - void * _pFrameInfoChain; -#endif /* defined (_M_IX86) */ - _setloc_struct _setloc_data; - - void * _encode_ptr; /* EncodePointer() routine */ - void * _decode_ptr; /* DecodePointer() routine */ - - void * _reserved1; /* nothing */ - void * _reserved2; /* nothing */ - void * _reserved3; /* nothing */ - - int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */ - - unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */ -}; - -typedef struct _tiddata * _ptiddata; - -class _LocaleUpdate -{ - _locale_tstruct localeinfo; - _ptiddata ptd; - bool updated; - public: - _LocaleUpdate(_locale_t plocinfo) - : updated(false) - { - /* - if (plocinfo == NULL) - { - ptd = _getptd(); - localeinfo.locinfo = ptd->ptlocinfo; - localeinfo.mbcinfo = ptd->ptmbcinfo; - - __UPDATE_LOCALE(ptd, localeinfo.locinfo); - __UPDATE_MBCP(ptd, localeinfo.mbcinfo); - if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT)) - { - ptd->_ownlocale |= _PER_THREAD_LOCALE_BIT; - updated = true; - } - } - else - { - localeinfo=*plocinfo; - } - */ - } - ~_LocaleUpdate() - { -// if (updated) -// ptd->_ownlocale = ptd->_ownlocale & ~_PER_THREAD_LOCALE_BIT; - } - _locale_t GetLocaleT() - { - return &localeinfo; - } -}; - - -#pragma warning(push) -#pragma warning(disable: 4483) -#if _MSC_FULL_VER >= 140050415 -#define _NATIVE_STARTUP_NAMESPACE __identifier("") -#else /* _MSC_FULL_VER >= 140050415 */ -#define _NATIVE_STARTUP_NAMESPACE __CrtImplementationDetails -#endif /* _MSC_FULL_VER >= 140050415 */ - -namespace _NATIVE_STARTUP_NAMESPACE -{ - class NativeDll - { - private: - static const unsigned int ProcessDetach = 0; - static const unsigned int ProcessAttach = 1; - static const unsigned int ThreadAttach = 2; - static const unsigned int ThreadDetach = 3; - static const unsigned int ProcessVerifier = 4; - - public: - - inline static bool IsInDllMain() - { - return false; - } - - inline static bool IsInProcessAttach() - { - return false; - } - - inline static bool IsInProcessDetach() - { - return false; - } - - inline static bool IsInVcclrit() - { - return false; - } - - inline static bool IsSafeForManagedCode() - { - if (!IsInDllMain()) - { - return true; - } - - if (IsInVcclrit()) - { - return true; - } - - return !IsInProcessAttach() && !IsInProcessDetach(); - } - }; -} -#pragma warning(pop) - -#endif // _MSC_VER >= 1400 - -#endif // !STEAM && !NO_MALLOC_OVERRIDE - -#endif // _WIN32 diff --git a/Resources/NetHook/tier0/minidump.h b/Resources/NetHook/tier0/minidump.h deleted file mode 100644 index fab59678..00000000 --- a/Resources/NetHook/tier0/minidump.h +++ /dev/null @@ -1,53 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef MINIDUMP_H -#define MINIDUMP_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/platform.h" - -// writes out a minidump of the current stack trace with a unique filename -PLATFORM_INTERFACE void WriteMiniDump(); - -typedef void (*FnWMain)( int , tchar *[] ); - -#if defined(_WIN32) && !defined(_X360) - -// calls the passed in function pointer and catches any exceptions/crashes thrown by it, and writes a minidump -// use from wmain() to protect the whole program - -PLATFORM_INTERFACE void CatchAndWriteMiniDump( FnWMain pfn, int argc, tchar *argv[] ); - -#include - -// Replaces the current function pointer with the one passed in. -// Returns the previously-set function. -// The function is called internally by WriteMiniDump() and CatchAndWriteMiniDump() -// The default is the built-in function that uses DbgHlp.dll's MiniDumpWriteDump function -typedef void (*FnMiniDump)( unsigned int uStructuredExceptionCode, _EXCEPTION_POINTERS * pExceptionInfo ); -PLATFORM_INTERFACE FnMiniDump SetMiniDumpFunction( FnMiniDump pfn ); - -// Use this to write a minidump explicitly. -// Some of the tools choose to catch the minidump themselves instead of using CatchAndWriteMinidump -// so they can show their own dialog. -// -// ptchMinidumpFileNameBuffer if not-NULL should be a writable tchar buffer of length at -// least _MAX_PATH and on return will contain the name of the minidump file written. -// If ptchMinidumpFileNameBuffer is NULL the name of the minidump file written will not -// be available after the function returns. -// -PLATFORM_INTERFACE bool WriteMiniDumpUsingExceptionInfo( - unsigned int uStructuredExceptionCode, - _EXCEPTION_POINTERS * pExceptionInfo, - MINIDUMP_TYPE minidumpType, - tchar *ptchMinidumpFileNameBuffer = NULL - ); -#endif - -#endif // MINIDUMP_H diff --git a/Resources/NetHook/tier0/platform.h b/Resources/NetHook/tier0/platform.h deleted file mode 100644 index 5640620a..00000000 --- a/Resources/NetHook/tier0/platform.h +++ /dev/null @@ -1,1168 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// - -#ifndef PLATFORM_H -#define PLATFORM_H - -#if defined( _X360 ) -#define NO_STEAM -#define NO_VOICE -// for the 360, the ppc platform and the rtos are tightly coupled -// setup the 360 environment here !once! for much less leaf module include wackiness -// these are critical order and purposely appear *before* anything else -#define _XBOX -#include -#include -#include -#include -#include -#include -#include -#undef _XBOX -#endif - -#include "wchartypes.h" -#include "basetypes.h" -#include "tier0/valve_off.h" - -#ifdef _WIN32 -#pragma once -#endif - -// feature enables -#define NEW_SOFTWARE_LIGHTING - -#ifdef _LINUX -// need this for _alloca -#include -#endif // _LINUX - -#include -#include - - -// need this for memset -#include - -#include "tier0/valve_minmax_on.h" // GCC 4.2.2 headers screw up our min/max defs. - -#ifdef _RETAIL -#define IsRetail() true -#else -#define IsRetail() false -#endif - -#ifdef _DEBUG -#define IsRelease() false -#define IsDebug() true -#else -#define IsRelease() true -#define IsDebug() false -#endif - -// Deprecating, infavor of IsX360() which will revert to IsXbox() -// after confidence of xbox 1 code flush -#define IsXbox() false - -#ifdef _WIN32 - #define IsLinux() false - #ifndef _X360 - #define IsPC() true - #define IsConsole() false - #define IsX360() false - #define IsPS3() false - #define IS_WINDOWS_PC - #else - #ifndef _CONSOLE - #define _CONSOLE - #endif - #define IsPC() false - #define IsConsole() true - #define IsX360() true - #define IsPS3() false - #endif -#elif defined(_LINUX) - #define IsPC() true - #define IsConsole() false - #define IsX360() false - #define IsPS3() false - #define IsLinux() true -#else - #error -#endif - -typedef unsigned char uint8; -typedef signed char int8; - -#ifdef __x86_64__ -#define X64BITS -#endif - -#if defined( _WIN32 ) - -typedef __int16 int16; -typedef unsigned __int16 uint16; -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; - -#ifdef X64BITS -typedef __int64 intp; // intp is an integer that can accomodate a pointer -typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *) -#else -typedef __int32 intp; -typedef unsigned __int32 uintp; -#endif - -#if defined( _X360 ) -#ifdef __m128 - #undef __m128 -#endif -#define __m128 __vector4 -#endif - -#else // _WIN32 - -typedef short int16; -typedef unsigned short uint16; -typedef int int32; -typedef unsigned int uint32; -typedef long long int64; -typedef unsigned long long uint64; -#ifdef X64BITS -typedef long long intp; -typedef unsigned long long uintp; -#else -typedef int intp; -typedef unsigned int uintp; -#endif - -#endif // else _WIN32 - - -typedef float float32; -typedef double float64; - -// for when we don't care about how many bits we use -typedef unsigned int uint; - -// This can be used to ensure the size of pointers to members when declaring -// a pointer type for a class that has only been forward declared -#ifdef _MSC_VER -#define SINGLE_INHERITANCE __single_inheritance -#define MULTIPLE_INHERITANCE __multiple_inheritance -#else -#define SINGLE_INHERITANCE -#define MULTIPLE_INHERITANCE -#endif - -#ifdef _MSC_VER -#define NO_VTABLE __declspec( novtable ) -#else -#define NO_VTABLE -#endif - -// This can be used to declare an abstract (interface only) class. -// Classes marked abstract should not be instantiated. If they are, and access violation will occur. -// -// Example of use: -// -// abstract_class CFoo -// { -// ... -// } -// -// MSDN __declspec(novtable) documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_novtable.asp -// -// Note: NJS: This is not enabled for regular PC, due to not knowing the implications of exporting a class with no no vtable. -// It's probable that this shouldn't be an issue, but an experiment should be done to verify this. -// -#ifndef _X360 -#define abstract_class class -#else -#define abstract_class class NO_VTABLE -#endif - -/* -FIXME: Enable this when we no longer fear change =) - -// need these for the limits -#include -#include - -// Maximum and minimum representable values -#define INT8_MAX SCHAR_MAX -#define INT16_MAX SHRT_MAX -#define INT32_MAX LONG_MAX -#define INT64_MAX (((int64)~0) >> 1) - -#define INT8_MIN SCHAR_MIN -#define INT16_MIN SHRT_MIN -#define INT32_MIN LONG_MIN -#define INT64_MIN (((int64)1) << 63) - -#define UINT8_MAX ((uint8)~0) -#define UINT16_MAX ((uint16)~0) -#define UINT32_MAX ((uint32)~0) -#define UINT64_MAX ((uint64)~0) - -#define UINT8_MIN 0 -#define UINT16_MIN 0 -#define UINT32_MIN 0 -#define UINT64_MIN 0 - -#ifndef UINT_MIN -#define UINT_MIN UINT32_MIN -#endif - -#define FLOAT32_MAX FLT_MAX -#define FLOAT64_MAX DBL_MAX - -#define FLOAT32_MIN FLT_MIN -#define FLOAT64_MIN DBL_MIN -*/ - -// portability / compiler settings -#if defined(_WIN32) && !defined(WINDED) - -#if defined(_M_IX86) -#define __i386__ 1 -#endif - -#elif _LINUX -typedef unsigned int DWORD; -typedef unsigned short WORD; -typedef void * HINSTANCE; -#define _MAX_PATH PATH_MAX -#endif // defined(_WIN32) && !defined(WINDED) - - -// Defines MAX_PATH -#ifndef MAX_PATH -#define MAX_PATH 260 -#endif - -#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression - -// Used to step into the debugger -#if defined( _WIN32 ) && !defined( _X360 ) -#define DebuggerBreak() __asm { int 3 } -#elif defined( _X360 ) -#define DebuggerBreak() DebugBreak() -#else -#define DebuggerBreak() {} -#endif -#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() - -// C functions for external declarations that call the appropriate C++ methods -#ifndef EXPORT - #ifdef _WIN32 - #define EXPORT _declspec( dllexport ) - #else - #define EXPORT /* */ - #endif -#endif - -#if defined __i386__ && !defined __linux__ - #define id386 1 -#else - #define id386 0 -#endif // __i386__ - -// decls for aligning data -#ifdef _WIN32 - #define DECL_ALIGN(x) __declspec(align(x)) - -#elif _LINUX - #define DECL_ALIGN(x) __attribute__((aligned(x))) -#elif - #define DECL_ALIGN(x) /* */ -#endif - -#define ALIGN8 DECL_ALIGN(8) -#define ALIGN16 DECL_ALIGN(16) -#define ALIGN32 DECL_ALIGN(32) -#define ALIGN128 DECL_ALIGN(128) - - -// Linux had a few areas where it didn't construct objects in the same order that Windows does. -// So when CVProfile::CVProfile() would access g_pMemAlloc, it would crash because the allocator wasn't initalized yet. -#ifdef _LINUX - #define CONSTRUCT_EARLY __attribute__((init_priority(101))) -#else - #define CONSTRUCT_EARLY -#endif - -#ifdef _WIN32 - #define SELECTANY __declspec(selectany) -#elif _LINUX - #define SELECTANY __attribute__((weak)) -#else - #define SELECTANY static -#endif - -#if defined( _WIN32 ) - -// Used for dll exporting and importing -#define DLL_EXPORT extern "C" __declspec( dllexport ) -#define DLL_IMPORT extern "C" __declspec( dllimport ) - -// Can't use extern "C" when DLL exporting a class -#define DLL_CLASS_EXPORT __declspec( dllexport ) -#define DLL_CLASS_IMPORT __declspec( dllimport ) - -// Can't use extern "C" when DLL exporting a global -#define DLL_GLOBAL_EXPORT extern __declspec( dllexport ) -#define DLL_GLOBAL_IMPORT extern __declspec( dllimport ) - -#elif defined _LINUX -// Used for dll exporting and importing -#define DLL_EXPORT extern "C" __attribute__ ((visibility("default"))) -#define DLL_IMPORT extern "C" - -// Can't use extern "C" when DLL exporting a class -#define DLL_CLASS_EXPORT __attribute__ ((visibility("default"))) -#define DLL_CLASS_IMPORT - -// Can't use extern "C" when DLL exporting a global -#define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default"))) -#define DLL_GLOBAL_IMPORT extern - -#else -#error "Unsupported Platform." -#endif - -// Used for standard calling conventions -#if defined( _WIN32 ) && !defined( _X360 ) - #define STDCALL __stdcall - #define FASTCALL __fastcall - #define FORCEINLINE __forceinline - // GCC 3.4.1 has a bug in supporting forced inline of templated functions - // this macro lets us not force inlining in that case - #define FORCEINLINE_TEMPLATE __forceinline -#elif defined( _X360 ) - #define STDCALL __stdcall - #ifdef FORCEINLINE - #undef FORCEINLINE - #endif - #define FORCEINLINE __forceinline - #define FORCEINLINE_TEMPLATE __forceinline -#else - #define STDCALL - #define FASTCALL - #ifdef _LINUX_DEBUGGABLE - #define FORCEINLINE - #else - #define FORCEINLINE inline - #endif - // GCC 3.4.1 has a bug in supporting forced inline of templated functions - // this macro lets us not force inlining in that case - #define FORCEINLINE_TEMPLATE inline - #define __stdcall __attribute__ ((__stdcall__)) -#endif - -// Force a function call site -not- to inlined. (useful for profiling) -#define DONT_INLINE(a) (((int)(a)+1)?(a):(a)) - -// Pass hints to the compiler to prevent it from generating unnessecary / stupid code -// in certain situations. Several compilers other than MSVC also have an equivilent -// construct. -// -// Essentially the 'Hint' is that the condition specified is assumed to be true at -// that point in the compilation. If '0' is passed, then the compiler assumes that -// any subsequent code in the same 'basic block' is unreachable, and thus usually -// removed. -#ifdef _MSC_VER - #define HINT(THE_HINT) __assume((THE_HINT)) -#else - #define HINT(THE_HINT) 0 -#endif - -// Marks the codepath from here until the next branch entry point as unreachable, -// and asserts if any attempt is made to execute it. -#define UNREACHABLE() { Assert(0); HINT(0); } - -// In cases where no default is present or appropriate, this causes MSVC to generate -// as little code as possible, and throw an assertion in debug. -#define NO_DEFAULT default: UNREACHABLE(); - -#ifdef _WIN32 -// Alloca defined for this platform -#define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) ) -#define stackfree( _p ) 0 -#elif _LINUX -// Alloca defined for this platform -#define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) ) -#define stackfree( _p ) 0 -#endif - -#ifdef _WIN32 -#define RESTRICT __restrict -#define RESTRICT_FUNC __declspec(restrict) -#else -#define RESTRICT -#define RESTRICT_FUNC -#endif - - -#ifdef _WIN32 -// Remove warnings from warning level 4. -#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed -#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter -#pragma warning(disable : 4127) // warning C4127: conditional expression is constant -#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated -#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable -#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined -#pragma warning(disable : 4702) // warning C4702: unreachable code -#pragma warning(disable : 4505) // unreferenced local function has been removed -#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& ) -#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex' -#pragma warning(disable : 4324) // Padding was added at the end of a structure -#pragma warning(disable : 4244) // type conversion warning. -#pragma warning(disable : 4305) // truncation from 'const double ' to 'float ' -#pragma warning(disable : 4786) // Disable warnings about long symbol names -#pragma warning(disable : 4250) // 'X' : inherits 'Y::Z' via dominance -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union - -#if _MSC_VER >= 1300 -#pragma warning(disable : 4511) // Disable warnings about private copy constructors -#pragma warning(disable : 4121) // warning C4121: 'symbol' : alignment of a member was sensitive to packing -#pragma warning(disable : 4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc (disabled due to std headers having exception syntax) -#endif - -#if _MSC_VER >= 1400 -#pragma warning(disable : 4996) // functions declared deprecated -#endif - - -#endif - -// When we port to 64 bit, we'll have to resolve the int, ptr vs size_t 32/64 bit problems... -#if !defined( _WIN64 ) -#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data -#pragma warning( disable : 4311 ) // pointer truncation from 'char *' to 'int' -#pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size -#endif - - -//----------------------------------------------------------------------------- -// fsel -//----------------------------------------------------------------------------- -#ifndef _X360 - -static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} -static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} - -#else - -// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT -// this is much faster than if ( aFloat > 0 ) { x = .. } -#define fsel __fsel - -#endif - - -//----------------------------------------------------------------------------- -// FP exception handling -//----------------------------------------------------------------------------- -//#define CHECK_FLOAT_EXCEPTIONS 1 - -#if !defined( _X360 ) -#if defined( _MSC_VER ) - -inline void SetupFPUControlWordForceExceptions() -{ - // use local to get and store control word - uint16 tmpCtrlW; - __asm - { - fnclex /* clear all current exceptions */ - fnstcw word ptr [tmpCtrlW] /* get current control word */ - and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */ - or [tmpCtrlW], 0230h /* set to 53-bit, mask only inexact, underflow */ - fldcw word ptr [tmpCtrlW] /* put new control word in FPU */ - } -} - -#ifdef CHECK_FLOAT_EXCEPTIONS - -inline void SetupFPUControlWord() -{ - SetupFPUControlWordForceExceptions(); -} - -#else - -inline void SetupFPUControlWord() -{ - // use local to get and store control word - uint16 tmpCtrlW; - __asm - { - fnstcw word ptr [tmpCtrlW] /* get current control word */ - and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */ - or [tmpCtrlW], 023Fh /* set to 53-bit, mask only inexact, underflow */ - fldcw word ptr [tmpCtrlW] /* put new control word in FPU */ - } -} - -#endif - -#else - -inline void SetupFPUControlWord() -{ - __volatile unsigned short int __cw; - __asm __volatile ("fnstcw %0" : "=m" (__cw)); - __cw = __cw & 0x0FCC0; // keep infinity control, keep rounding mode - __cw = __cw | 0x023F; // set 53-bit, no exceptions - __asm __volatile ("fldcw %0" : : "m" (__cw)); -} - -#endif // _MSC_VER - -#else - -#ifdef _DEBUG -FORCEINLINE bool IsFPUControlWordSet() -{ - float f = 0.996f; - union - { - double flResult; - int pResult[2]; - }; - flResult = __fctiw( f ); - return ( pResult[1] == 1 ); -} -#endif - -inline void SetupFPUControlWord() -{ - // Set round-to-nearest in FPSCR - // (cannot assemble, must use op-code form) - __emit( 0xFF80010C ); // mtfsfi 7,0 - - // Favour compatibility over speed (make sure the VPU set to Java-compliant mode) - // NOTE: the VPU *always* uses round-to-nearest - __vector4 a = { 0.0f, 0.0f, 0.0f, 0.0f }; - a; // Avoid compiler warning - __asm - { - mtvscr a; // Clear the Vector Status & Control Register to zero - } -} - -#endif // _X360 - -//----------------------------------------------------------------------------- -// Purpose: Standard functions for handling endian-ness -//----------------------------------------------------------------------------- - -//------------------------------------- -// Basic swaps -//------------------------------------- - -template -inline T WordSwapC( T w ) -{ - uint16 temp; - - temp = ((*((uint16 *)&w) & 0xff00) >> 8); - temp |= ((*((uint16 *)&w) & 0x00ff) << 8); - - return *((T*)&temp); -} - -template -inline T DWordSwapC( T dw ) -{ - uint32 temp; - - temp = *((uint32 *)&dw) >> 24; - temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8); - temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8); - temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24); - - return *((T*)&temp); -} - -//------------------------------------- -// Fast swaps -//------------------------------------- - -#if defined( _X360 ) - -#define WordSwap WordSwap360Intr -#define DWordSwap DWordSwap360Intr - -template -inline T WordSwap360Intr( T w ) -{ - T output; - __storeshortbytereverse( w, 0, &output ); - return output; -} - -template -inline T DWordSwap360Intr( T dw ) -{ - T output; - __storewordbytereverse( dw, 0, &output ); - return output; -} - -#elif defined( _MSC_VER ) - -#define WordSwap WordSwapAsm -#define DWordSwap DWordSwapAsm - -#pragma warning(push) -#pragma warning (disable:4035) // no return value - -template -inline T WordSwapAsm( T w ) -{ - __asm - { - mov ax, w - xchg al, ah - } -} - -template -inline T DWordSwapAsm( T dw ) -{ - __asm - { - mov eax, dw - bswap eax - } -} - -#pragma warning(pop) - -#else - -#define WordSwap WordSwapC -#define DWordSwap DWordSwapC - -#endif - -//------------------------------------- -// The typically used methods. -//------------------------------------- - -#if defined(__i386__) -#define LITTLE_ENDIAN 1 -#endif - -#if defined( _SGI_SOURCE ) || defined( _X360 ) -#define BIG_ENDIAN 1 -#endif - -// If a swapped float passes through the fpu, the bytes may get changed. -// Prevent this by swapping floats as DWORDs. -#define SafeSwapFloat( pOut, pIn ) (*((uint*)pOut) = DWordSwap( *((uint*)pIn) )) - -#if defined(LITTLE_ENDIAN) - -#define BigShort( val ) WordSwap( val ) -#define BigWord( val ) WordSwap( val ) -#define BigLong( val ) DWordSwap( val ) -#define BigDWord( val ) DWordSwap( val ) -#define LittleShort( val ) ( val ) -#define LittleWord( val ) ( val ) -#define LittleLong( val ) ( val ) -#define LittleDWord( val ) ( val ) -#define SwapShort( val ) BigShort( val ) -#define SwapWord( val ) BigWord( val ) -#define SwapLong( val ) BigLong( val ) -#define SwapDWord( val ) BigDWord( val ) - -// Pass floats by pointer for swapping to avoid truncation in the fpu -#define BigFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn ) -#define LittleFloat( pOut, pIn ) ( *pOut = *pIn ) -#define SwapFloat( pOut, pIn ) BigFloat( pOut, pIn ) - -#elif defined(BIG_ENDIAN) - -#define BigShort( val ) ( val ) -#define BigWord( val ) ( val ) -#define BigLong( val ) ( val ) -#define BigDWord( val ) ( val ) -#define LittleShort( val ) WordSwap( val ) -#define LittleWord( val ) WordSwap( val ) -#define LittleLong( val ) DWordSwap( val ) -#define LittleDWord( val ) DWordSwap( val ) -#define SwapShort( val ) LittleShort( val ) -#define SwapWord( val ) LittleWord( val ) -#define SwapLong( val ) LittleLong( val ) -#define SwapDWord( val ) LittleDWord( val ) - -// Pass floats by pointer for swapping to avoid truncation in the fpu -#define BigFloat( pOut, pIn ) ( *pOut = *pIn ) -#define LittleFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn ) -#define SwapFloat( pOut, pIn ) LittleFloat( pOut, pIn ) - -#else - -// @Note (toml 05-02-02): this technique expects the compiler to -// optimize the expression and eliminate the other path. On any new -// platform/compiler this should be tested. -inline short BigShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; } -inline uint16 BigWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; } -inline long BigLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; } -inline uint32 BigDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; } -inline short LittleShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); } -inline uint16 LittleWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); } -inline long LittleLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); } -inline uint32 LittleDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); } -inline short SwapShort( short val ) { return WordSwap( val ); } -inline uint16 SwapWord( uint16 val ) { return WordSwap( val ); } -inline long SwapLong( long val ) { return DWordSwap( val ); } -inline uint32 SwapDWord( uint32 val ) { return DWordSwap( val ); } - -// Pass floats by pointer for swapping to avoid truncation in the fpu -inline void BigFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? SafeSwapFloat( pOut, pIn ) : ( *pOut = *pIn ); } -inline void LittleFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? ( *pOut = *pIn ) : SafeSwapFloat( pOut, pIn ); } -inline void SwapFloat( float *pOut, const float *pIn ) { SafeSwapFloat( pOut, pIn ); } - -#endif - -#if _X360 -inline unsigned long LoadLittleDWord( unsigned long *base, unsigned int dwordIndex ) -{ - return __loadwordbytereverse( dwordIndex<<2, base ); -} - -inline void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword ) -{ - __storewordbytereverse( dword, dwordIndex<<2, base ); -} -#else -inline unsigned long LoadLittleDWord( unsigned long *base, unsigned int dwordIndex ) -{ - return LittleDWord( base[dwordIndex] ); -} - -inline void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword ) -{ - base[dwordIndex] = LittleDWord(dword); -} -#endif - - -#ifndef STATIC_TIER0 - -#ifdef TIER0_DLL_EXPORT - #define PLATFORM_INTERFACE DLL_EXPORT - #define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT -#else - #define PLATFORM_INTERFACE DLL_IMPORT - #define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT -#endif - -#else // BUILD_AS_DLL - -#define PLATFORM_INTERFACE extern -#define PLATFORM_OVERLOAD - -#endif // BUILD_AS_DLL - - -// When in benchmark mode, the timer returns a simple incremented value each time you call it. -// -// It should not be changed after startup unless you really know what you're doing. The only place -// that should do this is the benchmark code itself so it can output a legit duration. -PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode ); -PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); - - -PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded. -PLATFORM_INTERFACE unsigned long Plat_MSTime(); // Time in milliseconds. - -// b/w compatibility -#define Sys_FloatTime Plat_FloatTime - - -// Processor Information: -struct CPUInformation -{ - int m_Size; // Size of this structure, for forward compatability. - - bool m_bRDTSC : 1, // Is RDTSC supported? - m_bCMOV : 1, // Is CMOV supported? - m_bFCMOV : 1, // Is FCMOV supported? - m_bSSE : 1, // Is SSE supported? - m_bSSE2 : 1, // Is SSE2 Supported? - m_b3DNow : 1, // Is 3DNow! Supported? - m_bMMX : 1, // Is MMX supported? - m_bHT : 1; // Is HyperThreading supported? - - uint8 m_nLogicalProcessors; // Number op logical processors. - uint8 m_nPhysicalProcessors; // Number of physical processors - - int64 m_Speed; // In cycles per second. - - tchar* m_szProcessorID; // Processor vendor Identification. -}; - -PLATFORM_INTERFACE const CPUInformation& GetCPUInformation(); - -PLATFORM_INTERFACE void GetCurrentDate( int *pDay, int *pMonth, int *pYear ); - -// ---------------------------------------------------------------------------------- // -// Performance Monitoring Events - L2 stats etc... -// ---------------------------------------------------------------------------------- // -PLATFORM_INTERFACE void InitPME(); -PLATFORM_INTERFACE void ShutdownPME(); - -//----------------------------------------------------------------------------- -// Thread related functions -//----------------------------------------------------------------------------- -// Registers the current thread with Tier0's thread management system. -// This should be called on every thread created in the game. -PLATFORM_INTERFACE unsigned long Plat_RegisterThread( const tchar *pName = _T("Source Thread")); - -// Registers the current thread as the primary thread. -PLATFORM_INTERFACE unsigned long Plat_RegisterPrimaryThread(); - -// VC-specific. Sets the thread's name so it has a friendly name in the debugger. -// This should generally only be handled by Plat_RegisterThread and Plat_RegisterPrimaryThread -PLATFORM_INTERFACE void Plat_SetThreadName( unsigned long dwThreadID, const tchar *pName ); - -// These would be private if it were possible to export private variables from a .DLL. -// They need to be variables because they are checked by inline functions at performance -// critical places. -PLATFORM_INTERFACE unsigned long Plat_PrimaryThreadID; - -// Returns the ID of the currently executing thread. -PLATFORM_INTERFACE unsigned long Plat_GetCurrentThreadID(); - -// Returns the ID of the primary thread. -inline unsigned long Plat_GetPrimaryThreadID() -{ - return Plat_PrimaryThreadID; -} - -// Returns true if the current thread is the primary thread. -inline bool Plat_IsPrimaryThread() -{ - //return true; - return (Plat_GetPrimaryThreadID() == Plat_GetCurrentThreadID() ); -} - -//----------------------------------------------------------------------------- -// Process related functions -//----------------------------------------------------------------------------- -PLATFORM_INTERFACE const tchar *Plat_GetCommandLine(); -#ifndef _WIN32 -// helper function for OS's that don't have a ::GetCommandLine() call -PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine ); -#endif -PLATFORM_INTERFACE const char *Plat_GetCommandLineA(); - -//----------------------------------------------------------------------------- -// Security related functions -//----------------------------------------------------------------------------- -// Ensure that the hardware key's drivers have been installed. -PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver(); - -// Ok, so this isn't a very secure way to verify the hardware key for now. It -// is primarially depending on the fact that all the binaries have been wrapped -// with the secure wrapper provided by the hardware keys vendor. -PLATFORM_INTERFACE bool Plat_VerifyHardwareKey(); - -// The same as above, but notifies user with a message box when the key isn't in -// and gives him an opportunity to correct the situation. -PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt(); - -// Can be called in real time, doesn't perform the verify every frame. Mainly just -// here to allow the game to drop out quickly when the key is removed, rather than -// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't -// like much. -PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey(); - -//----------------------------------------------------------------------------- -// Just logs file and line to simple.log -//----------------------------------------------------------------------------- -PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line ); - -//----------------------------------------------------------------------------- -// Returns true if debugger attached, false otherwise -//----------------------------------------------------------------------------- -#if defined(_WIN32) -PLATFORM_INTERFACE bool Plat_IsInDebugSession(); -PLATFORM_INTERFACE void Plat_DebugString( const char * ); -#else -#define Plat_IsInDebugSession() (false) -#define Plat_DebugString(s) ((void)0) -#endif - -//----------------------------------------------------------------------------- -// XBOX Components valid in PC compilation space -//----------------------------------------------------------------------------- - -#define XBOX_DVD_SECTORSIZE 2048 -#define XBOX_DVD_ECC_SIZE 32768 // driver reads in quantum ECC blocks -#define XBOX_HDD_SECTORSIZE 512 - -// Custom windows messages for Xbox input -#define WM_XREMOTECOMMAND (WM_USER + 100) -#define WM_XCONTROLLER_KEY (WM_USER + 101) -#define WM_SYS_UI (WM_USER + 102) -#define WM_SYS_SIGNINCHANGED (WM_USER + 103) -#define WM_SYS_STORAGEDEVICESCHANGED (WM_USER + 104) -#define WM_SYS_PROFILESETTINGCHANGED (WM_USER + 105) -#define WM_SYS_MUTELISTCHANGED (WM_USER + 106) -#define WM_SYS_INPUTDEVICESCHANGED (WM_USER + 107) -#define WM_SYS_INPUTDEVICECONFIGCHANGED (WM_USER + 108) -#define WM_LIVE_CONNECTIONCHANGED (WM_USER + 109) -#define WM_LIVE_INVITE_ACCEPTED (WM_USER + 110) -#define WM_LIVE_LINK_STATE_CHANGED (WM_USER + 111) -#define WM_LIVE_CONTENT_INSTALLED (WM_USER + 112) -#define WM_LIVE_MEMBERSHIP_PURCHASED (WM_USER + 113) -#define WM_LIVE_VOICECHAT_AWAY (WM_USER + 114) -#define WM_LIVE_PRESENCE_CHANGED (WM_USER + 115) -#define WM_FRIENDS_PRESENCE_CHANGED (WM_USER + 116) -#define WM_FRIENDS_FRIEND_ADDED (WM_USER + 117) -#define WM_FRIENDS_FRIEND_REMOVED (WM_USER + 118) -#define WM_CUSTOM_GAMEBANNERPRESSED (WM_USER + 119) -#define WM_CUSTOM_ACTIONPRESSED (WM_USER + 120) -#define WM_XMP_STATECHANGED (WM_USER + 121) -#define WM_XMP_PLAYBACKBEHAVIORCHANGED (WM_USER + 122) -#define WM_XMP_PLAYBACKCONTROLLERCHANGED (WM_USER + 123) - -inline const char *GetPlatformExt( void ) -{ - return IsX360() ? ".360" : ""; -} - -// flat view, 6 hw threads -#define XBOX_PROCESSOR_0 ( 1<<0 ) -#define XBOX_PROCESSOR_1 ( 1<<1 ) -#define XBOX_PROCESSOR_2 ( 1<<2 ) -#define XBOX_PROCESSOR_3 ( 1<<3 ) -#define XBOX_PROCESSOR_4 ( 1<<4 ) -#define XBOX_PROCESSOR_5 ( 1<<5 ) - -// core view, 3 cores with 2 hw threads each -#define XBOX_CORE_0_HWTHREAD_0 XBOX_PROCESSOR_0 -#define XBOX_CORE_0_HWTHREAD_1 XBOX_PROCESSOR_1 -#define XBOX_CORE_1_HWTHREAD_0 XBOX_PROCESSOR_2 -#define XBOX_CORE_1_HWTHREAD_1 XBOX_PROCESSOR_3 -#define XBOX_CORE_2_HWTHREAD_0 XBOX_PROCESSOR_4 -#define XBOX_CORE_2_HWTHREAD_1 XBOX_PROCESSOR_5 - -//----------------------------------------------------------------------------- -// Include additional dependant header components. -//----------------------------------------------------------------------------- -#include "tier0/fasttimer.h" - -#if defined( _X360 ) -#include "xbox/xbox_core.h" -#endif - -//----------------------------------------------------------------------------- -// Methods to invoke the constructor, copy constructor, and destructor -//----------------------------------------------------------------------------- - -template -inline void Construct( T* pMemory ) -{ - ::new( pMemory ) T; -} - -template -inline void CopyConstruct( T* pMemory, T const& src ) -{ - ::new( pMemory ) T(src); -} - -template -inline void Destruct( T* pMemory ) -{ - pMemory->~T(); - -#ifdef _DEBUG - memset( pMemory, 0xDD, sizeof(T) ); -#endif -} - - -// -// GET_OUTER() -// -// A platform-independent way for a contained class to get a pointer to its -// owner. If you know a class is exclusively used in the context of some -// "outer" class, this is a much more space efficient way to get at the outer -// class than having the inner class store a pointer to it. -// -// class COuter -// { -// class CInner // Note: this does not need to be a nested class to work -// { -// void PrintAddressOfOuter() -// { -// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) ); -// } -// }; -// -// CInner m_Inner; -// friend class CInner; -// }; - -#define GET_OUTER( OuterType, OuterMember ) \ - ( ( OuterType * ) ( (uint8 *)this - offsetof( OuterType, OuterMember ) ) ) - - -/* TEMPLATE_FUNCTION_TABLE() - - (Note added to platform.h so platforms that correctly support templated - functions can handle portions as templated functions rather than wrapped - functions) - - Helps automate the process of creating an array of function - templates that are all specialized by a single integer. - This sort of thing is often useful in optimization work. - - For example, using TEMPLATE_FUNCTION_TABLE, this: - - TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10) - { - return argument * argument; - } - - is equivilent to the following: - - (NOTE: the function has to be wrapped in a class due to code - generation bugs involved with directly specializing a function - based on a constant.) - - template - class FunctionWrapper - { - public: - int Function( int blah, int blah ) - { - return argument*argument; - } - } - - typedef int (*FunctionType)( int blah, int blah ); - - class FunctionName - { - public: - enum { count = 10 }; - FunctionType functions[10]; - }; - - FunctionType FunctionName::functions[] = - { - FunctionWrapper<0>::Function, - FunctionWrapper<1>::Function, - FunctionWrapper<2>::Function, - FunctionWrapper<3>::Function, - FunctionWrapper<4>::Function, - FunctionWrapper<5>::Function, - FunctionWrapper<6>::Function, - FunctionWrapper<7>::Function, - FunctionWrapper<8>::Function, - FunctionWrapper<9>::Function - }; -*/ - -PLATFORM_INTERFACE bool vtune( bool resume ); - - -#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \ - \ -typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \ - \ -template \ -struct __Function_##NAME \ -{ \ - static RETURN_TYPE FASTCALL Run ARGS; \ -}; \ - \ -template \ -struct __MetaLooper_##NAME : __MetaLooper_##NAME \ -{ \ - __Type_##NAME func; \ - inline __MetaLooper_##NAME() { func = __Function_##NAME::Run; } \ -}; \ - \ -template<> \ -struct __MetaLooper_##NAME<0> \ -{ \ - __Type_##NAME func; \ - inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \ -}; \ - \ -class NAME \ -{ \ -private: \ - static const __MetaLooper_##NAME m; \ -public: \ - enum { count = COUNT }; \ - static const __Type_##NAME* functions; \ -}; \ -const __MetaLooper_##NAME NAME::m; \ -const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \ -template \ -RETURN_TYPE FASTCALL __Function_##NAME::Run ARGS - - -#define LOOP_INTERCHANGE(BOOLEAN, CODE)\ - if( (BOOLEAN) )\ - {\ - CODE;\ - } else\ - {\ - CODE;\ - } - -//----------------------------------------------------------------------------- - -#if defined(_INC_WINDOWS) && defined(_WIN32) -template -class CDynamicFunction -{ -public: - CDynamicFunction( const char *pszModule, const char *pszName, FUNCPTR_TYPE pfnFallback = NULL ) - { - m_pfn = pfnFallback; - - HMODULE hModule = ::LoadLibrary( pszModule ); - if ( hModule ) - m_pfn = (FUNCPTR_TYPE)::GetProcAddress( hModule, pszName ); - } - - operator bool() { return m_pfn != NULL; } - bool operator !() { return !m_pfn; } - operator FUNCPTR_TYPE() { return m_pfn; } - -private: - FUNCPTR_TYPE m_pfn; -}; -#endif - -//----------------------------------------------------------------------------- - -#include "tier0/valve_on.h" - -#endif /* PLATFORM_H */ diff --git a/Resources/NetHook/tier0/pmc360.h b/Resources/NetHook/tier0/pmc360.h deleted file mode 100644 index 4c99cd63..00000000 --- a/Resources/NetHook/tier0/pmc360.h +++ /dev/null @@ -1,73 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Analogous to l2cache.h, this class represents information gleaned -// from the 360's Performance Monitor Counters. In particular we -// are interested in l2 cache misses and load-hit-stores. -// -//=============================================================================// -#ifndef CPMCDATA_H -#define CPMCDATA_H -#ifdef _WIN32 -#pragma once -#endif - -#ifndef _X360 -#error This file must only be compiled for XBOX360! -#endif - - -// Warning: -// As written, this class only supports profiling thread 0, processor 0. - -class CPMCData -{ -public: - - CPMCData(); - ~CPMCData() {}; - - void Start( void ); - void End( void ); - - /// This function should be called exactly once during the lifespan of the program; - /// it will set up the counters to record the information we are interested in. - /// This will stomp on whoever else might have set the performance counters elsewhere - /// in the game. - static void InitializeOnceProgramWide( void ); - static bool IsInitialized(); - - //------------------------------------------------------------------------- - // GetL2CacheMisses - //------------------------------------------------------------------------- - uint64 GetL2CacheMisses( void ) const - { - return m_Delta.L2CacheMiss; - } - - uint64 GetLHS( void ) const - { - return m_Delta.LHS; - } - -/* -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE -*/ - -private: - /// represents saved numbers from the counters we are interested in - struct PMCounters - { - uint64 L2CacheMiss; - uint64 LHS; ///< load hit store - - PMCounters(int64 _l2cm, int64 _lhs ) : L2CacheMiss(_l2cm), LHS(_lhs) {}; - PMCounters() : L2CacheMiss(0), LHS(0) {}; - }; - - PMCounters m_OnStart; ///< values when we began the timer - PMCounters m_Delta ; ///< computed total delta between start/stop -}; - -#endif // CPMCDATA_H \ No newline at end of file diff --git a/Resources/NetHook/tier0/progressbar.h b/Resources/NetHook/tier0/progressbar.h deleted file mode 100644 index a58ca1f5..00000000 --- a/Resources/NetHook/tier0/progressbar.h +++ /dev/null @@ -1,23 +0,0 @@ -//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// -// -// Purpose: Provide a shared place for library fucntions to report progress % for display -// -//=============================================================================// - -#ifndef PROGRESSBAR_H -#define PROGRESSBAR_H -#ifdef _WIN32 -#pragma once -#endif - - -PLATFORM_INTERFACE void ReportProgress(char const *job_name, int total_units_to_do, - int n_units_completed); - -typedef void (*ProgressReportHandler_t)( char const*, int, int ); - -// install your own handler. returns previous handler -PLATFORM_INTERFACE ProgressReportHandler_t InstallProgressReportHandler( ProgressReportHandler_t pfn); - - -#endif diff --git a/Resources/NetHook/tier0/protected_things.h b/Resources/NetHook/tier0/protected_things.h deleted file mode 100644 index 0445503c..00000000 --- a/Resources/NetHook/tier0/protected_things.h +++ /dev/null @@ -1,284 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef PROTECTED_THINGS_H -#define PROTECTED_THINGS_H -#ifdef _WIN32 -#pragma once -#endif - - -// This header tries to prevent people from using potentially dangerous functions -// (like the notorious non-null-terminating strncpy) and functions that will break -// VCR mode (like time, input, registry, etc). -// -// This header should be included by ALL of our source code. - -// Eventually, ALL of these should be protected, but one man can only accomplish so much in -// one day AND work on features too! -#if defined( PROTECTED_STRINGS_ENABLE ) - - #if defined( printf ) - #undef printf - #endif - #define printf printf__HEY_YOU__USE_VSTDLIB - - #if defined( wprintf ) - #undef wprintf - #endif - #define wprintf wprintf__HEY_YOU__USE_VSTDLIB - - #if defined( strcmp ) - #undef strcmp - #endif - #define strcmp strcmp__HEY_YOU__USE_VSTDLIB - - #if defined( wcscmp ) - #undef wcscmp - #endif - #define wcscmp wcscmp__HEY_YOU__USE_VSTDLIB - - #if defined( strncpy ) - #undef strncpy - #endif - #define strncpy strncpy__HEY_YOU__USE_VSTDLIB - - #if defined( wcsncpy ) - #undef wcsncpy - #endif - #define wcsncpy wcsncpy__HEY_YOU__USE_VSTDLIB - - #if defined( strlen ) - #undef strlen - #endif - #define strlen strlen__HEY_YOU__USE_VSTDLIB - - #if defined( wcslen ) - #undef wcslen - #endif - #define wcslen wcslen__HEY_YOU__USE_VSTDLIB - - #if defined( Q_strlen ) - #undef Q_strlen - #endif - #define Q_strlen Q_strlen__HEY_YOU__USE_VSTDLIB - - #if defined( _snprintf ) - #undef _snprintf - #endif - #define _snprintf snprintf__HEY_YOU__USE_VSTDLIB - - #if defined( _snwprintf ) - #undef _snwprintf - #endif - #define _snwprintf snwprintf__HEY_YOU__USE_VSTDLIB - - #if defined( sprintf ) - #undef sprintf - #endif - #define sprintf sprintf__HEY_YOU__USE_VSTDLIB - - #if defined( swprintf ) - #undef swprintf - #endif - #define swprintf swprintf__HEY_YOU__USE_VSTDLIB - - #if defined( vsprintf ) - #undef vsprintf - #endif - #define vsprintf vsprintf__HEY_YOU__USE_VSTDLIB - - #if defined( vswprintf ) - #undef vswprintf - #endif - #define vswprintf vswprintf__HEY_YOU__USE_VSTDLIB - - #if defined( _vsnprintf ) - #undef _vsnprintf - #endif - #define _vsnprintf vsnprintf__HEY_YOU__USE_VSTDLIB - - #if defined( _vsnwprintf ) - #undef _vsnwprintf - #endif - #define _vsnwprintf vsnwprintf__HEY_YOU__USE_VSTDLIB - - #if defined( strcat ) - #undef strcat - #endif - #define strcat strcat__HEY_YOU__USE_VSTDLIB - - #if defined( wcscat ) - #undef wcscat - #endif - #define wcscat wcscat__HEY_YOU__USE_VSTDLIB - - #if defined( strncat ) - #undef strncat - #endif - #define strncat strncat__HEY_YOU__USE_VSTDLIB - - #if defined( wcsncat ) - #undef wcsncat - #endif - #define wcsncat wcsncat__HEY_YOU__USE_VSTDLIB - -#endif - - -#if defined( PROTECT_FILEIO_FUNCTIONS ) && ( ! defined( _LINUX ) ) - #if defined( fopen ) - #undef fopen - #endif - #define fopen fopen_USE_FILESYSTEM_INSTEAD - - #if defined( _wfopen ) - #undef _wfopen - #endif - #define _wfopen _wfopen_USE_FILESYSTEM_INSTEAD -#endif - - -#if defined( PROTECTED_THINGS_ENABLE ) && !defined( _X360 ) - - #if defined( GetTickCount ) - #undef GetTickCount - #endif - #define GetTickCount GetTickCount__USE_VCR_MODE - - - #if defined( timeGetTime ) - #undef timeGetTime - #endif - #define timeGetTime timeGetTime__USE_VCR_MODE - #if defined( clock ) - #undef clock - #endif - #define time time__USE_VCR_MODE - - - #if defined( recvfrom ) - #undef recvfrom - #endif - #define recvfrom recvfrom__USE_VCR_MODE - - - #if defined( GetCursorPos ) - #undef GetCursorPos - #endif - #define GetCursorPos GetCursorPos__USE_VCR_MODE - - - #if defined( ScreenToClient ) - #undef ScreenToClient - #endif - #define ScreenToClient ScreenToClient__USE_VCR_MODE - - - #if defined( GetCommandLine ) - #undef GetCommandLine - #endif - #define GetCommandLine GetCommandLine__USE_VCR_MODE - - - #if defined( RegOpenKeyEx ) - #undef RegOpenKeyEx - #endif - #define RegOpenKeyEx RegOpenKeyEx__USE_VCR_MODE - - - #if defined( RegOpenKey ) - #undef RegOpenKey - #endif - #define RegOpenKey RegOpenKey__USE_VCR_MODE - - - #if defined( RegSetValueEx ) - #undef RegSetValueEx - #endif - #define RegSetValueEx RegSetValueEx__USE_VCR_MODE - - - #if defined( RegSetValue ) - #undef RegSetValue - #endif - #define RegSetValue RegSetValue__USE_VCR_MODE - - - #if defined( RegQueryValueEx ) - #undef RegQueryValueEx - #endif - #define RegQueryValueEx RegQueryValueEx__USE_VCR_MODE - - - #if defined( RegQueryValue ) - #undef RegQueryValue - #endif - #define RegQueryValue RegQueryValue__USE_VCR_MODE - - - #if defined( RegCreateKeyEx ) - #undef RegCreateKeyEx - #endif - #define RegCreateKeyEx RegCreateKeyEx__USE_VCR_MODE - - - #if defined( RegCreateKey ) - #undef RegCreateKey - #endif - #define RegCreateKey RegCreateKey__USE_VCR_MODE - - - #if defined( RegCloseKey ) - #undef RegCloseKey - #endif - #define RegCloseKey RegCloseKey__USE_VCR_MODE - - - #if defined( GetNumberOfConsoleInputEvents ) - #undef GetNumberOfConsoleInputEvents - #endif - #define GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents__USE_VCR_MODE - - - #if defined( ReadConsoleInput ) - #undef ReadConsoleInput - #endif - #define ReadConsoleInput ReadConsoleInput__USE_VCR_MODE - - - #if defined( GetAsyncKeyState ) - #undef GetAsyncKeyState - #endif - #define GetAsyncKeyState GetAsyncKeyState__USE_VCR_MODE - - - #if defined( GetKeyState ) - #undef GetKeyState - #endif - #define GetKeyState GetKeyState__USE_VCR_MODE - - - #if defined( CreateThread ) - #undef CreateThread - #endif - #define CreateThread CreateThread__USE_VCR_MODE - - #if defined( WaitForSingleObject ) - #undef WaitForSingleObject - #endif - #define WaitForSingleObject WaitForSingleObject__USE_VCR_MODE - - #if defined( EnterCriticalSection ) - #undef EnterCriticalSection - #endif - #define EnterCriticalSection EnterCriticalSection__USE_VCR_MODE - -#endif - - -#endif // PROTECTED_THINGS_H diff --git a/Resources/NetHook/tier0/systeminformation.h b/Resources/NetHook/tier0/systeminformation.h deleted file mode 100644 index a64b13cb..00000000 --- a/Resources/NetHook/tier0/systeminformation.h +++ /dev/null @@ -1,56 +0,0 @@ -//====== Copyright c 1996-2007, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#ifndef SYSTEMINFORMATION_H -#define SYSTEMINFORMATION_H - -#ifdef _WIN32 - #pragma once -#endif - -#ifndef PLATFORM_INTERFACE - #define PLATFORM_INTERFACE -#endif - -// -// Defines a possible outcome of a system call -// -enum SYSTEM_CALL_RESULT_t -{ - SYSCALL_SUCCESS = 0, // System call succeeded - SYSCALL_FAILED = 1, // System call failed - SYSCALL_NOPROC = 2, // Failed to find required system procedure - SYSCALL_NODLL = 3, // Failed to find or load required system module - SYSCALL_UNSUPPORTED = 4, // System call unsupported on the OS -}; - - -// -// Information about paged pool memory -// -struct PAGED_POOL_INFO_t -{ - unsigned long numPagesUsed; // Number of Paged Pool pages used - unsigned long numPagesFree; // Number of Paged Pool pages free -}; - -// -// Plat_GetMemPageSize -// Returns the size of a memory page in kilobytes. -// -PLATFORM_INTERFACE unsigned long Plat_GetMemPageSize(); - -// -// Plat_GetPagedPoolInfo -// Fills in the paged pool info structure if successful. -// -PLATFORM_INTERFACE SYSTEM_CALL_RESULT_t Plat_GetPagedPoolInfo( PAGED_POOL_INFO_t *pPPI ); - - - -#endif // #ifndef SYSTEMINFORMATION_H diff --git a/Resources/NetHook/tier0/testthread.h b/Resources/NetHook/tier0/testthread.h deleted file mode 100644 index 4dbd2576..00000000 --- a/Resources/NetHook/tier0/testthread.h +++ /dev/null @@ -1,60 +0,0 @@ -//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: exposes testing thread functions -// -//============================================================================= - -#ifndef TESTTHREAD_H -#define TESTTHREAD_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" - -// test callback -typedef void (STDCALL *TestFunc)(void *pv); - -// runs the test function -DBG_INTERFACE void Test_RunTest(TestFunc func, void *pvArg); - -// call to give the test thread a chance to run -// calling thread will block until the test thread yields -// doesn't do anything if no tests are running -DBG_INTERFACE void Test_RunFrame(); - -// true if any tests are running, or have ran -DBG_INTERFACE bool Test_IsActive(); - -// sets that the test has failed -DBG_INTERFACE void Test_SetFailed(); - -// true if any tests have failed, due to an assert, warning, or explicit fail -DBG_INTERFACE bool Test_HasFailed(); - -// true if any tests have completed -DBG_INTERFACE bool Test_HasFinished(); - -// terminates the test thread -DBG_INTERFACE void Test_TerminateThread(); - -// the following functions should only be called from the test thread - -// yields to the main thread for a single frame -// passing in is a count of the number of frames that have been yielded by this yield macro -// can be used to assert if a test thread is blocked foor -DBG_INTERFACE void TestThread_Yield(); - -// utility functions to pause the test frame until the selected condition is true -#define YIELD_UNTIL(x) { int iYieldCount = 0; while (!(x)) { TestThread_Yield(); iYieldCount++; if ( iYieldCount >= 100 ) { AssertMsg( false, #x ); break; } } } - -// use this like a while(1) loop, with break; to stop yielding -#define YIELD_UNTIL_BREAK() for (; true; TestThread_Yield()) - -// yields for a single frame -#define YIELD_FRAME() { TestThread_Yield(); } -#define YIELD_TWO_FRAMES() { TestThread_Yield(); TestThread_Yield(); } - - - -#endif // TESTTHREAD_H diff --git a/Resources/NetHook/tier0/threadtools.h b/Resources/NetHook/tier0/threadtools.h deleted file mode 100644 index e974da4d..00000000 --- a/Resources/NetHook/tier0/threadtools.h +++ /dev/null @@ -1,1577 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: A collection of utility classes to simplify thread handling, and -// as much as possible contain portability problems. Here avoiding -// including windows.h. -// -//============================================================================= - -#ifndef THREADTOOLS_H -#define THREADTOOLS_H - -#include - -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier0/vcrmode.h" - -#ifdef _LINUX -#include -#include -#endif - -#if defined( _WIN32 ) -#pragma once -#pragma warning(push) -#pragma warning(disable:4251) -#endif - -// #define THREAD_PROFILER 1 - -#ifndef STATIC_TIER0 - -#ifdef TIER0_DLL_EXPORT -#define TT_INTERFACE DLL_EXPORT -#define TT_OVERLOAD DLL_GLOBAL_EXPORT -#define TT_CLASS DLL_CLASS_EXPORT -#else -#define TT_INTERFACE DLL_IMPORT -#define TT_OVERLOAD DLL_GLOBAL_IMPORT -#define TT_CLASS DLL_CLASS_IMPORT -#endif - -#else // BUILD_AS_DLL - -#define TT_INTERFACE extern -#define TT_OVERLOAD -#define TT_CLASS -#endif // BUILD_AS_DLL - -#ifndef _RETAIL -#define THREAD_MUTEX_TRACING_SUPPORTED -#if defined(_WIN32) && defined(_DEBUG) -#define THREAD_MUTEX_TRACING_ENABLED -#endif -#endif - -#ifdef _WIN32 -typedef void *HANDLE; -#endif - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- - -const unsigned TT_INFINITE = 0xffffffff; - -#ifndef NO_THREAD_LOCAL - -#ifndef THREAD_LOCAL -#ifdef _WIN32 -#define THREAD_LOCAL __declspec(thread) -#elif _LINUX -#define THREAD_LOCAL __thread -#endif -#endif - -#endif // NO_THREAD_LOCAL - -typedef unsigned long ThreadId_t; - -//----------------------------------------------------------------------------- -// -// Simple thread creation. Differs from VCR mode/CreateThread/_beginthreadex -// in that it accepts a standard C function rather than compiler specific one. -// -//----------------------------------------------------------------------------- -FORWARD_DECLARE_HANDLE( ThreadHandle_t ); -typedef unsigned (*ThreadFunc_t)( void *pParam ); - -TT_OVERLOAD ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, ThreadId_t *pID, unsigned stackSize = 0 ); -TT_INTERFACE ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, unsigned stackSize = 0 ); -TT_INTERFACE bool ReleaseThreadHandle( ThreadHandle_t ); - - -//----------------------------------------------------------------------------- - -TT_INTERFACE void ThreadSleep(unsigned duration = 0); -TT_INTERFACE uint ThreadGetCurrentId(); -TT_INTERFACE ThreadHandle_t ThreadGetCurrentHandle(); -TT_INTERFACE int ThreadGetPriority( ThreadHandle_t hThread = NULL ); -TT_INTERFACE bool ThreadSetPriority( ThreadHandle_t hThread, int priority ); -inline bool ThreadSetPriority( int priority ) { return ThreadSetPriority( NULL, priority ); } -TT_INTERFACE bool ThreadInMainThread(); -TT_INTERFACE void DeclareCurrentThreadIsMainThread(); - -// NOTE: ThreadedLoadLibraryFunc_t needs to return the sleep time in milliseconds or TT_INFINITE -typedef int (*ThreadedLoadLibraryFunc_t)(); -TT_INTERFACE void SetThreadedLoadLibraryFunc( ThreadedLoadLibraryFunc_t func ); -TT_INTERFACE ThreadedLoadLibraryFunc_t GetThreadedLoadLibraryFunc(); - -#if defined( _WIN32 ) && !defined( _WIN64 ) && !defined( _X360 ) -extern "C" unsigned long __declspec(dllimport) __stdcall GetCurrentThreadId(); -#define ThreadGetCurrentId GetCurrentThreadId -#endif - -inline void ThreadPause() -{ -#if defined( _WIN32 ) && !defined( _X360 ) - __asm pause; -#elif _LINUX - __asm __volatile("pause"); -#elif defined( _X360 ) -#else -#error "implement me" -#endif -} - -TT_INTERFACE bool ThreadJoin( ThreadHandle_t, unsigned timeout = TT_INFINITE ); - -TT_INTERFACE void ThreadSetDebugName( ThreadId_t id, const char *pszName ); -inline void ThreadSetDebugName( const char *pszName ) { ThreadSetDebugName( (ThreadId_t)-1, pszName ); } - -TT_INTERFACE void ThreadSetAffinity( ThreadHandle_t hThread, int nAffinityMask ); - -//----------------------------------------------------------------------------- - -enum ThreadWaitResult_t -{ - TW_FAILED = 0xffffffff, // WAIT_FAILED - TW_TIMEOUT = 0x00000102, // WAIT_TIMEOUT -}; - -#ifdef _WIN32 -TT_INTERFACE int ThreadWaitForObjects( int nEvents, const HANDLE *pHandles, bool bWaitAll = true, unsigned timeout = TT_INFINITE ); -inline int ThreadWaitForObject( HANDLE handle, bool bWaitAll = true, unsigned timeout = TT_INFINITE ) { return ThreadWaitForObjects( 1, &handle, bWaitAll, timeout ); } -#endif - -//----------------------------------------------------------------------------- -// -// Interlock methods. These perform very fast atomic thread -// safe operations. These are especially relevant in a multi-core setting. -// -//----------------------------------------------------------------------------- - -#ifdef _WIN32 -#define NOINLINE -#elif _LINUX -#define NOINLINE __attribute__ ((noinline)) -#endif - -#if defined(_WIN32) && !defined(_X360) -#if ( _MSC_VER >= 1310 ) -#define USE_INTRINSIC_INTERLOCKED -#endif -#endif - -#ifdef USE_INTRINSIC_INTERLOCKED -extern "C" -{ - long __cdecl _InterlockedIncrement(volatile long*); - long __cdecl _InterlockedDecrement(volatile long*); - long __cdecl _InterlockedExchange(volatile long*, long); - long __cdecl _InterlockedExchangeAdd(volatile long*, long); - long __cdecl _InterlockedCompareExchange(volatile long*, long, long); -} - -#pragma intrinsic( _InterlockedCompareExchange ) -#pragma intrinsic( _InterlockedDecrement ) -#pragma intrinsic( _InterlockedExchange ) -#pragma intrinsic( _InterlockedExchangeAdd ) -#pragma intrinsic( _InterlockedIncrement ) - -inline long ThreadInterlockedIncrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedIncrement( p ); } -inline long ThreadInterlockedDecrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedDecrement( p ); } -inline long ThreadInterlockedExchange( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchange( p, value ); } -inline long ThreadInterlockedExchangeAdd( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchangeAdd( p, value ); } -inline long ThreadInterlockedCompareExchange( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedCompareExchange( p, value, comperand ); } -inline bool ThreadInterlockedAssignIf( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return ( _InterlockedCompareExchange( p, value, comperand ) == comperand ); } -#else -TT_INTERFACE long ThreadInterlockedIncrement( long volatile * ) NOINLINE; -TT_INTERFACE long ThreadInterlockedDecrement( long volatile * ) NOINLINE; -TT_INTERFACE long ThreadInterlockedExchange( long volatile *, long value ) NOINLINE; -TT_INTERFACE long ThreadInterlockedExchangeAdd( long volatile *, long value ) NOINLINE; -TT_INTERFACE long ThreadInterlockedCompareExchange( long volatile *, long value, long comperand ) NOINLINE; -TT_INTERFACE bool ThreadInterlockedAssignIf( long volatile *, long value, long comperand ) NOINLINE; -#endif - -inline unsigned ThreadInterlockedExchangeSubtract( long volatile *p, long value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, -value ); } - -#if defined( USE_INTRINSIC_INTERLOCKED ) && !defined( _WIN64 ) -#define TIPTR() -inline void *ThreadInterlockedExchangePointer( void * volatile *p, void *value ) { return (void *)_InterlockedExchange( reinterpret_cast(p), reinterpret_cast(value) ); } -inline void *ThreadInterlockedCompareExchangePointer( void * volatile *p, void *value, void *comperand ) { return (void *)_InterlockedCompareExchange( reinterpret_cast(p), reinterpret_cast(value), reinterpret_cast(comperand) ); } -inline bool ThreadInterlockedAssignPointerIf( void * volatile *p, void *value, void *comperand ) { return ( _InterlockedCompareExchange( reinterpret_cast(p), reinterpret_cast(value), reinterpret_cast(comperand) ) == reinterpret_cast(comperand) ); } -#else -TT_INTERFACE void *ThreadInterlockedExchangePointer( void * volatile *, void *value ) NOINLINE; -TT_INTERFACE void *ThreadInterlockedCompareExchangePointer( void * volatile *, void *value, void *comperand ) NOINLINE; -TT_INTERFACE bool ThreadInterlockedAssignPointerIf( void * volatile *, void *value, void *comperand ) NOINLINE; -#endif - -inline void const *ThreadInterlockedExchangePointerToConst( void const * volatile *p, void const *value ) { return ThreadInterlockedExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ) ); } -inline void const *ThreadInterlockedCompareExchangePointerToConst( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedCompareExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); } -inline bool ThreadInterlockedAssignPointerToConstIf( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedAssignPointerIf( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); } - -TT_INTERFACE int64 ThreadInterlockedIncrement64( int64 volatile * ) NOINLINE; -TT_INTERFACE int64 ThreadInterlockedDecrement64( int64 volatile * ) NOINLINE; -TT_INTERFACE int64 ThreadInterlockedCompareExchange64( int64 volatile *, int64 value, int64 comperand ) NOINLINE; -TT_INTERFACE int64 ThreadInterlockedExchange64( int64 volatile *, int64 value ) NOINLINE; -TT_INTERFACE int64 ThreadInterlockedExchangeAdd64( int64 volatile *, int64 value ) NOINLINE; -TT_INTERFACE bool ThreadInterlockedAssignIf64(volatile int64 *pDest, int64 value, int64 comperand ) NOINLINE; - -inline unsigned ThreadInterlockedExchangeSubtract( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); } -inline unsigned ThreadInterlockedIncrement( unsigned volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); } -inline unsigned ThreadInterlockedDecrement( unsigned volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); } -inline unsigned ThreadInterlockedExchange( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); } -inline unsigned ThreadInterlockedExchangeAdd( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); } -inline unsigned ThreadInterlockedCompareExchange( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); } -inline bool ThreadInterlockedAssignIf( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); } - -inline int ThreadInterlockedExchangeSubtract( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); } -inline int ThreadInterlockedIncrement( int volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); } -inline int ThreadInterlockedDecrement( int volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); } -inline int ThreadInterlockedExchange( int volatile *p, int value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); } -inline int ThreadInterlockedExchangeAdd( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); } -inline int ThreadInterlockedCompareExchange( int volatile *p, int value, int comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); } -inline bool ThreadInterlockedAssignIf( int volatile *p, int value, int comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); } - -//----------------------------------------------------------------------------- -// Access to VTune thread profiling -//----------------------------------------------------------------------------- -#if defined(_WIN32) && defined(THREAD_PROFILER) -TT_INTERFACE void ThreadNotifySyncPrepare(void *p); -TT_INTERFACE void ThreadNotifySyncCancel(void *p); -TT_INTERFACE void ThreadNotifySyncAcquired(void *p); -TT_INTERFACE void ThreadNotifySyncReleasing(void *p); -#else -#define ThreadNotifySyncPrepare(p) ((void)0) -#define ThreadNotifySyncCancel(p) ((void)0) -#define ThreadNotifySyncAcquired(p) ((void)0) -#define ThreadNotifySyncReleasing(p) ((void)0) -#endif - -//----------------------------------------------------------------------------- -// Encapsulation of a thread local datum (needed because THREAD_LOCAL doesn't -// work in a DLL loaded with LoadLibrary() -//----------------------------------------------------------------------------- - -#ifndef __AFXTLS_H__ // not compatible with some Windows headers -#ifndef NO_THREAD_LOCAL - -class TT_CLASS CThreadLocalBase -{ -public: - CThreadLocalBase(); - ~CThreadLocalBase(); - - void * Get() const; - void Set(void *); - -private: -#ifdef _WIN32 - uint32 m_index; -#elif _LINUX - pthread_key_t m_index; -#endif -}; - -//--------------------------------------------------------- - -#ifndef __AFXTLS_H__ - -template -class CThreadLocal : public CThreadLocalBase -{ -public: - CThreadLocal() - { - COMPILE_TIME_ASSERT( sizeof(T) == sizeof(void *) ); - } - - T Get() const - { - return reinterpret_cast(CThreadLocalBase::Get()); - } - - void Set(T val) - { - CThreadLocalBase::Set(reinterpret_cast(val)); - } -}; - -#endif - -//--------------------------------------------------------- - -template -class CThreadLocalInt : public CThreadLocal -{ -public: - operator const T() const { return Get(); } - int operator=( T i ) { Set( i ); return i; } - - T operator++() { T i = Get(); Set( ++i ); return i; } - T operator++(int) { T i = Get(); Set( i + 1 ); return i; } - - T operator--() { T i = Get(); Set( --i ); return i; } - T operator--(int) { T i = Get(); Set( i - 1 ); return i; } -}; - -//--------------------------------------------------------- - -template -class CThreadLocalPtr : private CThreadLocalBase -{ -public: - CThreadLocalPtr() {} - - operator const void *() const { return (T *)Get(); } - operator void *() { return (T *)Get(); } - - operator const T *() const { return (T *)Get(); } - operator const T *() { return (T *)Get(); } - operator T *() { return (T *)Get(); } - - int operator=( int i ) { AssertMsg( i == 0, "Only NULL allowed on integer assign" ); Set( NULL ); return 0; } - T * operator=( T *p ) { Set( p ); return p; } - - bool operator !() const { return (!Get()); } - bool operator!=( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() != NULL); } - bool operator==( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() == NULL); } - bool operator==( const void *p ) const { return (Get() == p); } - bool operator!=( const void *p ) const { return (Get() != p); } - bool operator==( const T *p ) const { return operator==((void*)p); } - bool operator!=( const T *p ) const { return operator!=((void*)p); } - - T * operator->() { return (T *)Get(); } - T & operator *() { return *((T *)Get()); } - - const T * operator->() const { return (T *)Get(); } - const T & operator *() const { return *((T *)Get()); } - - const T & operator[]( int i ) const { return *((T *)Get() + i); } - T & operator[]( int i ) { return *((T *)Get() + i); } - -private: - // Disallowed operations - CThreadLocalPtr( T *pFrom ); - CThreadLocalPtr( const CThreadLocalPtr &from ); - T **operator &(); - T * const *operator &() const; - void operator=( const CThreadLocalPtr &from ); - bool operator==( const CThreadLocalPtr &p ) const; - bool operator!=( const CThreadLocalPtr &p ) const; -}; - -#endif // NO_THREAD_LOCAL -#endif // !__AFXTLS_H__ - -//----------------------------------------------------------------------------- -// -// A super-fast thread-safe integer A simple class encapsulating the notion of an -// atomic integer used across threads that uses the built in and faster -// "interlocked" functionality rather than a full-blown mutex. Useful for simple -// things like reference counts, etc. -// -//----------------------------------------------------------------------------- - -template -class CInterlockedIntT -{ -public: - CInterlockedIntT() : m_value( 0 ) { COMPILE_TIME_ASSERT( sizeof(T) == sizeof(long) ); } - CInterlockedIntT( T value ) : m_value( value ) {} - - operator T() const { return m_value; } - - bool operator!() const { return ( m_value == 0 ); } - bool operator==( T rhs ) const { return ( m_value == rhs ); } - bool operator!=( T rhs ) const { return ( m_value != rhs ); } - - T operator++() { return (T)ThreadInterlockedIncrement( (long *)&m_value ); } - T operator++(int) { return operator++() - 1; } - - T operator--() { return (T)ThreadInterlockedDecrement( (long *)&m_value ); } - T operator--(int) { return operator--() + 1; } - - bool AssignIf( T conditionValue, T newValue ) { return ThreadInterlockedAssignIf( (long *)&m_value, (long)newValue, (long)conditionValue ); } - - T operator=( T newValue ) { ThreadInterlockedExchange((long *)&m_value, newValue); return m_value; } - - void operator+=( T add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, (long)add ); } - void operator-=( T subtract ) { operator+=( -subtract ); } - void operator*=( T multiplier ) { - T original, result; - do - { - original = m_value; - result = original * multiplier; - } while ( !AssignIf( original, result ) ); - } - void operator/=( T divisor ) { - T original, result; - do - { - original = m_value; - result = original / divisor; - } while ( !AssignIf( original, result ) ); - } - - T operator+( T rhs ) const { return m_value + rhs; } - T operator-( T rhs ) const { return m_value - rhs; } - -private: - volatile T m_value; -}; - -typedef CInterlockedIntT CInterlockedInt; -typedef CInterlockedIntT CInterlockedUInt; - -//----------------------------------------------------------------------------- - -template -class CInterlockedPtr -{ -public: - CInterlockedPtr() : m_value( 0 ) { COMPILE_TIME_ASSERT( sizeof(T *) == sizeof(long) ); /* Will need to rework operator+= for 64 bit */ } - CInterlockedPtr( T *value ) : m_value( value ) {} - - operator T *() const { return m_value; } - - bool operator!() const { return ( m_value == 0 ); } - bool operator==( T *rhs ) const { return ( m_value == rhs ); } - bool operator!=( T *rhs ) const { return ( m_value != rhs ); } - - T *operator++() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) )) + 1; } - T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) ); } - - T *operator--() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) )) - 1; } - T *operator--(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) ); } - - bool AssignIf( T *conditionValue, T *newValue ) { return ThreadInterlockedAssignPointerToConstIf( (void const **) &m_value, (void const *) newValue, (void const *) conditionValue ); } - - T *operator=( T *newValue ) { ThreadInterlockedExchangePointerToConst( (void const **) &m_value, (void const *) newValue ); return newValue; } - - void operator+=( int add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, add * sizeof(T) ); } - void operator-=( int subtract ) { operator+=( -subtract ); } - - T *operator+( int rhs ) const { return m_value + rhs; } - T *operator-( int rhs ) const { return m_value - rhs; } - T *operator+( unsigned rhs ) const { return m_value + rhs; } - T *operator-( unsigned rhs ) const { return m_value - rhs; } - size_t operator-( T *p ) const { return m_value - p; } - size_t operator-( const CInterlockedPtr &p ) const { return m_value - p.m_value; } - -private: - T * volatile m_value; -}; - - -//----------------------------------------------------------------------------- -// -// Platform independent for critical sections management -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThreadMutex -{ -public: - CThreadMutex(); - ~CThreadMutex(); - - //------------------------------------------------------ - // Mutex acquisition/release. Const intentionally defeated. - //------------------------------------------------------ - void Lock(); - void Lock() const { (const_cast(this))->Lock(); } - void Unlock(); - void Unlock() const { (const_cast(this))->Unlock(); } - - bool TryLock(); - bool TryLock() const { return (const_cast(this))->TryLock(); } - - //------------------------------------------------------ - // Use this to make deadlocks easier to track by asserting - // when it is expected that the current thread owns the mutex - //------------------------------------------------------ - bool AssertOwnedByCurrentThread(); - - //------------------------------------------------------ - // Enable tracing to track deadlock problems - //------------------------------------------------------ - void SetTrace( bool ); - -private: - // Disallow copying - CThreadMutex( const CThreadMutex & ); - CThreadMutex &operator=( const CThreadMutex & ); - -#if defined( _WIN32 ) - // Efficient solution to breaking the windows.h dependency, invariant is tested. -#ifdef _WIN64 - #define TT_SIZEOF_CRITICALSECTION 40 -#else -#ifndef _X360 - #define TT_SIZEOF_CRITICALSECTION 24 -#else - #define TT_SIZEOF_CRITICALSECTION 28 -#endif // !_XBOX -#endif // _WIN64 - byte m_CriticalSection[TT_SIZEOF_CRITICALSECTION]; -#elif _LINUX - pthread_mutex_t m_Mutex; - pthread_mutexattr_t m_Attr; -#else -#error -#endif - -#ifdef THREAD_MUTEX_TRACING_SUPPORTED - // Debugging (always here to allow mixed debug/release builds w/o changing size) - uint m_currentOwnerID; - uint16 m_lockCount; - bool m_bTrace; -#endif -}; - -//----------------------------------------------------------------------------- -// -// An alternative mutex that is useful for cases when thread contention is -// rare, but a mutex is required. Instances should be declared volatile. -// Sleep of 0 may not be sufficient to keep high priority threads from starving -// lesser threads. This class is not a suitable replacement for a critical -// section if the resource contention is high. -// -//----------------------------------------------------------------------------- - -#if defined(_WIN32) && !defined(THREAD_PROFILER) - -class CThreadFastMutex -{ -public: - CThreadFastMutex() - : m_ownerID( 0 ), - m_depth( 0 ) - { - } - -private: - FORCEINLINE bool TryLockInline( const uint32 threadId ) volatile - { - if ( threadId != m_ownerID && !ThreadInterlockedAssignIf( (volatile long *)&m_ownerID, (long)threadId, 0 ) ) - return false; - - ++m_depth; - return true; - } - - bool TryLock( const uint32 threadId ) volatile - { - return TryLockInline( threadId ); - } - - TT_CLASS void Lock( const uint32 threadId, unsigned nSpinSleepTime ) volatile; - -public: - bool TryLock() volatile - { -#ifdef _DEBUG - if ( m_depth == INT_MAX ) - DebuggerBreak(); - - if ( m_depth < 0 ) - DebuggerBreak(); -#endif - return TryLockInline( ThreadGetCurrentId() ); - } - -#ifndef _DEBUG - FORCEINLINE -#endif - void Lock( unsigned nSpinSleepTime = 0 ) volatile - { - const uint32 threadId = ThreadGetCurrentId(); - - if ( !TryLockInline( threadId ) ) - { - ThreadPause(); - Lock( threadId, nSpinSleepTime ); - } -#ifdef _DEBUG - if ( m_ownerID != ThreadGetCurrentId() ) - DebuggerBreak(); - - if ( m_depth == INT_MAX ) - DebuggerBreak(); - - if ( m_depth < 0 ) - DebuggerBreak(); -#endif - } - -#ifndef _DEBUG - FORCEINLINE -#endif - void Unlock() volatile - { -#ifdef _DEBUG - if ( m_ownerID != ThreadGetCurrentId() ) - DebuggerBreak(); - - if ( m_depth <= 0 ) - DebuggerBreak(); -#endif - - --m_depth; - if ( !m_depth ) - ThreadInterlockedExchange( &m_ownerID, 0 ); - } - - bool TryLock() const volatile { return (const_cast(this))->TryLock(); } - void Lock(unsigned nSpinSleepTime = 1 ) const volatile { (const_cast(this))->Lock( nSpinSleepTime ); } - void Unlock() const volatile { (const_cast(this))->Unlock(); } - - // To match regular CThreadMutex: - bool AssertOwnedByCurrentThread() { return true; } - void SetTrace( bool ) {} - - uint32 GetOwnerId() const { return m_ownerID; } - int GetDepth() const { return m_depth; } -private: - volatile uint32 m_ownerID; - int m_depth; -}; - -class ALIGN128 CAlignedThreadFastMutex : public CThreadFastMutex -{ -public: - CAlignedThreadFastMutex() - { - Assert( (size_t)this % 128 == 0 && sizeof(*this) == 128 ); - } - -private: - uint8 pad[128-sizeof(CThreadFastMutex)]; -}; - -#else -typedef CThreadMutex CThreadFastMutex; -#endif - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- - -class CThreadNullMutex -{ -public: - static void Lock() {} - static void Unlock() {} - - static bool TryLock() { return true; } - static bool AssertOwnedByCurrentThread() { return true; } - static void SetTrace( bool b ) {} - - static uint32 GetOwnerId() { return 0; } - static int GetDepth() { return 0; } -}; - -//----------------------------------------------------------------------------- -// -// A mutex decorator class used to control the use of a mutex, to make it -// less expensive when not multithreading -// -//----------------------------------------------------------------------------- - -template -class CThreadConditionalMutex : public BaseClass -{ -public: - void Lock() { if ( *pCondition ) BaseClass::Lock(); } - void Lock() const { if ( *pCondition ) BaseClass::Lock(); } - void Unlock() { if ( *pCondition ) BaseClass::Unlock(); } - void Unlock() const { if ( *pCondition ) BaseClass::Unlock(); } - - bool TryLock() { if ( *pCondition ) return BaseClass::TryLock(); else return true; } - bool TryLock() const { if ( *pCondition ) return BaseClass::TryLock(); else return true; } - bool AssertOwnedByCurrentThread() { if ( *pCondition ) return BaseClass::AssertOwnedByCurrentThread(); else return true; } - void SetTrace( bool b ) { if ( *pCondition ) BaseClass::SetTrace( b ); } -}; - -//----------------------------------------------------------------------------- -// Mutex decorator that blows up if another thread enters -//----------------------------------------------------------------------------- - -template -class CThreadTerminalMutex : public BaseClass -{ -public: - bool TryLock() { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; } - bool TryLock() const { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; } - void Lock() { if ( !TryLock() ) BaseClass::Lock(); } - void Lock() const { if ( !TryLock() ) BaseClass::Lock(); } - -}; - -//----------------------------------------------------------------------------- -// -// Class to Lock a critical section, and unlock it automatically -// when the lock goes out of scope -// -//----------------------------------------------------------------------------- - -template -class CAutoLockT -{ -public: - FORCEINLINE CAutoLockT( MUTEX_TYPE &lock) - : m_lock(lock) - { - m_lock.Lock(); - } - - FORCEINLINE CAutoLockT(const MUTEX_TYPE &lock) - : m_lock(const_cast(lock)) - { - m_lock.Lock(); - } - - FORCEINLINE ~CAutoLockT() - { - m_lock.Unlock(); - } - - -private: - MUTEX_TYPE &m_lock; - - // Disallow copying - CAutoLockT( const CAutoLockT & ); - CAutoLockT &operator=( const CAutoLockT & ); -}; - -typedef CAutoLockT CAutoLock; - -//--------------------------------------------------------- - -template struct CAutoLockTypeDeducer {}; -template <> struct CAutoLockTypeDeducer { typedef CThreadMutex Type_t; }; -template <> struct CAutoLockTypeDeducer { typedef CThreadNullMutex Type_t; }; -#if defined(_WIN32) && !defined(THREAD_PROFILER) -template <> struct CAutoLockTypeDeducer { typedef CThreadFastMutex Type_t; }; -template <> struct CAutoLockTypeDeducer { typedef CAlignedThreadFastMutex Type_t; }; -#endif - -#define AUTO_LOCK_( type, mutex ) \ - CAutoLockT< type > UNIQUE_ID( static_cast( mutex ) ) - -#define AUTO_LOCK( mutex ) \ - AUTO_LOCK_( CAutoLockTypeDeducer::Type_t, mutex ) - - -#define AUTO_LOCK_FM( mutex ) \ - AUTO_LOCK_( CThreadFastMutex, mutex ) - -#define LOCAL_THREAD_LOCK_( tag ) \ - ; \ - static CThreadFastMutex autoMutex_##tag; \ - AUTO_LOCK( autoMutex_##tag ) - -#define LOCAL_THREAD_LOCK() \ - LOCAL_THREAD_LOCK_(_) - -//----------------------------------------------------------------------------- -// -// Base class for event, semaphore and mutex objects. -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThreadSyncObject -{ -public: - ~CThreadSyncObject(); - - //----------------------------------------------------- - // Query if object is useful - //----------------------------------------------------- - bool operator!() const; - - //----------------------------------------------------- - // Access handle - //----------------------------------------------------- -#ifdef _WIN32 - operator HANDLE() { return m_hSyncObject; } -#endif - //----------------------------------------------------- - // Wait for a signal from the object - //----------------------------------------------------- - bool Wait( uint32 dwTimeout = TT_INFINITE ); - -protected: - CThreadSyncObject(); - void AssertUseable(); - -#ifdef _WIN32 - HANDLE m_hSyncObject; -#elif _LINUX - pthread_mutex_t m_Mutex; - pthread_cond_t m_Condition; - bool m_bInitalized; - int m_cSet; - bool m_bManualReset; -#else -#error "Implement me" -#endif - -private: - CThreadSyncObject( const CThreadSyncObject & ); - CThreadSyncObject &operator=( const CThreadSyncObject & ); -}; - - -//----------------------------------------------------------------------------- -// -// Wrapper for unnamed event objects -// -//----------------------------------------------------------------------------- - -#if defined( _WIN32 ) - -//----------------------------------------------------------------------------- -// -// CThreadSemaphore -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThreadSemaphore : public CThreadSyncObject -{ -public: - CThreadSemaphore(long initialValue, long maxValue); - - //----------------------------------------------------- - // Increases the count of the semaphore object by a specified - // amount. Wait() decreases the count by one on return. - //----------------------------------------------------- - bool Release(long releaseCount = 1, long * pPreviousCount = NULL ); - -private: - CThreadSemaphore(const CThreadSemaphore &); - CThreadSemaphore &operator=(const CThreadSemaphore &); -}; - - -//----------------------------------------------------------------------------- -// -// A mutex suitable for out-of-process, multi-processor usage -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThreadFullMutex : public CThreadSyncObject -{ -public: - CThreadFullMutex( bool bEstablishInitialOwnership = false, const char * pszName = NULL ); - - //----------------------------------------------------- - // Release ownership of the mutex - //----------------------------------------------------- - bool Release(); - - // To match regular CThreadMutex: - void Lock() { Wait(); } - void Lock( unsigned timeout ) { Wait( timeout ); } - void Unlock() { Release(); } - bool AssertOwnedByCurrentThread() { return true; } - void SetTrace( bool ) {} - -private: - CThreadFullMutex( const CThreadFullMutex & ); - CThreadFullMutex &operator=( const CThreadFullMutex & ); -}; -#endif - - -class TT_CLASS CThreadEvent : public CThreadSyncObject -{ -public: - CThreadEvent( bool fManualReset = false ); - - //----------------------------------------------------- - // Set the state to signaled - //----------------------------------------------------- - bool Set(); - - //----------------------------------------------------- - // Set the state to nonsignaled - //----------------------------------------------------- - bool Reset(); - - //----------------------------------------------------- - // Check if the event is signaled - //----------------------------------------------------- - bool Check(); - - bool Wait( uint32 dwTimeout = TT_INFINITE ); - -private: - CThreadEvent( const CThreadEvent & ); - CThreadEvent &operator=( const CThreadEvent & ); -#ifdef _LINUX - CInterlockedInt m_cSet; -#endif -}; - -// Hard-wired manual event for use in array declarations -class CThreadManualEvent : public CThreadEvent -{ -public: - CThreadManualEvent() - : CThreadEvent( true ) - { - } -}; - -inline int ThreadWaitForEvents( int nEvents, const CThreadEvent *pEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE ) -{ -#ifdef _LINUX - Assert(0); - return 0; -#else - return ThreadWaitForObjects( nEvents, (const HANDLE *)pEvents, bWaitAll, timeout ); -#endif -} - -//----------------------------------------------------------------------------- -// -// CThreadRWLock -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThreadRWLock -{ -public: - CThreadRWLock(); - - void LockForRead(); - void UnlockRead(); - void LockForWrite(); - void UnlockWrite(); - - void LockForRead() const { const_cast(this)->LockForRead(); } - void UnlockRead() const { const_cast(this)->UnlockRead(); } - void LockForWrite() const { const_cast(this)->LockForWrite(); } - void UnlockWrite() const { const_cast(this)->UnlockWrite(); } - -private: - void WaitForRead(); - - CThreadFastMutex m_mutex; - CThreadEvent m_CanWrite; - CThreadEvent m_CanRead; - - int m_nWriters; - int m_nActiveReaders; - int m_nPendingReaders; -}; - -//----------------------------------------------------------------------------- -// -// CThreadSpinRWLock -// -//----------------------------------------------------------------------------- - -#define TFRWL_ALIGN ALIGN8 - -TFRWL_ALIGN -class TT_CLASS CThreadSpinRWLock -{ -public: - CThreadSpinRWLock() { COMPILE_TIME_ASSERT( sizeof( LockInfo_t ) == sizeof( int64 ) ); Assert( (int)this % 8 == 0 ); memset( this, 0, sizeof( *this ) ); } - - bool TryLockForWrite(); - bool TryLockForRead(); - - void LockForRead(); - void UnlockRead(); - void LockForWrite(); - void UnlockWrite(); - - bool TryLockForWrite() const { return const_cast(this)->TryLockForWrite(); } - bool TryLockForRead() const { return const_cast(this)->TryLockForRead(); } - void LockForRead() const { const_cast(this)->LockForRead(); } - void UnlockRead() const { const_cast(this)->UnlockRead(); } - void LockForWrite() const { const_cast(this)->LockForWrite(); } - void UnlockWrite() const { const_cast(this)->UnlockWrite(); } - -private: - struct LockInfo_t - { - uint32 m_writerId; - int m_nReaders; - }; - - bool AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand ); - bool TryLockForWrite( const uint32 threadId ); - void SpinLockForWrite( const uint32 threadId ); - - volatile LockInfo_t m_lockInfo; - CInterlockedInt m_nWriters; -}; - -//----------------------------------------------------------------------------- -// -// A thread wrapper similar to a Java thread. -// -//----------------------------------------------------------------------------- - -class TT_CLASS CThread -{ -public: - CThread(); - virtual ~CThread(); - - //----------------------------------------------------- - - const char *GetName(); - void SetName( const char * ); - - size_t CalcStackDepth( void *pStackVariable ) { return ((byte *)m_pStackBase - (byte *)pStackVariable); } - - //----------------------------------------------------- - // Functions for the other threads - //----------------------------------------------------- - - // Start thread running - error if already running - virtual bool Start( unsigned nBytesStack = 0 ); - - // Returns true if thread has been created and hasn't yet exited - bool IsAlive(); - - // This method causes the current thread to wait until this thread - // is no longer alive. - bool Join( unsigned timeout = TT_INFINITE ); - -#ifdef _WIN32 - // Access the thread handle directly - HANDLE GetThreadHandle(); - uint GetThreadId(); -#endif - - //----------------------------------------------------- - - int GetResult(); - - //----------------------------------------------------- - // Functions for both this, and maybe, and other threads - //----------------------------------------------------- - - // Forcibly, abnormally, but relatively cleanly stop the thread - void Stop( int exitCode = 0 ); - - // Get the priority - int GetPriority() const; - - // Set the priority - bool SetPriority( int ); - - // Suspend a thread - unsigned Suspend(); - - // Resume a suspended thread - unsigned Resume(); - - // Force hard-termination of thread. Used for critical failures. - bool Terminate( int exitCode = 0 ); - - //----------------------------------------------------- - // Global methods - //----------------------------------------------------- - - // Get the Thread object that represents the current thread, if any. - // Can return NULL if the current thread was not created using - // CThread - static CThread *GetCurrentCThread(); - - // Offer a context switch. Under Win32, equivalent to Sleep(0) -#ifdef Yield -#undef Yield -#endif - static void Yield(); - - // This method causes the current thread to yield and not to be - // scheduled for further execution until a certain amount of real - // time has elapsed, more or less. - static void Sleep( unsigned duration ); - -protected: - - // Optional pre-run call, with ability to fail-create. Note Init() - // is forced synchronous with Start() - virtual bool Init(); - - // Thread will run this function on startup, must be supplied by - // derived class, performs the intended action of the thread. - virtual int Run() = 0; - - // Called when the thread exits - virtual void OnExit(); - -#ifdef _WIN32 - // Allow for custom start waiting - virtual bool WaitForCreateComplete( CThreadEvent *pEvent ); -#endif - - // "Virtual static" facility - typedef unsigned (__stdcall *ThreadProc_t)( void * ); - virtual ThreadProc_t GetThreadProc(); - - CThreadMutex m_Lock; - -private: - enum Flags - { - SUPPORT_STOP_PROTOCOL = 1 << 0 - }; - - // Thread initially runs this. param is actually 'this'. function - // just gets this and calls ThreadProc - struct ThreadInit_t - { - CThread * pThread; -#ifdef _WIN32 - CThreadEvent *pInitCompleteEvent; -#endif - bool * pfInitSuccess; - }; - - static unsigned __stdcall ThreadProc( void * pv ); - - // make copy constructor and assignment operator inaccessible - CThread( const CThread & ); - CThread &operator=( const CThread & ); - -#ifdef _WIN32 - HANDLE m_hThread; - ThreadId_t m_threadId; -#elif _LINUX - pthread_t m_threadId; -#endif - int m_result; - char m_szName[32]; - void * m_pStackBase; - unsigned m_flags; -}; - -//----------------------------------------------------------------------------- -// Simple thread class encompasses the notion of a worker thread, handing -// synchronized communication. -//----------------------------------------------------------------------------- - -#ifdef _WIN32 - -// These are internal reserved error results from a call attempt -enum WTCallResult_t -{ - WTCR_FAIL = -1, - WTCR_TIMEOUT = -2, - WTCR_THREAD_GONE = -3, -}; - -class TT_CLASS CWorkerThread : public CThread -{ -public: - CWorkerThread(); - - //----------------------------------------------------- - // - // Inter-thread communication - // - // Calls in either direction take place on the same "channel." - // Seperate functions are specified to make identities obvious - // - //----------------------------------------------------- - - // Master: Signal the thread, and block for a response - int CallWorker( unsigned, unsigned timeout = TT_INFINITE, bool fBoostWorkerPriorityToMaster = true ); - - // Worker: Signal the thread, and block for a response - int CallMaster( unsigned, unsigned timeout = TT_INFINITE ); - - // Wait for the next request - bool WaitForCall( unsigned dwTimeout, unsigned *pResult = NULL ); - bool WaitForCall( unsigned *pResult = NULL ); - - // Is there a request? - bool PeekCall( unsigned *pParam = NULL ); - - // Reply to the request - void Reply( unsigned ); - - // Wait for a reply in the case when CallWorker() with timeout != TT_INFINITE - int WaitForReply( unsigned timeout = TT_INFINITE ); - - // If you want to do WaitForMultipleObjects you'll need to include - // this handle in your wait list or you won't be responsive - HANDLE GetCallHandle(); - - // Find out what the request was - unsigned GetCallParam() const; - - // Boost the worker thread to the master thread, if worker thread is lesser, return old priority - int BoostPriority(); - -protected: - typedef uint32 (__stdcall *WaitFunc_t)( uint32 nHandles, const HANDLE*pHandles, int bWaitAll, uint32 timeout ); - int Call( unsigned, unsigned timeout, bool fBoost, WaitFunc_t = NULL ); - int WaitForReply( unsigned timeout, WaitFunc_t ); - -private: - CWorkerThread( const CWorkerThread & ); - CWorkerThread &operator=( const CWorkerThread & ); - -#ifdef _WIN32 - CThreadEvent m_EventSend; - CThreadEvent m_EventComplete; -#endif - - unsigned m_Param; - int m_ReturnVal; -}; - -#else - -typedef CThread CWorkerThread; - -#endif - -// a unidirectional message queue. A queue of type T. Not especially high speed since each message -// is malloced/freed. Note that if your message class has destructors/constructors, they MUST be -// thread safe! -template class CMessageQueue -{ - CThreadEvent SignalEvent; // signals presence of data - CThreadMutex QueueAccessMutex; - - // the parts protected by the mutex - struct MsgNode - { - MsgNode *Next; - T Data; - }; - - MsgNode *Head; - MsgNode *Tail; - -public: - CMessageQueue( void ) - { - Head = Tail = NULL; - } - - // check for a message. not 100% reliable - someone could grab the message first - bool MessageWaiting( void ) - { - return ( Head != NULL ); - } - - void WaitMessage( T *pMsg ) - { - for(;;) - { - while( ! MessageWaiting() ) - SignalEvent.Wait(); - QueueAccessMutex.Lock(); - if (! Head ) - { - // multiple readers could make this null - QueueAccessMutex.Unlock(); - continue; - } - *( pMsg ) = Head->Data; - MsgNode *remove_this = Head; - Head = Head->Next; - if (! Head) // if empty, fix tail ptr - Tail = NULL; - QueueAccessMutex.Unlock(); - delete remove_this; - break; - } - } - - void QueueMessage( T const &Msg) - { - MsgNode *new1=new MsgNode; - new1->Data=Msg; - new1->Next=NULL; - QueueAccessMutex.Lock(); - if ( Tail ) - { - Tail->Next=new1; - Tail = new1; - } - else - { - Head = new1; - Tail = new1; - } - SignalEvent.Set(); - QueueAccessMutex.Unlock(); - } -}; - - -//----------------------------------------------------------------------------- -// -// CThreadMutex. Inlining to reduce overhead and to allow client code -// to decide debug status (tracing) -// -//----------------------------------------------------------------------------- - -#ifdef _WIN32 -typedef struct _RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION; -typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; - -#ifndef _X360 -extern "C" -{ - void __declspec(dllimport) __stdcall InitializeCriticalSection(CRITICAL_SECTION *); - void __declspec(dllimport) __stdcall EnterCriticalSection(CRITICAL_SECTION *); - void __declspec(dllimport) __stdcall LeaveCriticalSection(CRITICAL_SECTION *); - void __declspec(dllimport) __stdcall DeleteCriticalSection(CRITICAL_SECTION *); -}; -#endif - -//--------------------------------------------------------- - -inline void CThreadMutex::Lock() -{ -#ifdef THREAD_MUTEX_TRACING_ENABLED - uint thisThreadID = ThreadGetCurrentId(); - if ( m_bTrace && m_currentOwnerID && ( m_currentOwnerID != thisThreadID ) ) - Msg( "Thread %u about to wait for lock %x owned by %u\n", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID ); -#endif - - VCRHook_EnterCriticalSection((CRITICAL_SECTION *)&m_CriticalSection); - -#ifdef THREAD_MUTEX_TRACING_ENABLED - if (m_lockCount == 0) - { - // we now own it for the first time. Set owner information - m_currentOwnerID = thisThreadID; - if ( m_bTrace ) - Msg( "Thread %u now owns lock 0x%x\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection ); - } - m_lockCount++; -#endif -} - -//--------------------------------------------------------- - -inline void CThreadMutex::Unlock() -{ -#ifdef THREAD_MUTEX_TRACING_ENABLED - AssertMsg( m_lockCount >= 1, "Invalid unlock of thread lock" ); - m_lockCount--; - if (m_lockCount == 0) - { - if ( m_bTrace ) - Msg( "Thread %u releasing lock 0x%x\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection ); - m_currentOwnerID = 0; - } -#endif - LeaveCriticalSection((CRITICAL_SECTION *)&m_CriticalSection); -} - -//--------------------------------------------------------- - -inline bool CThreadMutex::AssertOwnedByCurrentThread() -{ -#ifdef THREAD_MUTEX_TRACING_ENABLED - if (ThreadGetCurrentId() == m_currentOwnerID) - return true; - AssertMsg3( 0, "Expected thread %u as owner of lock 0x%x, but %u owns", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID ); - return false; -#else - return true; -#endif -} - -//--------------------------------------------------------- - -inline void CThreadMutex::SetTrace( bool bTrace ) -{ -#ifdef THREAD_MUTEX_TRACING_ENABLED - m_bTrace = bTrace; -#endif -} - -//--------------------------------------------------------- - -#elif _LINUX - -inline CThreadMutex::CThreadMutex() -{ - // enable recursive locks as we need them - pthread_mutexattr_init( &m_Attr ); - pthread_mutexattr_settype( &m_Attr, PTHREAD_MUTEX_RECURSIVE_NP ); - pthread_mutex_init( &m_Mutex, &m_Attr ); -} - -//--------------------------------------------------------- - -inline CThreadMutex::~CThreadMutex() -{ - pthread_mutex_destroy( &m_Mutex ); -} - -//--------------------------------------------------------- - -inline void CThreadMutex::Lock() -{ - pthread_mutex_lock( &m_Mutex ); -} - -//--------------------------------------------------------- - -inline void CThreadMutex::Unlock() -{ - pthread_mutex_unlock( &m_Mutex ); -} - -//--------------------------------------------------------- - -inline bool CThreadMutex::AssertOwnedByCurrentThread() -{ - return true; -} - -//--------------------------------------------------------- - -inline void CThreadMutex::SetTrace(bool fTrace) -{ -} - -#endif // _LINUX - -//----------------------------------------------------------------------------- -// -// CThreadRWLock inline functions -// -//----------------------------------------------------------------------------- - -inline CThreadRWLock::CThreadRWLock() -: m_CanRead( true ), - m_nWriters( 0 ), - m_nActiveReaders( 0 ), - m_nPendingReaders( 0 ) -{ -} - -inline void CThreadRWLock::LockForRead() -{ - m_mutex.Lock(); - if ( m_nWriters) - { - WaitForRead(); - } - m_nActiveReaders++; - m_mutex.Unlock(); -} - -inline void CThreadRWLock::UnlockRead() -{ - m_mutex.Lock(); - m_nActiveReaders--; - if ( m_nActiveReaders == 0 && m_nWriters != 0 ) - { - m_CanWrite.Set(); - } - m_mutex.Unlock(); -} - - -//----------------------------------------------------------------------------- -// -// CThreadSpinRWLock inline functions -// -//----------------------------------------------------------------------------- - -inline bool CThreadSpinRWLock::AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand ) -{ - return ThreadInterlockedAssignIf64( (int64 *)&m_lockInfo, *((int64 *)&newValue), *((int64 *)&comperand) ); -} - -inline bool CThreadSpinRWLock::TryLockForWrite( const uint32 threadId ) -{ - // In order to grab a write lock, there can be no readers and no owners of the write lock - if ( m_lockInfo.m_nReaders > 0 || ( m_lockInfo.m_writerId && m_lockInfo.m_writerId != threadId ) ) - { - return false; - } - - static const LockInfo_t oldValue = { 0, 0 }; - LockInfo_t newValue = { threadId, 0 }; - const bool bSuccess = AssignIf( newValue, oldValue ); -#if defined(_X360) - if ( bSuccess ) - { - // X360TBD: Serious perf implications. Not Yet. __sync(); - } -#endif - return bSuccess; -} - -inline bool CThreadSpinRWLock::TryLockForWrite() -{ - m_nWriters++; - if ( !TryLockForWrite( ThreadGetCurrentId() ) ) - { - m_nWriters--; - return false; - } - return true; -} - -inline bool CThreadSpinRWLock::TryLockForRead() -{ - if ( m_nWriters != 0 ) - { - return false; - } - // In order to grab a write lock, the number of readers must not change and no thread can own the write - LockInfo_t oldValue; - LockInfo_t newValue; - - oldValue.m_nReaders = m_lockInfo.m_nReaders; - oldValue.m_writerId = 0; - newValue.m_nReaders = oldValue.m_nReaders + 1; - newValue.m_writerId = 0; - - const bool bSuccess = AssignIf( newValue, oldValue ); -#if defined(_X360) - if ( bSuccess ) - { - // X360TBD: Serious perf implications. Not Yet. __sync(); - } -#endif - return bSuccess; -} - -inline void CThreadSpinRWLock::LockForWrite() -{ - const uint32 threadId = ThreadGetCurrentId(); - - m_nWriters++; - - if ( !TryLockForWrite( threadId ) ) - { - ThreadPause(); - SpinLockForWrite( threadId ); - } -} - -//----------------------------------------------------------------------------- - -#if defined( _WIN32 ) -#pragma warning(pop) -#endif - -#endif // THREADTOOLS_H diff --git a/Resources/NetHook/tier0/tslist.h b/Resources/NetHook/tier0/tslist.h deleted file mode 100644 index c0df0b25..00000000 --- a/Resources/NetHook/tier0/tslist.h +++ /dev/null @@ -1,794 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: -// -// LIFO from disassembly of Windows API and http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf -// FIFO from http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf -// -//============================================================================= - -#ifndef TSLIST_H -#define TSLIST_H - -#if defined( _WIN32 ) -#pragma once -#endif - -#if ( defined(_WIN64) || defined(_X360) ) -#define USE_NATIVE_SLIST -#endif - -#if defined( USE_NATIVE_SLIST ) && !defined( _X360 ) -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include "tier0/dbg.h" -#include "tier0/threadtools.h" - -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- - -#if defined(_WIN64) -#define TSLIST_HEAD_ALIGNMENT MEMORY_ALLOCATION_ALIGNMENT -#define TSLIST_NODE_ALIGNMENT MEMORY_ALLOCATION_ALIGNMENT -#else -#define TSLIST_HEAD_ALIGNMENT 8 -#define TSLIST_NODE_ALIGNMENT 8 -#endif - -#define TSLIST_HEAD_ALIGN DECL_ALIGN(TSLIST_HEAD_ALIGNMENT) -#define TSLIST_NODE_ALIGN DECL_ALIGN(TSLIST_NODE_ALIGNMENT) - -//----------------------------------------------------------------------------- - -PLATFORM_INTERFACE bool RunTSQueueTests( int nListSize = 10000, int nTests = 1 ); -PLATFORM_INTERFACE bool RunTSListTests( int nListSize = 10000, int nTests = 1 ); - -//----------------------------------------------------------------------------- -// Lock free list. -//----------------------------------------------------------------------------- -//#define USE_NATIVE_SLIST - -#ifdef USE_NATIVE_SLIST -typedef SLIST_ENTRY TSLNodeBase_t; -typedef SLIST_HEADER TSLHead_t; -#else -struct TSLIST_NODE_ALIGN TSLNodeBase_t -{ - TSLNodeBase_t *Next; // name to match Windows -}; - -union TSLHead_t -{ - struct Value_t - { - TSLNodeBase_t *Next; - int16 Depth; - int16 Sequence; - } value; - - int64 value64; -}; -#endif - -//------------------------------------- - -class TSLIST_HEAD_ALIGN CTSListBase -{ -public: - CTSListBase() - { - if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 ) - { - Error( "CTSListBase: Misaligned list\n" ); - DebuggerBreak(); - } - -#ifdef USE_NATIVE_SLIST - InitializeSListHead( &m_Head ); -#else - m_Head.value64 = (int64)0; -#endif - } - - ~CTSListBase() - { - Detach(); - } - - TSLNodeBase_t *Push( TSLNodeBase_t *pNode ) - { - if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 ) - { - Error( "CTSListBase: Misaligned node\n" ); - DebuggerBreak(); - } - -#ifdef USE_NATIVE_SLIST -#ifdef _X360 - // integrated write-release barrier - return (TSLNodeBase_t *)InterlockedPushEntrySListRelease( &m_Head, pNode ); -#else - return (TSLNodeBase_t *)InterlockedPushEntrySList( &m_Head, pNode ); -#endif -#else - TSLHead_t oldHead; - TSLHead_t newHead; - - for (;;) - { - oldHead.value64 = m_Head.value64; - pNode->Next = oldHead.value.Next; - newHead.value.Next = pNode; - *((uint32 *)&newHead.value.Depth) = *((uint32 *)&oldHead.value.Depth) + 0x10001; - - if ( ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) ) - { - break; - } - ThreadPause(); - }; - - return (TSLNodeBase_t *)oldHead.value.Next; -#endif - } - - TSLNodeBase_t *Pop() - { -#ifdef USE_NATIVE_SLIST -#ifdef _X360 - // integrated read-acquire barrier - TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySListAcquire( &m_Head ); -#else - TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySList( &m_Head ); -#endif - return pNode; -#else - TSLHead_t oldHead; - TSLHead_t newHead; - - for (;;) - { - oldHead.value64 = m_Head.value64; - if ( !oldHead.value.Next ) - return NULL; - - newHead.value.Next = oldHead.value.Next->Next; - *((uint32 *)&newHead.value.Depth) = *((uint32 *)&oldHead.value.Depth) - 1; - - if ( ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) ) - { - break; - } - ThreadPause(); - }; - - return (TSLNodeBase_t *)oldHead.value.Next; -#endif - } - - TSLNodeBase_t *Detach() - { -#ifdef USE_NATIVE_SLIST - TSLNodeBase_t *pBase = (TSLNodeBase_t *)InterlockedFlushSList( &m_Head ); -#ifdef _X360 - __lwsync(); // read-acquire barrier -#endif - return pBase; -#else - TSLHead_t oldHead; - TSLHead_t newHead; - - do - { - ThreadPause(); - - oldHead.value64 = m_Head.value64; - if ( !oldHead.value.Next ) - return NULL; - - newHead.value.Next = NULL; - *((uint32 *)&newHead.value.Depth) = *((uint32 *)&oldHead.value.Depth) & 0xffff0000; - - } while( !ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) ); - - return (TSLNodeBase_t *)oldHead.value.Next; -#endif - } - - int Count() const - { -#ifdef USE_NATIVE_SLIST - return QueryDepthSList( &m_Head ); -#else - return m_Head.value.Depth; -#endif - } - -private: - TSLHead_t m_Head; -}; - -//------------------------------------- - -template -class TSLIST_HEAD_ALIGN CTSSimpleList : public CTSListBase -{ -public: - void Push( T *pNode ) - { - Assert( sizeof(T) >= sizeof(TSLNodeBase_t) ); - CTSListBase::Push( (TSLNodeBase_t *)pNode ); - } - - T *Pop() - { - return (T *)CTSListBase::Pop(); - } -}; - -//------------------------------------- - -template -class TSLIST_HEAD_ALIGN CTSList : public CTSListBase -{ -public: - struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t - { - Node_t() {} - Node_t( const T &init ) : elem( init ) {} - - T elem; - - }; - - ~CTSList() - { - Purge(); - } - - void Purge() - { - Node_t *pCurrent = Detach(); - Node_t *pNext; - while ( pCurrent ) - { - pNext = (Node_t *)pCurrent->Next; - delete pCurrent; - pCurrent = pNext; - } - } - - void RemoveAll() - { - Purge(); - } - - Node_t *Push( Node_t *pNode ) - { - return (Node_t *)CTSListBase::Push( pNode ); - } - - Node_t *Pop() - { - return (Node_t *)CTSListBase::Pop(); - } - - void PushItem( const T &init ) - { - Push( new Node_t( init ) ); - } - - bool PopItem( T *pResult) - { - Node_t *pNode = Pop(); - if ( !pNode ) - return false; - *pResult = pNode->elem; - delete pNode; - return true; - } - - Node_t *Detach() - { - return (Node_t *)CTSListBase::Detach(); - } - -}; - -// this is a replacement for CTSList<> and CObjectPool<> that does not -// have a per-item, per-alloc new/delete overhead -// similar to CTSSimpleList except that it allocates it's own pool objects -// and frees them on destruct. Also it does not overlay the TSNodeBase_t memory -// on T's memory -template< class T > -class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase -{ - // packs the node and the item (T) into a single struct and pools those - struct TSLIST_NODE_ALIGN simpleTSPoolStruct_t : public TSLNodeBase_t - { - T elem; - }; - -public: - - ~CTSPool() - { - simpleTSPoolStruct_t *pNode = NULL; - while ( 1 ) - { - pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop(); - if ( !pNode ) - break; - delete pNode; - } - } - - void PutObject( T *pInfo ) - { - char *pElem = (char *)pInfo; - pElem -= offsetof(simpleTSPoolStruct_t,elem); - simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)pElem; - - CTSListBase::Push( pNode ); - } - - T *GetObject() - { - simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop(); - if ( !pNode ) - { - pNode = new simpleTSPoolStruct_t; - } - return &pNode->elem; - } -}; - -//------------------------------------- - -template -class TSLIST_HEAD_ALIGN CTSListWithFreeList : public CTSListBase -{ -public: - struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t - { - Node_t() {} - Node_t( const T &init ) : elem( init ) {} - - T elem; - }; - - ~CTSListWithFreeList() - { - Purge(); - } - - void Purge() - { - Node_t *pCurrent = Detach(); - Node_t *pNext; - while ( pCurrent ) - { - pNext = (Node_t *)pCurrent->Next; - delete pCurrent; - pCurrent = pNext; - } - pCurrent = (Node_t *)m_FreeList.Detach(); - while ( pCurrent ) - { - pNext = (Node_t *)pCurrent->Next; - delete pCurrent; - pCurrent = pNext; - } - } - - void RemoveAll() - { - Node_t *pCurrent = Detach(); - Node_t *pNext; - while ( pCurrent ) - { - pNext = (Node_t *)pCurrent->Next; - m_FreeList.Push( pCurrent ); - pCurrent = pNext; - } - } - - Node_t *Push( Node_t *pNode ) - { - return (Node_t *)CTSListBase::Push( pNode ); - } - - Node_t *Pop() - { - return (Node_t *)CTSListBase::Pop(); - } - - void PushItem( const T &init ) - { - Node_t *pNode = (Node_t *)m_FreeList.Pop(); - if ( !pNode ) - { - pNode = new Node_t; - } - pNode->elem = init; - Push( pNode ); - } - - bool PopItem( T *pResult) - { - Node_t *pNode = Pop(); - if ( !pNode ) - return false; - *pResult = pNode->elem; - m_FreeList.Push( pNode ); - return true; - } - - Node_t *Detach() - { - return (Node_t *)CTSListBase::Detach(); - } - - void FreeNode( Node_t *pNode ) - { - m_FreeList.Push( pNode ); - } - -private: - CTSListBase m_FreeList; -}; - -//----------------------------------------------------------------------------- -// Lock free queue -// -// A special consideration: the element type should be simple. This code -// actually dereferences freed nodes as part of pop, but later detects -// that. If the item in the queue is a complex type, only bad things can -// come of that. Also, therefore, if you're using Push/Pop instead of -// push item, be aware that the node memory cannot be freed until -// all threads that might have been popping have completed the pop. -// The PushItem()/PopItem() for handles this by keeping a persistent -// free list. Dont mix Push/PushItem. Note also nodes will be freed at the end, -// and are expected to have been allocated with operator new. -//----------------------------------------------------------------------------- - -template -class TSLIST_HEAD_ALIGN CTSQueue -{ -public: - struct TSLIST_NODE_ALIGN Node_t - { - Node_t() {} - Node_t( const T &init ) : elem( init ) {} - - Node_t *pNext; - T elem; - }; - - union TSLIST_HEAD_ALIGN NodeLink_t - { - struct Value_t - { - Node_t *pNode; - int32 sequence; - } value; - - int64 value64; - }; - - CTSQueue() - { - COMPILE_TIME_ASSERT( sizeof(Node_t) >= sizeof(TSLNodeBase_t) ); - if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 ) - { - Error( "CTSQueue: Misaligned queue\n" ); - DebuggerBreak(); - } - if ( ((size_t)&m_Tail) % TSLIST_HEAD_ALIGNMENT != 0 ) - { - Error( "CTSQueue: Misaligned queue\n" ); - DebuggerBreak(); - } - m_Count = 0; - m_Head.value.sequence = m_Tail.value.sequence = 0; - m_Head.value.pNode = m_Tail.value.pNode = new Node_t; // list always contains a dummy node - m_Head.value.pNode->pNext = End(); - } - - ~CTSQueue() - { - Purge(); - Assert( m_Count == 0 ); - Assert( m_Head.value.pNode == m_Tail.value.pNode ); - Assert( m_Head.value.pNode->pNext == End() ); - delete m_Head.value.pNode; - } - - // Note: Purge, RemoveAll, and Validate are *not* threadsafe - void Purge() - { - if ( IsDebug() ) - { - Validate(); - } - - Node_t *pNode; - while ( ( pNode = Pop() ) != NULL ) - { - delete pNode; - } - - while ( ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL ) - { - delete pNode; - } - - Assert( m_Count == 0 ); - Assert( m_Head.value.pNode == m_Tail.value.pNode ); - Assert( m_Head.value.pNode->pNext == End() ); - - m_Head.value.sequence = m_Tail.value.sequence = 0; - } - - void RemoveAll() - { - if ( IsDebug() ) - { - Validate(); - } - - Node_t *pNode; - while ( ( pNode = Pop() ) != NULL ) - { - m_FreeNodes.Push( (TSLNodeBase_t *)pNode ); - } - } - - bool Validate() - { - bool bResult = true; - int nNodes = 0; - if ( m_Tail.value.pNode->pNext != End() ) - { - DebuggerBreakIfDebugging(); - bResult = false; - } - - if ( m_Count == 0 ) - { - if ( m_Head.value.pNode != m_Tail.value.pNode ) - { - DebuggerBreakIfDebugging(); - bResult = false; - } - } - - Node_t *pNode = m_Head.value.pNode; - while ( pNode != End() ) - { - nNodes++; - pNode = pNode->pNext; - } - - nNodes--;// skip dummy node - - if ( nNodes != m_Count ) - { - DebuggerBreakIfDebugging(); - bResult = false; - } - - if ( !bResult ) - { - Msg( "Corrupt CTSQueueDetected" ); - } - - return bResult; - } - - void FinishPush( Node_t *pNode, const NodeLink_t &oldTail ) - { - NodeLink_t newTail; - - newTail.value.pNode = pNode; - newTail.value.sequence = oldTail.value.sequence + 1; - -#ifdef _X360 - __lwsync(); // write-release barrier -#endif - InterlockedCompareExchangeNodeLink( &m_Tail, newTail, oldTail ); - } - - Node_t *Push( Node_t *pNode ) - { -#ifdef _DEBUG - if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 ) - { - Error( "CTSListBase: Misaligned node\n" ); - DebuggerBreak(); - } -#endif - - NodeLink_t oldTail; - - pNode->pNext = End(); - - for (;;) - { - oldTail = m_Tail; - if ( InterlockedCompareExchangeNode( &(oldTail.value.pNode->pNext), pNode, End() ) == End() ) - { - break; - } - else - { - // Another thread is trying to push, help it along - FinishPush( oldTail.value.pNode->pNext, oldTail ); - } - } - - FinishPush( pNode, oldTail ); - - m_Count++; - - return oldTail.value.pNode; - } - - Node_t *Pop() - { - #define TSQUEUE_BAD_NODE_LINK ((Node_t *)0xdeadbeef) - NodeLink_t * volatile pHead = &m_Head; - NodeLink_t * volatile pTail = &m_Tail; - Node_t * volatile * pHeadNode = &m_Head.value.pNode; - volatile int * volatile pHeadSequence = &m_Head.value.sequence; - Node_t * volatile * pTailNode = &pTail->value.pNode; - - NodeLink_t head; - NodeLink_t newHead; - Node_t *pNext; - int tailSequence; - T elem; - - for (;;) - { - head.value.sequence = *pHeadSequence; // must grab sequence first, which allows condition below to ensure pNext is valid -#ifdef _X360 - __lwsync(); // 360 needs a barrier to prevent reordering of these assignments -#endif - head.value.pNode = *pHeadNode; - tailSequence = pTail->value.sequence; - pNext = head.value.pNode->pNext; - - if ( pNext && head.value.sequence == *pHeadSequence ) // Checking pNext only to force optimizer to not reorder the assignment to pNext and the compare of the sequence - { - if ( bTestOptimizer ) - { - if ( pNext == TSQUEUE_BAD_NODE_LINK ) - { - Msg( "Bad node link detected\n" ); - continue; - } - } - if ( head.value.pNode == *pTailNode ) - { - if ( pNext == End() ) - { - return NULL; - } - - // Another thread is trying to push, help it along - NodeLink_t &oldTail = head; // just reuse local memory for head to build old tail - oldTail.value.sequence = tailSequence; // reuse head pNode - FinishPush( pNext, oldTail ); - } - else if ( pNext != End() ) - { - elem = pNext->elem; // NOTE: next could be a freed node here, by design - newHead.value.pNode = pNext; - newHead.value.sequence = head.value.sequence + 1; - if ( InterlockedCompareExchangeNodeLink( pHead, newHead, head ) ) - { -#ifdef _X360 - __lwsync(); // read-acquire barrier -#endif - if ( bTestOptimizer ) - { - head.value.pNode->pNext = TSQUEUE_BAD_NODE_LINK; - } - break; - } - } - } - } - - m_Count--; - head.value.pNode->elem = elem; - return head.value.pNode; - } - - void FreeNode( Node_t *pNode ) - { - m_FreeNodes.Push( (TSLNodeBase_t *)pNode ); - } - - void PushItem( const T &init ) - { - Node_t *pNode = (Node_t *)m_FreeNodes.Pop(); - if ( pNode ) - { - pNode->elem = init; - } - else - { - pNode = new Node_t( init ); - } - Push( pNode ); - } - - bool PopItem( T *pResult) - { - Node_t *pNode = Pop(); - if ( !pNode ) - return false; - *pResult = pNode->elem; - m_FreeNodes.Push( (TSLNodeBase_t *)pNode ); - return true; - } - - int Count() - { - return m_Count; - } - -private: - Node_t *End() { return (Node_t *)this; } // just need a unique signifier - -#ifndef _WIN64 - Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand ) - { - return (Node_t *)::ThreadInterlockedCompareExchangePointer( (void **)ppNode, value, comperand ); - } - - bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand ) - { - return ThreadInterlockedAssignIf64( (int64 *)pLink, value.value64, comperand.value64 ); - } - -#else - Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand ) - { - AUTO_LOCK( m_ExchangeMutex ); - Node_t *retVal = *ppNode; - if ( *ppNode == comperand ) - *ppNode = value; - return retVal; - } - - bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand ) - { - AUTO_LOCK( m_ExchangeMutex ); - if ( pLink->value64 == comperand.value64 ) - { - pLink->value64 = value.value64; - return true; - } - return false; - } - - CThreadFastMutex m_ExchangeMutex; -#endif - - NodeLink_t m_Head; - NodeLink_t m_Tail; - - CInterlockedInt m_Count; - - CTSListBase m_FreeNodes; -}; - -#include "tier0/memdbgoff.h" - -#endif // TSLIST_H diff --git a/Resources/NetHook/tier0/validator.h b/Resources/NetHook/tier0/validator.h deleted file mode 100644 index d2cc2dba..00000000 --- a/Resources/NetHook/tier0/validator.h +++ /dev/null @@ -1,73 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - - -#include "valobject.h" - -#ifndef VALIDATOR_H -#define VALIDATOR_H - -#ifdef _WIN32 -#pragma once -#endif - - -#ifdef DBGFLAG_VALIDATE - - -class CValidator -{ -public: - // Constructors & destructors - CValidator( void ); - ~CValidator( void ); - - // Call this each time we enter a new Validate function - void Push( tchar *pchType, void *pvObj, tchar *pchName ); - - // Call this each time we exit a Validate function - void Pop( void ); - - // Claim ownership of a memory block - void ClaimMemory( void *pvMem ); - - // Finish performing a check and perform necessary computations - void Finalize( void ); - - // Render our results to the console - void RenderObjects( int cubThreshold ); // Render all reported objects - void RenderLeaks( void ); // Render all memory leaks - - // List manipulation functions: - CValObject *FindObject( void *pvObj ); // Returns CValObject containing pvObj, or NULL. - void DiffAgainst( CValidator *pOtherValidator ); // Removes any entries from this validator that are also present in the other. - - // Accessors - bool BMemLeaks( void ) { return m_bMemLeaks; }; - CValObject *PValObjectFirst( void ) { return m_pValObjectFirst; }; - - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures - - -private: - CValObject *m_pValObjectFirst; // Linked list of all ValObjects - CValObject *m_pValObjectLast; // Last ValObject on the linked list - - CValObject *m_pValObjectCur; // Object we're current processing - - int m_cpvOwned; // Total # of blocks owned - - int m_cpubLeaked; // # of leaked memory blocks - int m_cubLeaked; // Amount of leaked memory - bool m_bMemLeaks; // Has any memory leaked? -}; - - -#endif // DBGFLAG_VALIDATE - - -#endif // VALIDATOR_H diff --git a/Resources/NetHook/tier0/valobject.h b/Resources/NetHook/tier0/valobject.h deleted file mode 100644 index 59ecca68..00000000 --- a/Resources/NetHook/tier0/valobject.h +++ /dev/null @@ -1,72 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: CValObject is used for tracking individual objects that report -// in to CValidator. Whenever a new object reports in (via CValidator::Push), -// we create a new CValObject to aggregate stats for it. -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef VALOBJECT_H -#define VALOBJECT_H -#ifdef _WIN32 -#pragma once -#endif - - -#ifdef DBGFLAG_VALIDATE -class CValObject -{ -public: - // Constructors & destructors - CValObject( void ) { }; - ~CValObject( void ); - - void Init( tchar *pchType, void *pvObj, tchar *pchName, CValObject *pValObjectParent, - CValObject *pValObjectPrev ); - - // Our object has claimed ownership of a memory block - void ClaimMemoryBlock( void *pvMem ); - - // A child of ours has claimed ownership of a memory block - void ClaimChildMemoryBlock( int cubUser ); - - // Accessors - tchar *PchType( void ) { return m_rgchType; }; - void *PvObj( void ) { return m_pvObj; }; - tchar *PchName( void ) { return m_rgchName; }; - CValObject *PValObjectParent( void ) { return m_pValObjectParent; }; - int NLevel( void ) { return m_nLevel; }; - CValObject *PValObjectNext( void ) { return m_pValObjectNext; }; - int CpubMemSelf( void ) { return m_cpubMemSelf; }; - int CubMemSelf( void ) { return m_cubMemSelf; }; - int CpubMemTree( void ) { return m_cpubMemTree; }; - int CubMemTree( void ) { return m_cubMemTree; }; - int NUser( void ) { return m_nUser; }; - void SetNUser( int nUser ) { m_nUser = nUser; }; - void SetBNewSinceSnapshot( bool bNewSinceSnapshot ) { m_bNewSinceSnapshot = bNewSinceSnapshot; } - bool BNewSinceSnapshot( void ) { return m_bNewSinceSnapshot; } - -private: - bool m_bNewSinceSnapshot; // If this block is new since the snapshot. - tchar m_rgchType[64]; // Type of the object we represent - tchar m_rgchName[64]; // Name of this particular object - void *m_pvObj; // Pointer to the object we represent - - CValObject *m_pValObjectParent; // Our parent object in the tree. - int m_nLevel; // Our depth in the tree - - CValObject *m_pValObjectNext; // Next ValObject in the linked list - - int m_cpubMemSelf; // # of memory blocks we own directly - int m_cubMemSelf; // Total size of the memory blocks we own directly - - int m_cpubMemTree; // # of memory blocks owned by us and our children - int m_cubMemTree; // Total size of the memory blocks owned by us and our children - - int m_nUser; // Field provided for use by our users -}; -#endif // DBGFLAG_VALIDATE - - -#endif // VALOBJECT_H diff --git a/Resources/NetHook/tier0/valve_minmax_off.h b/Resources/NetHook/tier0/valve_minmax_off.h deleted file mode 100644 index ade5f284..00000000 --- a/Resources/NetHook/tier0/valve_minmax_off.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef min - #undef min -#endif - -#ifdef max - #undef max -#endif - diff --git a/Resources/NetHook/tier0/valve_minmax_on.h b/Resources/NetHook/tier0/valve_minmax_on.h deleted file mode 100644 index 2ede7be3..00000000 --- a/Resources/NetHook/tier0/valve_minmax_on.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef min - #define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef max - #define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - diff --git a/Resources/NetHook/tier0/valve_off.h b/Resources/NetHook/tier0/valve_off.h deleted file mode 100644 index eced1aac..00000000 --- a/Resources/NetHook/tier0/valve_off.h +++ /dev/null @@ -1,30 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This turns off all Valve-specific #defines. Because we sometimes -// call external include files from inside .cpp files, we need to -// wrap those includes like this: -// #include "tier0/valve_off.h" -// #include -// #include "tier0/valve_on.h" -// -// $NoKeywords: $ -//=============================================================================// - - -#ifdef STEAM - -//----------------------------------------------------------------------------- -// Unicode-related #defines (see wchartypes.h) -//----------------------------------------------------------------------------- -#undef char - - -//----------------------------------------------------------------------------- -// Memory-related #defines -//----------------------------------------------------------------------------- -#undef malloc -#undef realloc -#undef _expand -#undef free - -#endif diff --git a/Resources/NetHook/tier0/valve_on.h b/Resources/NetHook/tier0/valve_on.h deleted file mode 100644 index 4fb50876..00000000 --- a/Resources/NetHook/tier0/valve_on.h +++ /dev/null @@ -1,31 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: This turns on all Valve-specific #defines. Because we sometimes -// call external include files from inside .cpp files, we need to -// wrap those includes like this: -// #include "tier0/valve_off.h" -// #include -// #include "tier0/valve_on.h" -// -// $NoKeywords: $ -//=============================================================================// - - -#ifdef STEAM -//----------------------------------------------------------------------------- -// Unicode-related #defines (see wchartypes.h) -//----------------------------------------------------------------------------- -#ifdef ENFORCE_WCHAR -#define char DontUseChar_SeeWcharOn.h -#endif - - -//----------------------------------------------------------------------------- -// Memory-related #defines -//----------------------------------------------------------------------------- -#define malloc( cub ) HEY_DONT_USE_MALLOC_USE_PVALLOC -#define realloc( pvOld, cub ) HEY_DONT_USE_REALLOC_USE_PVREALLOC -#define _expand( pvOld, cub ) HEY_DONT_USE_EXPAND_USE_PVEXPAND -#define free( pv ) HEY_DONT_USE_FREE_USE_FREEPV - -#endif diff --git a/Resources/NetHook/tier0/vcr_shared.h b/Resources/NetHook/tier0/vcr_shared.h deleted file mode 100644 index c7b6f638..00000000 --- a/Resources/NetHook/tier0/vcr_shared.h +++ /dev/null @@ -1,54 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef VCR_SHARED_H -#define VCR_SHARED_H -#ifdef _WIN32 -#pragma once -#endif - - -#define VCRFILE_VERSION 2 - - -// Identifiers for the things we record. When playing back, these things should -// be asked for in the exact same order (otherwise, the engine isn't making all -// the calls in the same order). -typedef enum -{ - VCREvent_Sys_FloatTime=0, - VCREvent_recvfrom, - VCREvent_SyncToken, - VCREvent_GetCursorPos, - VCREvent_SetCursorPos, - VCREvent_ScreenToClient, - VCREvent_Cmd_Exec, - VCREvent_CmdLine, - VCREvent_RegOpenKeyEx, - VCREvent_RegSetValueEx, - VCREvent_RegQueryValueEx, - VCREvent_RegCreateKeyEx, - VCREvent_RegCloseKey, - VCREvent_PeekMessage, - VCREvent_GameMsg, - VCREvent_GetNumberOfConsoleInputEvents, - VCREvent_ReadConsoleInput, - VCREvent_GetKeyState, - VCREvent_recv, - VCREvent_send, - VCREvent_Generic, - VCREvent_CreateThread, - VCREvent_WaitForSingleObject, - VCREvent_EnterCriticalSection, - VCREvent_Time, - VCREvent_LocalTime, - VCREvent_GenericString, - VCREvent_NUMEVENTS -} VCREvent; - - -#endif // VCR_SHARED_H diff --git a/Resources/NetHook/tier0/vcrmode.h b/Resources/NetHook/tier0/vcrmode.h deleted file mode 100644 index 00e0cba3..00000000 --- a/Resources/NetHook/tier0/vcrmode.h +++ /dev/null @@ -1,306 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: VCR mode records a client's game and allows you to -// play it back and reproduce it exactly. When playing it back, nothing -// is simulated on the server, but all server packets are recorded. -// -// Most of the VCR mode functionality is accomplished through hooks -// called at various points in the engine. -// -// $NoKeywords: $ -//===========================================================================// -#ifndef VCRMODE_H -#define VCRMODE_H - -#ifdef _WIN32 -#include -#endif - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/platform.h" -#include "tier0/vcr_shared.h" -#include "tier0/dbg.h" - -#ifdef _LINUX -DBG_INTERFACE void BuildCmdLine( int argc, tchar **argv ); -tchar *GetCommandLine(); -#endif - -#ifdef _X360 -#define NO_VCR 1 -#endif - - -// Enclose lines of code in this if you don't want anything in them written to or read from the VCR file. -#ifndef NO_VCR -#define NOVCR(x) \ -{\ - VCRSetEnabled(0);\ - x;\ - VCRSetEnabled(1);\ -} -#else -#define NOVCR(x) \ -{\ - x;\ -} -#endif - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -struct InputEvent_t; - - -//----------------------------------------------------------------------------- -// Definitions. -//----------------------------------------------------------------------------- -enum VCRMode_t -{ - VCR_Invalid=-1, - VCR_Disabled=0, - VCR_Record, - VCR_Playback -}; - - -//----------------------------------------------------------------------------- -// Functions. -//----------------------------------------------------------------------------- -abstract_class IVCRHelpers -{ -public: - virtual void ErrorMessage( const tchar *pMsg ) = 0; - virtual void* GetMainWindow() = 0; -}; - - -// Used by the vcrtrace program. -abstract_class IVCRTrace -{ -public: - virtual VCREvent ReadEvent() = 0; - virtual void Read( void *pDest, int size ) = 0; -}; - -typedef struct VCR_s -{ - // Start VCR record or play. - int (*Start)( tchar const *pFilename, bool bRecord, IVCRHelpers *pHelpers ); - void (*End)(); - - // Used by the VCR trace app. - IVCRTrace* (*GetVCRTraceInterface)(); - - // Get the current mode the VCR is in. - VCRMode_t (*GetMode)(); - - // This can be used to block out areas of code that are unpredictable (like things triggered by WM_TIMER messages). - // Note: this enables/disables VCR mode usage on a PER-THREAD basis. The assumption is that you're marking out - // specific sections of code that you don't want to use VCR mode inside of, but you're not intending to - // stop all the other threads from using VCR mode. - void (*SetEnabled)(int bEnabled); - - // This can be called any time to put in a debug check to make sure things are synchronized. - void (*SyncToken)(tchar const *pToken); - - // Hook for Sys_FloatTime(). - double (*Hook_Sys_FloatTime)(double time); - - // Note: this makes no guarantees about msg.hwnd being the same on playback. If it needs to be, then we need to add - // an ID system for Windows and store the ID like in Goldsrc. - int (*Hook_PeekMessage)( - struct tagMSG *msg, - void *hWnd, - unsigned int wMsgFilterMin, - unsigned int wMsgFilterMax, - unsigned int wRemoveMsg - ); - - // Call this to record game messages. - void (*Hook_RecordGameMsg)( const InputEvent_t &event ); - void (*Hook_RecordEndGameMsg)(); - - // Call this to playback game messages until it returns false. - bool (*Hook_PlaybackGameMsg)( InputEvent_t *pEvent ); - - // Hook for recvfrom() calls. This replaces the recvfrom() call. - int (*Hook_recvfrom)(int s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen); - - void (*Hook_GetCursorPos)(struct tagPOINT *pt); - void (*Hook_ScreenToClient)(void *hWnd, struct tagPOINT *pt); - - void (*Hook_Cmd_Exec)(tchar **f); - - tchar* (*Hook_GetCommandLine)(); - - // Registry hooks. - long (*Hook_RegOpenKeyEx)( void *hKey, const tchar *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void *pHKey ); - long (*Hook_RegSetValueEx)(void *hKey, tchar const *lpValueName, unsigned long Reserved, unsigned long dwType, uint8 const *lpData, unsigned long cbData); - long (*Hook_RegQueryValueEx)(void *hKey, tchar const *lpValueName, unsigned long *lpReserved, unsigned long *lpType, uint8 *lpData, unsigned long *lpcbData); - long (*Hook_RegCreateKeyEx)(void *hKey, tchar const *lpSubKey, unsigned long Reserved, tchar *lpClass, unsigned long dwOptions, unsigned long samDesired, void *lpSecurityAttributes, void *phkResult, unsigned long *lpdwDisposition); - void (*Hook_RegCloseKey)(void *hKey); - - // hInput is a HANDLE. - int (*Hook_GetNumberOfConsoleInputEvents)( void *hInput, unsigned long *pNumEvents ); - - // hInput is a HANDLE. - // pRecs is an INPUT_RECORD pointer. - int (*Hook_ReadConsoleInput)( void *hInput, void *pRecs, int nMaxRecs, unsigned long *pNumRead ); - - - // This calls time() then gives you localtime()'s result. - void (*Hook_LocalTime)( struct tm *today ); - - short (*Hook_GetKeyState)( int nVirtKey ); - - // TCP calls. - int (*Hook_recv)( int s, char *buf, int len, int flags ); - int (*Hook_send)( int s, const char *buf, int len, int flags ); - - // These can be used to add events without having to modify VCR mode. - // pEventName is used for verification to make sure it's playing back correctly. - // If pEventName is null, then verification is not performed. - void (*GenericRecord)( const tchar *pEventName, const void *pData, int len ); - - - // Returns the number of bytes written in the generic event. - // If bForceLenSame is true, then it will error out unless the value in the VCR file is the same as maxLen. - int (*GenericPlayback)( const tchar *pEventName, void *pOutData, int maxLen, bool bForceLenSame ); - - // If you just want to record and playback a value and not worry about whether or not you're - // recording or playing back, use this. It also will do nothing if you're not recording or playing back. - // - // NOTE: also see GenericValueVerify, which allows you to have it VERIFY that pData's contents are the same upon playback - // (rather than just copying whatever is in the VCR file into pData). - void (*GenericValue)( const tchar *pEventName, void *pData, int maxLen ); - - // Get the current percent (0.0 - 1.0) that it's played back through the file (only valid in playback). - double (*GetPercentCompleted)(); - - // If you use this, then any VCR stuff the thread does will work with VCR mode. - // This mirrors the Windows API CreateThread function and returns a HANDLE the same way. - void* (*Hook_CreateThread)( - void *lpThreadAttributes, - unsigned long dwStackSize, - void *lpStartAddress, - void *lpParameter, - unsigned long dwCreationFlags, - unsigned long *lpThreadID ); - - unsigned long (*Hook_WaitForSingleObject)( - void *handle, - unsigned long dwMilliseconds ); - - void (*Hook_EnterCriticalSection)( void *pCS ); - - void (*Hook_Time)( long *pTime ); - - // String value. Playback just verifies that the incoming string is the same as it was when recording. - void (*GenericString)( const char *pEventName, const char *pString ); - - // Works like GenericValue, except upon playback it will verify that pData's contents are the same as it was during recording. - void (*GenericValueVerify)( const tchar *pEventName, const void *pData, int maxLen ); - - unsigned long (*Hook_WaitForMultipleObjects)( uint32 nHandles, const void **pHandles, int bWaitAll, uint32 timeout ); - -} VCR_t; - -#ifndef NO_VCR - -// In the launcher, this is created by vcrmode.c. -// In the engine, this is set when the launcher initializes its DLL. -PLATFORM_INTERFACE VCR_t *g_pVCR; - -#endif - - -#ifndef NO_VCR -#define VCRStart g_pVCR->Start -#define VCREnd g_pVCR->End -#define VCRGetVCRTraceInterface g_pVCR->GetVCRTraceInterface -#define VCRGetMode g_pVCR->GetMode -#define VCRSetEnabled g_pVCR->SetEnabled -#define VCRSyncToken g_pVCR->SyncToken -#define VCRGenericString g_pVCR->GenericString -#define VCRGenericValueVerify g_pVCR->GenericValueVerify -#define VCRHook_Sys_FloatTime g_pVCR->Hook_Sys_FloatTime -#define VCRHook_PeekMessage g_pVCR->Hook_PeekMessage -#define VCRHook_RecordGameMsg g_pVCR->Hook_RecordGameMsg -#define VCRHook_RecordEndGameMsg g_pVCR->Hook_RecordEndGameMsg -#define VCRHook_PlaybackGameMsg g_pVCR->Hook_PlaybackGameMsg -#define VCRHook_recvfrom g_pVCR->Hook_recvfrom -#define VCRHook_GetCursorPos g_pVCR->Hook_GetCursorPos -#define VCRHook_ScreenToClient g_pVCR->Hook_ScreenToClient -#define VCRHook_Cmd_Exec g_pVCR->Hook_Cmd_Exec -#define VCRHook_GetCommandLine g_pVCR->Hook_GetCommandLine -#define VCRHook_RegOpenKeyEx g_pVCR->Hook_RegOpenKeyEx -#define VCRHook_RegSetValueEx g_pVCR->Hook_RegSetValueEx -#define VCRHook_RegQueryValueEx g_pVCR->Hook_RegQueryValueEx -#define VCRHook_RegCreateKeyEx g_pVCR->Hook_RegCreateKeyEx -#define VCRHook_RegCloseKey g_pVCR->Hook_RegCloseKey -#define VCRHook_GetNumberOfConsoleInputEvents g_pVCR->Hook_GetNumberOfConsoleInputEvents -#define VCRHook_ReadConsoleInput g_pVCR->Hook_ReadConsoleInput -#define VCRHook_LocalTime g_pVCR->Hook_LocalTime -#define VCRHook_GetKeyState g_pVCR->Hook_GetKeyState -#define VCRHook_recv g_pVCR->Hook_recv -#define VCRHook_send g_pVCR->Hook_send -#define VCRGenericRecord g_pVCR->GenericRecord -#define VCRGenericPlayback g_pVCR->GenericPlayback -#define VCRGenericValue g_pVCR->GenericValue -#define VCRGetPercentCompleted g_pVCR->GetPercentCompleted -#define VCRHook_CreateThread g_pVCR->Hook_CreateThread -#define VCRHook_WaitForSingleObject g_pVCR->Hook_WaitForSingleObject -#define VCRHook_EnterCriticalSection g_pVCR->Hook_EnterCriticalSection -#define VCRHook_Time g_pVCR->Hook_Time -#define VCRHook_WaitForMultipleObjects( a, b, c, d) g_pVCR->Hook_WaitForMultipleObjects( a, (const void **)b, c, d) -#else -#define VCRStart( a, b, c ) (1) -#define VCREnd ((void)(0)) -#define VCRGetVCRTraceInterface (NULL) -#define VCRGetMode() (VCR_Disabled) -#define VCRSetEnabled( a ) ((void)(0)) -#define VCRSyncToken( a ) ((void)(0)) -#define VCRGenericRecord MUST_IFDEF_OUT_GenericRecord -#define VCRGenericPlayback MUST_IFDEF_OUT_GenericPlayback -#define VCRGenericValue MUST_IFDEF_OUT_GenericValue -#define VCRGenericString MUST_IFDEF_OUT_GenericString -#define VCRGenericValueVerify MUST_IFDEF_OUT_GenericValueVerify -#define VCRGetPercentCompleted() (0.0f) -#define VCRHook_Sys_FloatTime Sys_FloatTime -#define VCRHook_PeekMessage PeekMessage -#define VCRHook_RecordGameMsg RecordGameMsg -#define VCRHook_RecordEndGameMsg RecordEndGameMsg -#define VCRHook_PlaybackGameMsg PlaybackGameMsg -#define VCRHook_recvfrom recvfrom -#define VCRHook_GetCursorPos GetCursorPos -#define VCRHook_ScreenToClient ScreenToClient -#define VCRHook_Cmd_Exec( a ) ((void)(0)) -#define VCRHook_GetCommandLine GetCommandLine -#define VCRHook_RegOpenKeyEx RegOpenKeyEx -#define VCRHook_RegSetValueEx RegSetValueEx -#define VCRHook_RegQueryValueEx RegQueryValueEx -#define VCRHook_RegCreateKeyEx RegCreateKeyEx -#define VCRHook_RegCloseKey RegCloseKey -#define VCRHook_GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents -#define VCRHook_ReadConsoleInput ReadConsoleInput -#define VCRHook_LocalTime( a ) memset(a, 0, sizeof(*a)); -#define VCRHook_GetKeyState GetKeyState -#define VCRHook_recv recv -#define VCRHook_send send -#if defined( _X360 ) -#define VCRHook_CreateThread CreateThread -#else -#define VCRHook_CreateThread (void*)_beginthreadex -#endif -#define VCRHook_WaitForSingleObject WaitForSingleObject -#define VCRHook_EnterCriticalSection EnterCriticalSection -#define VCRHook_WaitForMultipleObjects( a, b, c, d) WaitForMultipleObjects( a, (const HANDLE *)b, c, d) -#define VCRHook_Time Time -#endif - -#endif // VCRMODE_H diff --git a/Resources/NetHook/tier0/vprof.h b/Resources/NetHook/tier0/vprof.h deleted file mode 100644 index d5228e5f..00000000 --- a/Resources/NetHook/tier0/vprof.h +++ /dev/null @@ -1,1187 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Real-Time Hierarchical Profiling -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef VPROF_H -#define VPROF_H - -#include "tier0/dbg.h" -#include "tier0/fasttimer.h" -#include "tier0/l2cache.h" -#include "tier0/threadtools.h" - -// VProf is enabled by default in all configurations -except- X360 Retail. -#if !( defined(_X360) && ( defined(_RETAIL) || defined(_CERT) ) ) -#define VPROF_ENABLED -#endif - -#if defined(_X360) && defined(VPROF_ENABLED) -#include "tier0/pmc360.h" -#ifndef USE_PIX -#define VPROF_UNDO_PIX -#undef _PIX_H_ -#undef PIXBeginNamedEvent -#undef PIXEndNamedEvent -#undef PIXSetMarker -#undef PIXNameThread -#define USE_PIX -#include -#undef USE_PIX -#else -#include -#endif -#endif - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4251) -#endif - -// enable this to get detailed nodes beneath budget -// #define VPROF_LEVEL 1 - -// enable this to use pix (360 only) -// #define VPROF_PIX 1 - -#if defined(VPROF_PIX) -#pragma comment( lib, "Xapilibi" ) -#endif - -//----------------------------------------------------------------------------- -// -// Profiling instrumentation macros -// - -#define MAXCOUNTERS 256 - - -#ifdef VPROF_ENABLED - -#define VPROF_VTUNE_GROUP - -#define VPROF( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0) -#define VPROF_ASSERT_ACCOUNTED( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, true, 0) -#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) VPROF_##detail(name,group, bAssertAccounted, budgetFlags) - -#define VPROF_BUDGET( name, group ) VPROF_BUDGET_FLAGS(name, group, BUDGETFLAG_OTHER) -#define VPROF_BUDGET_FLAGS( name, group, flags ) VPROF_(name, 0, group, false, flags) - -#define VPROF_SCOPE_BEGIN( tag ) do { VPROF( tag ) -#define VPROF_SCOPE_END() } while (0) - -#define VPROF_ONLY( expression ) expression - -#define VPROF_ENTER_SCOPE( name ) g_VProfCurrentProfile.EnterScope( name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0 ) -#define VPROF_EXIT_SCOPE() g_VProfCurrentProfile.ExitScope() - -#define VPROF_BUDGET_GROUP_ID_UNACCOUNTED 0 - - -// Budgetgroup flags. These are used with VPROF_BUDGET_FLAGS. -// These control which budget panels the groups show up in. -// If a budget group uses VPROF_BUDGET, it gets the default -// which is BUDGETFLAG_OTHER. -#define BUDGETFLAG_CLIENT (1<<0) // Shows up in the client panel. -#define BUDGETFLAG_SERVER (1<<1) // Shows up in the server panel. -#define BUDGETFLAG_OTHER (1<<2) // Unclassified (the client shows these but the dedicated server doesn't). -#define BUDGETFLAG_HIDDEN (1<<15) -#define BUDGETFLAG_ALL 0xFFFF - - -// NOTE: You can use strings instead of these defines. . they are defined here and added -// in vprof.cpp so that they are always in the same order. -#define VPROF_BUDGETGROUP_OTHER_UNACCOUNTED _T("Unaccounted") -#define VPROF_BUDGETGROUP_WORLD_RENDERING _T("World Rendering") -#define VPROF_BUDGETGROUP_DISPLACEMENT_RENDERING _T("Displacement_Rendering") -#define VPROF_BUDGETGROUP_GAME _T("Game") -#define VPROF_BUDGETGROUP_NPCS _T("NPCs") -#define VPROF_BUDGETGROUP_SERVER_ANIM _T("Server Animation") -#define VPROF_BUDGETGROUP_PHYSICS _T("Physics") -#define VPROF_BUDGETGROUP_STATICPROP_RENDERING _T("Static_Prop_Rendering") -#define VPROF_BUDGETGROUP_MODEL_RENDERING _T("Other_Model_Rendering") -#define VPROF_BUDGETGROUP_BRUSHMODEL_RENDERING _T("Brush_Model_Rendering") -#define VPROF_BUDGETGROUP_SHADOW_RENDERING _T("Shadow_Rendering") -#define VPROF_BUDGETGROUP_DETAILPROP_RENDERING _T("Detail_Prop_Rendering") -#define VPROF_BUDGETGROUP_PARTICLE_RENDERING _T("Particle/Effect_Rendering") -#define VPROF_BUDGETGROUP_ROPES _T("Ropes") -#define VPROF_BUDGETGROUP_DLIGHT_RENDERING _T("Dynamic_Light_Rendering") -#define VPROF_BUDGETGROUP_OTHER_NETWORKING _T("Networking") -#define VPROF_BUDGETGROUP_CLIENT_ANIMATION _T("Client_Animation") -#define VPROF_BUDGETGROUP_OTHER_SOUND _T("Sound") -#define VPROF_BUDGETGROUP_OTHER_VGUI _T("VGUI") -#define VPROF_BUDGETGROUP_OTHER_FILESYSTEM _T("FileSystem") -#define VPROF_BUDGETGROUP_PREDICTION _T("Prediction") -#define VPROF_BUDGETGROUP_INTERPOLATION _T("Interpolation") -#define VPROF_BUDGETGROUP_SWAP_BUFFERS _T("Swap_Buffers") -#define VPROF_BUDGETGROUP_PLAYER _T("Player") -#define VPROF_BUDGETGROUP_OCCLUSION _T("Occlusion") -#define VPROF_BUDGETGROUP_OVERLAYS _T("Overlays") -#define VPROF_BUDGETGROUP_TOOLS _T("Tools") -#define VPROF_BUDGETGROUP_LIGHTCACHE _T("Light_Cache") -#define VPROF_BUDGETGROUP_DISP_HULLTRACES _T("Displacement_Hull_Traces") -#define VPROF_BUDGETGROUP_TEXTURE_CACHE _T("Texture_Cache") -#define VPROF_BUDGETGROUP_PARTICLE_SIMULATION _T("Particle Simulation") -#define VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING _T("Flashlight Shadows") -#define VPROF_BUDGETGROUP_CLIENT_SIM _T("Client Simulation") // think functions, tempents, etc. -#define VPROF_BUDGETGROUP_STEAM _T("Steam") - -#ifdef _X360 -// update flags -#define VPROF_UPDATE_BUDGET 0x01 // send budget data every frame -#define VPROF_UPDATE_TEXTURE_GLOBAL 0x02 // send global texture data every frame -#define VPROF_UPDATE_TEXTURE_PERFRAME 0x04 // send perframe texture data every frame -#endif - -//------------------------------------- - -#ifndef VPROF_LEVEL -#define VPROF_LEVEL 0 -#endif - -#define VPROF_0(name,group,assertAccounted,budgetFlags) CVProfScope VProf_(name, 0, group, assertAccounted, budgetFlags); - -#if VPROF_LEVEL > 0 -#define VPROF_1(name,group,assertAccounted,budgetFlags) CVProfScope VProf_(name, 1, group, assertAccounted, budgetFlags); -#else -#define VPROF_1(name,group,assertAccounted,budgetFlags) ((void)0) -#endif - -#if VPROF_LEVEL > 1 -#define VPROF_2(name,group,assertAccounted,budgetFlags) CVProfScope VProf_(name, 2, group, assertAccounted, budgetFlags); -#else -#define VPROF_2(name,group,assertAccounted,budgetFlags) ((void)0) -#endif - -#if VPROF_LEVEL > 2 -#define VPROF_3(name,group,assertAccounted,budgetFlags) CVProfScope VProf_(name, 3, group, assertAccounted, budgetFlags); -#else -#define VPROF_3(name,group,assertAccounted,budgetFlags) ((void)0) -#endif - -#if VPROF_LEVEL > 3 -#define VPROF_4(name,group,assertAccounted,budgetFlags) CVProfScope VProf_(name, 4, group, assertAccounted, budgetFlags); -#else -#define VPROF_4(name,group,assertAccounted,budgetFlags) ((void)0) -#endif - -//------------------------------------- - -#define VPROF_INCREMENT_COUNTER(name,amount) do { static CVProfCounter _counter( name ); _counter.Increment( amount ); } while( 0 ) -#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) do { static CVProfCounter _counter( name, group ); _counter.Increment( amount ); } while( 0 ) - -#else - -#define VPROF( name ) ((void)0) -#define VPROF_ASSERT_ACCOUNTED( name ) ((void)0) -#define VPROF_( name, detail, group, bAssertAccounted ) ((void)0) -#define VPROF_BUDGET( name, group ) ((void)0) -#define VPROF_BUDGET_FLAGS( name, group, flags ) ((void)0) - -#define VPROF_SCOPE_BEGIN( tag ) do { -#define VPROF_SCOPE_END() } while (0) - -#define VPROF_ONLY( expression ) ((void)0) - -#define VPROF_ENTER_SCOPE( name ) -#define VPROF_EXIT_SCOPE() - -#define VPROF_INCREMENT_COUNTER(name,amount) ((void)0) -#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) ((void)0) - -#endif - -//----------------------------------------------------------------------------- - -#ifdef VPROF_ENABLED - -//----------------------------------------------------------------------------- -// -// A node in the call graph hierarchy -// - -class DBG_CLASS CVProfNode -{ -friend class CVProfRecorder; -friend class CVProfile; - -public: - CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags ); - ~CVProfNode(); - - CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, int budgetFlags ); - CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName ); - CVProfNode *GetParent(); - CVProfNode *GetSibling(); - CVProfNode *GetPrevSibling(); - CVProfNode *GetChild(); - - void MarkFrame(); - void ResetPeak(); - - void Pause(); - void Resume(); - void Reset(); - - void EnterScope(); - bool ExitScope(); - - const tchar *GetName(); - - int GetBudgetGroupID() - { - return m_BudgetGroupID; - } - - // Only used by the record/playback stuff. - void SetBudgetGroupID( int id ) - { - m_BudgetGroupID = id; - } - - int GetCurCalls(); - double GetCurTime(); - int GetPrevCalls(); - double GetPrevTime(); - int GetTotalCalls(); - double GetTotalTime(); - double GetPeakTime(); - - double GetCurTimeLessChildren(); - double GetPrevTimeLessChildren(); - double GetTotalTimeLessChildren(); - - int GetPrevL2CacheMissLessChildren(); - int GetPrevLoadHitStoreLessChildren(); - - void ClearPrevTime(); - - int GetL2CacheMisses(); - - // Not used in the common case... - void SetCurFrameTime( unsigned long milliseconds ); - - void SetClientData( int iClientData ) { m_iClientData = iClientData; } - int GetClientData() const { return m_iClientData; } - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE - - -// Used by vprof record/playback. -private: - - void SetUniqueNodeID( int id ) - { - m_iUniqueNodeID = id; - } - - int GetUniqueNodeID() const - { - return m_iUniqueNodeID; - } - - static int s_iCurrentUniqueNodeID; - - -private: - const tchar *m_pszName; - CFastTimer m_Timer; - - // L2 Cache data. - int m_iPrevL2CacheMiss; - int m_iCurL2CacheMiss; - int m_iTotalL2CacheMiss; - -#ifndef _X360 - // L2 Cache data. - CL2Cache m_L2Cache; -#else // 360: - - unsigned int m_iBitFlags; // see enum below for settings - CPMCData m_PMCData; - int m_iPrevLoadHitStores; - int m_iCurLoadHitStores; - int m_iTotalLoadHitStores; - - public: - enum FlagBits - { - kRecordL2 = 0x01, - kCPUTrace = 0x02, ///< cause a PIX trace inside this node. - }; - // call w/ true to enable L2 and LHS recording; false to turn it off - inline void EnableL2andLHS(bool enable) - { - if (enable) - m_iBitFlags |= kRecordL2; - else - m_iBitFlags &= (~kRecordL2); - } - - inline bool IsL2andLHSEnabled( void ) - { - return (m_iBitFlags & kRecordL2) != 0; - } - - int GetLoadHitStores(); - - private: - -#endif - - int m_nRecursions; - - unsigned m_nCurFrameCalls; - CCycleCount m_CurFrameTime; - - unsigned m_nPrevFrameCalls; - CCycleCount m_PrevFrameTime; - - unsigned m_nTotalCalls; - CCycleCount m_TotalTime; - - CCycleCount m_PeakTime; - - CVProfNode *m_pParent; - CVProfNode *m_pChild; - CVProfNode *m_pSibling; - - int m_BudgetGroupID; - - int m_iClientData; - int m_iUniqueNodeID; -}; - -//----------------------------------------------------------------------------- -// -// Coordinator and root node of the profile hierarchy tree -// - -enum VProfReportType_t -{ - VPRT_SUMMARY = ( 1 << 0 ), - VPRT_HIERARCHY = ( 1 << 1 ), - VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY = ( 1 << 2 ), - VPRT_LIST_BY_TIME = ( 1 << 3 ), - VPRT_LIST_BY_TIME_LESS_CHILDREN = ( 1 << 4 ), - VPRT_LIST_BY_AVG_TIME = ( 1 << 5 ), - VPRT_LIST_BY_AVG_TIME_LESS_CHILDREN = ( 1 << 6 ), - VPRT_LIST_BY_PEAK_TIME = ( 1 << 7 ), - VPRT_LIST_BY_PEAK_OVER_AVERAGE = ( 1 << 8 ), - VPRT_LIST_TOP_ITEMS_ONLY = ( 1 << 9 ), - - VPRT_FULL = (0xffffffff & ~(VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY|VPRT_LIST_TOP_ITEMS_ONLY)), -}; - -enum CounterGroup_t -{ - COUNTER_GROUP_DEFAULT=0, - COUNTER_GROUP_NO_RESET, // The engine doesn't reset these counters. Usually, they are used - // like global variables that can be accessed across modules. - COUNTER_GROUP_TEXTURE_GLOBAL, // Global texture usage counters (totals for what is currently in memory). - COUNTER_GROUP_TEXTURE_PER_FRAME // Per-frame texture usage counters. -}; - -class DBG_CLASS CVProfile -{ -public: - CVProfile(); - ~CVProfile(); - - void Term(); - - // - // Runtime operations - // - - void Start(); - void Stop(); - -#ifdef _X360 - enum VXConsoleReportMode_t - { - VXCONSOLE_REPORT_TIME = 0, - VXCONSOLE_REPORT_L2CACHE_MISSES, - VXCONSOLE_REPORT_LOAD_HIT_STORE, - - VXCONSOLE_REPORT_COUNT, - }; - - // piggyback to profiler - void VXProfileStart(); - void VXProfileUpdate(); - void VXEnableUpdateMode(int event, bool bEnable); - - void PMCDisableAllNodes(CVProfNode *pStartNode = NULL); ///< turn off l2 and lhs recording for everywhere - bool PMCEnableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node - bool PMCDisableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node - - void DumpEnabledPMCNodes( void ); - - void VXConsoleReportMode( VXConsoleReportMode_t mode ); - void VXConsoleReportScale( VXConsoleReportMode_t mode, float flScale ); - - // the CPU trace mode is actually a small state machine; it can be off, primed for - // single capture, primed for everything-in-a-frame capture, or currently in everything-in-a-frame - // capture. - enum CPUTraceState - { - kDisabled, - kFirstHitNode, /// < record from the first time we hit the node until that node ends - kAllNodesInFrame_WaitingForMark, ///< we're going to record all the times a node is hit in a frame, but are waiting for the frame to start - kAllNodesInFrame_Recording, ///< we're recording all hits on a node this frame. - }; - - /// Global switch to turn CPU tracing on or off at all. The idea is you set up a node first, - /// then trigger tracing by throwing this to true. It'll reset back to false after the trace - /// happens. - inline CPUTraceState GetCPUTraceMode(); - inline void SetCPUTraceEnabled(CPUTraceState enabled); - inline void IncrementMultiTraceIndex(); /// tick up the counter that gets appended to the multi-per-frame traces - inline unsigned int GetMultiTraceIndex(); /// return the counter - void CPUTraceDisableAllNodes(CVProfNode *pStartNode = NULL); //< disable the cpu trace flag wherever it may be - CVProfNode *CPUTraceEnableForNode(const tchar *pszNodeName); ///< enable cpu trace on this node only, disabling it wherever else it may be on. - CVProfNode *CPUTraceGetEnabledNode(CVProfNode *pStartNode = NULL); ///< return the node enabled for CPU tracing, or NULL. - const char *GetCPUTraceFilename(); ///< get the filename the trace should write into. - const char *SetCPUTraceFilename(const char *filename); ///< set the filename the trace should write into. (don't specify the extension; I'll do that.) - -#endif - - void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted ); - void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags ); - void ExitScope(); - - void MarkFrame(); - void ResetPeaks(); - - void Pause(); - void Resume(); - void Reset(); - - bool IsEnabled() const; - int GetDetailLevel() const; - - bool AtRoot() const; - - // - // Queries - // - -#ifdef VPROF_VTUNE_GROUP -# define MAX_GROUP_STACK_DEPTH 1024 - - void EnableVTuneGroup( const tchar *pGroupName ) - { - m_nVTuneGroupID = BudgetGroupNameToBudgetGroupID( pGroupName ); - m_bVTuneGroupEnabled = true; - } - void DisableVTuneGroup( void ) - { - m_bVTuneGroupEnabled = false; - } - - inline void PushGroup( int nGroupID ); - inline void PopGroup( void ); -#endif - - int NumFramesSampled() { return m_nFrames; } - double GetPeakFrameTime(); - double GetTotalTimeSampled(); - double GetTimeLastFrame(); - - CVProfNode *GetRoot(); - CVProfNode *FindNode( CVProfNode *pStartNode, const tchar *pszNode ); - - void OutputReport( int type = VPRT_FULL, const tchar *pszStartNode = NULL, int budgetGroupID = -1 ); - - const tchar *GetBudgetGroupName( int budgetGroupID ); - int GetBudgetGroupFlags( int budgetGroupID ) const; // Returns a combination of BUDGETFLAG_ defines. - int GetNumBudgetGroups( void ); - void GetBudgetGroupColor( int budgetGroupID, int &r, int &g, int &b, int &a ); - int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName ); - int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName, int budgetFlagsToORIn ); - void RegisterNumBudgetGroupsChangedCallBack( void (*pCallBack)(void) ); - - int BudgetGroupNameToBudgetGroupIDNoCreate( const tchar *pBudgetGroupName ) { return FindBudgetGroupName( pBudgetGroupName ); } - - void HideBudgetGroup( int budgetGroupID, bool bHide = true ); - void HideBudgetGroup( const char *pszName, bool bHide = true ) { HideBudgetGroup( BudgetGroupNameToBudgetGroupID( pszName), bHide ); } - - int *FindOrCreateCounter( const tchar *pName, CounterGroup_t eCounterGroup=COUNTER_GROUP_DEFAULT ); - void ResetCounters( CounterGroup_t eCounterGroup ); - - int GetNumCounters( void ) const; - - const tchar *GetCounterName( int index ) const; - int GetCounterValue( int index ) const; - const tchar *GetCounterNameAndValue( int index, int &val ) const; - CounterGroup_t GetCounterGroup( int index ) const; - - // Performance monitoring events. - void PMEInitialized( bool bInit ) { m_bPMEInit = bInit; } - void PMEEnable( bool bEnable ) { m_bPMEEnabled = bEnable; } - -#ifndef _X360 - bool UsePME( void ) { return ( m_bPMEInit && m_bPMEEnabled ); } -#else - bool UsePME( void ) { return ( CPMCData::IsInitialized() && m_bPMEEnabled ); } -#endif - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE - -protected: - - void FreeNodes_R( CVProfNode *pNode ); - -#ifdef VPROF_VTUNE_GROUP - bool VTuneGroupEnabled() - { - return m_bVTuneGroupEnabled; - } - int VTuneGroupID() - { - return m_nVTuneGroupID; - } -#endif - - void SumTimes( const tchar *pszStartNode, int budgetGroupID ); - void SumTimes( CVProfNode *pNode, int budgetGroupID ); - void DumpNodes( CVProfNode *pNode, int indent, bool bAverageAndCountOnly ); - int FindBudgetGroupName( const tchar *pBudgetGroupName ); - int AddBudgetGroupName( const tchar *pBudgetGroupName, int budgetFlags ); - -#ifdef VPROF_VTUNE_GROUP - bool m_bVTuneGroupEnabled; - int m_nVTuneGroupID; - int m_GroupIDStack[MAX_GROUP_STACK_DEPTH]; - int m_GroupIDStackDepth; -#endif - int m_enabled; - bool m_fAtRoot; // tracked for efficiency of the "not profiling" case - CVProfNode *m_pCurNode; - CVProfNode m_Root; - int m_nFrames; - int m_ProfileDetailLevel; - int m_pausedEnabledDepth; - - class CBudgetGroup - { - public: - tchar *m_pName; - int m_BudgetFlags; - }; - - CBudgetGroup *m_pBudgetGroups; - int m_nBudgetGroupNamesAllocated; - int m_nBudgetGroupNames; - void (*m_pNumBudgetGroupsChangedCallBack)(void); - - // Performance monitoring events. - bool m_bPMEInit; - bool m_bPMEEnabled; - - int m_Counters[MAXCOUNTERS]; - char m_CounterGroups[MAXCOUNTERS]; // (These are CounterGroup_t's). - tchar *m_CounterNames[MAXCOUNTERS]; - int m_NumCounters; - -#ifdef _X360 - int m_UpdateMode; - CPUTraceState m_iCPUTraceEnabled; - char m_CPUTraceFilename[128]; - unsigned int m_iSuccessiveTraceIndex; - VXConsoleReportMode_t m_ReportMode; - float m_pReportScale[VXCONSOLE_REPORT_COUNT]; -#endif -}; - -//------------------------------------- - -DBG_INTERFACE CVProfile g_VProfCurrentProfile; - - -//----------------------------------------------------------------------------- - -#ifdef VPROF_VTUNE_GROUP -inline void CVProfile::PushGroup( int nGroupID ) -{ - // There is always at least one item on the stack since we force - // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED. - Assert( m_GroupIDStackDepth > 0 ); - Assert( m_GroupIDStackDepth < MAX_GROUP_STACK_DEPTH ); - m_GroupIDStack[m_GroupIDStackDepth] = nGroupID; - m_GroupIDStackDepth++; - if( m_GroupIDStack[m_GroupIDStackDepth-2] != nGroupID && - VTuneGroupEnabled() && - nGroupID == VTuneGroupID() ) - { - vtune( true ); - } -} -#endif // VPROF_VTUNE_GROUP - -#ifdef VPROF_VTUNE_GROUP -inline void CVProfile::PopGroup( void ) -{ - m_GroupIDStackDepth--; - // There is always at least one item on the stack since we force - // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED. - Assert( m_GroupIDStackDepth > 0 ); - if( m_GroupIDStack[m_GroupIDStackDepth] != m_GroupIDStack[m_GroupIDStackDepth+1] && - VTuneGroupEnabled() && - m_GroupIDStack[m_GroupIDStackDepth+1] == VTuneGroupID() ) - { - vtune( false ); - } -} -#endif // VPROF_VTUNE_GROUP - -//----------------------------------------------------------------------------- - -class CVProfScope -{ -public: - CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags ); - ~CVProfScope(); -}; - -//----------------------------------------------------------------------------- -// -// CVProfNode, inline methods -// - -inline CVProfNode::CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags ) - : m_pszName( pszName ), - m_nCurFrameCalls( 0 ), - m_nPrevFrameCalls( 0 ), - m_nRecursions( 0 ), - m_pParent( pParent ), - m_pChild( NULL ), - m_pSibling( NULL ), - m_iClientData( -1 ) -#ifdef _X360 - , m_iBitFlags( 0 ) -#endif -{ - m_iUniqueNodeID = s_iCurrentUniqueNodeID++; - - if ( m_iUniqueNodeID > 0 ) - { - m_BudgetGroupID = g_VProfCurrentProfile.BudgetGroupNameToBudgetGroupID( pBudgetGroupName, budgetFlags ); - } - else - { - m_BudgetGroupID = 0; // "m_Root" can't call BudgetGroupNameToBudgetGroupID because g_VProfCurrentProfile not yet initialized - } - - Reset(); - - if( m_pParent && ( m_BudgetGroupID == VPROF_BUDGET_GROUP_ID_UNACCOUNTED ) ) - { - m_BudgetGroupID = m_pParent->GetBudgetGroupID(); - } -} - - -//------------------------------------- - -inline CVProfNode *CVProfNode::GetParent() -{ - Assert( m_pParent ); - return m_pParent; -} - -//------------------------------------- - -inline CVProfNode *CVProfNode::GetSibling() -{ - return m_pSibling; -} - -//------------------------------------- -// Hacky way to the previous sibling, only used from vprof panel at the moment, -// so it didn't seem like it was worth the memory waste to add the reverse -// link per node. - -inline CVProfNode *CVProfNode::GetPrevSibling() -{ - CVProfNode* p = GetParent(); - - if(!p) - return NULL; - - CVProfNode* s; - for( s = p->GetChild(); - s && ( s->GetSibling() != this ); - s = s->GetSibling() ) - ; - - return s; -} - -//------------------------------------- - -inline CVProfNode *CVProfNode::GetChild() -{ - return m_pChild; -} - -//------------------------------------- - -inline const tchar *CVProfNode::GetName() -{ - Assert( m_pszName ); - return m_pszName; -} - -//------------------------------------- - -inline int CVProfNode::GetTotalCalls() -{ - return m_nTotalCalls; -} - -//------------------------------------- - -inline double CVProfNode::GetTotalTime() -{ - return m_TotalTime.GetMillisecondsF(); -} - -//------------------------------------- - -inline int CVProfNode::GetCurCalls() -{ - return m_nCurFrameCalls; -} - -//------------------------------------- - -inline double CVProfNode::GetCurTime() -{ - return m_CurFrameTime.GetMillisecondsF(); -} - -//------------------------------------- - -inline int CVProfNode::GetPrevCalls() -{ - return m_nPrevFrameCalls; -} - -//------------------------------------- - -inline double CVProfNode::GetPrevTime() -{ - return m_PrevFrameTime.GetMillisecondsF(); -} - -//------------------------------------- - -inline double CVProfNode::GetPeakTime() -{ - return m_PeakTime.GetMillisecondsF(); -} - -//------------------------------------- - -inline double CVProfNode::GetTotalTimeLessChildren() -{ - double result = GetTotalTime(); - CVProfNode *pChild = GetChild(); - while ( pChild ) - { - result -= pChild->GetTotalTime(); - pChild = pChild->GetSibling(); - } - return result; -} - -//------------------------------------- - -inline double CVProfNode::GetCurTimeLessChildren() -{ - double result = GetCurTime(); - CVProfNode *pChild = GetChild(); - while ( pChild ) - { - result -= pChild->GetCurTime(); - pChild = pChild->GetSibling(); - } - return result; -} - -inline double CVProfNode::GetPrevTimeLessChildren() -{ - double result = GetPrevTime(); - CVProfNode *pChild = GetChild(); - while ( pChild ) - { - result -= pChild->GetPrevTime(); - pChild = pChild->GetSibling(); - } - return result; -} - -//----------------------------------------------------------------------------- -inline int CVProfNode::GetPrevL2CacheMissLessChildren() -{ - int result = m_iPrevL2CacheMiss; - CVProfNode *pChild = GetChild(); - while ( pChild ) - { - result -= pChild->m_iPrevL2CacheMiss; - pChild = pChild->GetSibling(); - } - return result; -} - -//----------------------------------------------------------------------------- -inline int CVProfNode::GetPrevLoadHitStoreLessChildren() -{ -#ifndef _X360 - return 0; -#else - int result = m_iPrevLoadHitStores; - CVProfNode *pChild = GetChild(); - while ( pChild ) - { - result -= pChild->m_iPrevLoadHitStores; - pChild = pChild->GetSibling(); - } - return result; -#endif -} - - -//----------------------------------------------------------------------------- -inline void CVProfNode::ClearPrevTime() -{ - m_PrevFrameTime.Init(); -} - -//----------------------------------------------------------------------------- -inline int CVProfNode::GetL2CacheMisses( void ) -{ -#ifndef _X360 - return m_L2Cache.GetL2CacheMisses(); -#else - return m_iTotalL2CacheMiss; -#endif -} - -#ifdef _X360 -inline int CVProfNode::GetLoadHitStores( void ) -{ - return m_iTotalLoadHitStores; -} -#endif - -//----------------------------------------------------------------------------- -// -// CVProfile, inline methods -// - -//------------------------------------- - -inline bool CVProfile::IsEnabled() const -{ - return ( m_enabled != 0 ); -} - -//------------------------------------- - -inline int CVProfile::GetDetailLevel() const -{ - return m_ProfileDetailLevel; -} - - -//------------------------------------- - -inline bool CVProfile::AtRoot() const -{ - return m_fAtRoot; -} - -//------------------------------------- - -inline void CVProfile::Start() -{ - if ( ++m_enabled == 1 ) - { - m_Root.EnterScope(); -#ifdef _X360 - VXProfileStart(); - CPMCData::InitializeOnceProgramWide(); -#endif - } -} - -//------------------------------------- - -inline void CVProfile::Stop() -{ - if ( --m_enabled == 0 ) - m_Root.ExitScope(); -} - -//------------------------------------- - -inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags ) -{ - if ( ( m_enabled != 0 || !m_fAtRoot ) && ThreadInMainThread() ) // if became disabled, need to unwind back to root before stopping - { - // Only account for vprof stuff on the primary thread. - //if( !Plat_IsPrimaryThread() ) - // return; - - if ( pszName != m_pCurNode->GetName() ) - { - m_pCurNode = m_pCurNode->GetSubNode( pszName, detailLevel, pBudgetGroupName, budgetFlags ); - } - m_pBudgetGroups[m_pCurNode->GetBudgetGroupID()].m_BudgetFlags |= budgetFlags; - -#if defined( _DEBUG ) && !defined( _X360 ) - // 360 doesn't want this to allow tier0 debug/release .def files to match - if ( bAssertAccounted ) - { - // FIXME - AssertOnce( m_pCurNode->GetBudgetGroupID() != 0 ); - } -#endif - m_pCurNode->EnterScope(); - m_fAtRoot = false; - } -#if defined(_X360) && defined(VPROF_PIX) - if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED ) - PIXBeginNamedEvent( 0, pszName ); -#endif -} - -inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted ) -{ - EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, BUDGETFLAG_OTHER ); -} - -//------------------------------------- - -inline void CVProfile::ExitScope() -{ -#if defined(_X360) && defined(VPROF_PIX) -#ifdef PIXBeginNamedEvent -#error -#endif - if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED ) - PIXEndNamedEvent(); -#endif - if ( ( !m_fAtRoot || m_enabled != 0 ) && ThreadInMainThread() ) - { - // Only account for vprof stuff on the primary thread. - //if( !Plat_IsPrimaryThread() ) - // return; - - // ExitScope will indicate whether we should back up to our parent (we may - // be profiling a recursive function) - if (m_pCurNode->ExitScope()) - { - m_pCurNode = m_pCurNode->GetParent(); - } - m_fAtRoot = ( m_pCurNode == &m_Root ); - } -} - -//------------------------------------- - -inline void CVProfile::Pause() -{ - m_pausedEnabledDepth = m_enabled; - m_enabled = 0; - if ( !AtRoot() ) - m_Root.Pause(); -} - -//------------------------------------- - -inline void CVProfile::Resume() -{ - m_enabled = m_pausedEnabledDepth; - if ( !AtRoot() ) - m_Root.Resume(); -} - -//------------------------------------- - -inline void CVProfile::Reset() -{ - m_Root.Reset(); - m_nFrames = 0; -} - -//------------------------------------- - -inline void CVProfile::ResetPeaks() -{ - m_Root.ResetPeak(); -} - -//------------------------------------- - -inline void CVProfile::MarkFrame() -{ - if ( m_enabled ) - { - ++m_nFrames; - m_Root.ExitScope(); - m_Root.MarkFrame(); - m_Root.EnterScope(); - -#ifdef _X360 - // update the CPU trace state machine if enabled - switch ( GetCPUTraceMode() ) - { - case kAllNodesInFrame_WaitingForMark: - // mark! Start recording a zillion traces. - m_iCPUTraceEnabled = kAllNodesInFrame_Recording; - - break; - case kAllNodesInFrame_Recording: - // end of frame. stop recording. - m_iCPUTraceEnabled = kDisabled; - Msg("Frame ended. Recording no more CPU traces\n"); - - break; - - default: - // no default - break; - } -#endif - } -} - -//------------------------------------- - -inline double CVProfile::GetTotalTimeSampled() -{ - return m_Root.GetTotalTime(); -} - -//------------------------------------- - -inline double CVProfile::GetPeakFrameTime() -{ - return m_Root.GetPeakTime(); -} - -//------------------------------------- - -inline double CVProfile::GetTimeLastFrame() -{ - return m_Root.GetCurTime(); -} - -//------------------------------------- - -inline CVProfNode *CVProfile::GetRoot() -{ - return &m_Root; -} - - -inline const tchar *CVProfile::GetBudgetGroupName( int budgetGroupID ) -{ - Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames ); - return m_pBudgetGroups[budgetGroupID].m_pName; -} - -inline int CVProfile::GetBudgetGroupFlags( int budgetGroupID ) const -{ - Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames ); - return m_pBudgetGroups[budgetGroupID].m_BudgetFlags; -} - -#ifdef _X360 - -inline CVProfile::CPUTraceState CVProfile::GetCPUTraceMode() -{ - return m_iCPUTraceEnabled; -} - -inline void CVProfile::SetCPUTraceEnabled(CPUTraceState enabled) -{ - m_iCPUTraceEnabled = enabled; -} - -inline void CVProfile::IncrementMultiTraceIndex() -{ - ++m_iSuccessiveTraceIndex; -} - -inline unsigned int CVProfile::GetMultiTraceIndex() -{ - return m_iSuccessiveTraceIndex; -} - -#endif - - -//----------------------------------------------------------------------------- - -inline CVProfScope::CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags ) -{ - g_VProfCurrentProfile.EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, budgetFlags ); -} - -//------------------------------------- - -inline CVProfScope::~CVProfScope() -{ - g_VProfCurrentProfile.ExitScope(); -} - -class CVProfCounter -{ -public: - CVProfCounter( const tchar *pName, CounterGroup_t group=COUNTER_GROUP_DEFAULT ) - { - m_pCounter = g_VProfCurrentProfile.FindOrCreateCounter( pName, group ); - Assert( m_pCounter ); - } - ~CVProfCounter() - { - } - void Increment( int val ) - { - Assert( m_pCounter ); - *m_pCounter += val; - } -private: - int *m_pCounter; -}; - -#endif - -#ifdef VPROF_UNDO_PIX -#undef USE_PIX -#undef _PIX_H_ -#undef PIXBeginNamedEvent -#undef PIXEndNamedEvent -#undef PIXSetMarker -#undef PIXNameThread -#include -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif - -//============================================================================= diff --git a/Resources/NetHook/tier0/wchartypes.h b/Resources/NetHook/tier0/wchartypes.h deleted file mode 100644 index 79bc5f53..00000000 --- a/Resources/NetHook/tier0/wchartypes.h +++ /dev/null @@ -1,101 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: All of our code is completely Unicode. Instead of char, you should -// use wchar, uint8, or char8, as explained below. -// -// $NoKeywords: $ -//=============================================================================// - - -#ifndef WCHARTYPES_H -#define WCHARTYPES_H -#ifdef _WIN32 -#pragma once -#endif - -#ifdef _INC_TCHAR -#error ("Must include tier0 type headers before tchar.h") -#endif - -// Temporarily turn off Valve defines -#include "tier0/valve_off.h" - -#ifndef _WCHAR_T_DEFINED -typedef unsigned short wchar_t; -#define _WCHAR_T_DEFINED -#endif - -// char8 -// char8 is equivalent to char, and should be used when you really need a char -// (for example, when calling an external function that's declared to take -// chars). -typedef char char8; - -// uint8 -// uint8 is equivalent to byte (but is preferred over byte for clarity). Use this -// whenever you mean a byte (for example, one byte of a network packet). -typedef unsigned char uint8; -typedef unsigned char BYTE; -typedef unsigned char byte; - -// wchar -// wchar is a single character of text (currently 16 bits, as all of our text is -// Unicode). Use this whenever you mean a piece of text (for example, in a string). -typedef wchar_t wchar; -//typedef char wchar; - -// __WFILE__ -// This is a Unicode version of __FILE__ -#define WIDEN2(x) L ## x -#define WIDEN(x) WIDEN2(x) -#define __WFILE__ WIDEN(__FILE__) - -#ifdef STEAM -#ifndef _UNICODE -#define FORCED_UNICODE -#endif -#define _UNICODE -#endif - -#ifdef _WIN32 -#include -#else -#define _tcsstr strstr -#define _tcsicmp stricmp -#define _tcscmp strcmp -#define _tcscpy strcpy -#define _tcsncpy strncpy -#define _tcsrchr strrchr -#define _tcslen strlen -#define _tfopen fopen -#define _stprintf sprintf -#define _ftprintf fprintf -#define _vsntprintf _vsnprintf -#define _tprintf printf -#define _sntprintf _snprintf -#define _T(s) s -#endif - -#if defined(_UNICODE) -typedef wchar tchar; -#define tstring wstring -#define __TFILE__ __WFILE__ -#define TCHAR_IS_WCHAR -#else -typedef char tchar; -#define tstring string -#define __TFILE__ __FILE__ -#define TCHAR_IS_CHAR -#endif - -#ifdef FORCED_UNICODE -#undef _UNICODE -#endif - -// Turn valve defines back on -#include "tier0/valve_on.h" - - -#endif // WCHARTYPES - - diff --git a/Resources/NetHook/tier0/xbox_codeline_defines.h b/Resources/NetHook/tier0/xbox_codeline_defines.h deleted file mode 100644 index 3a4147b4..00000000 --- a/Resources/NetHook/tier0/xbox_codeline_defines.h +++ /dev/null @@ -1,16 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef XBOX_CODELINE_DEFINES_H -#define XBOX_CODELINE_DEFINES_H - - -// In the regular src_main codeline, we leave this out. -//#define IN_XBOX_CODELINE - - -#endif // XBOX_CODELINE_DEFINES_H diff --git a/Resources/NetHook/tier1/CommandBuffer.h b/Resources/NetHook/tier1/CommandBuffer.h deleted file mode 100644 index 0a3c4433..00000000 --- a/Resources/NetHook/tier1/CommandBuffer.h +++ /dev/null @@ -1,160 +0,0 @@ -//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// $NoKeywords: $ -//===========================================================================// - - -#ifndef COMMANDBUFFER_H -#define COMMANDBUFFER_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utllinkedlist.h" -#include "tier1/convar.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CUtlBuffer; - - -//----------------------------------------------------------------------------- -// Invalid command handle -//----------------------------------------------------------------------------- -typedef int CommandHandle_t; -enum -{ - COMMAND_BUFFER_INVALID_COMMAND_HANDLE = 0 -}; - - -//----------------------------------------------------------------------------- -// A command buffer class- a queue of argc/argv based commands associated -// with a particular time -//----------------------------------------------------------------------------- -class CCommandBuffer -{ -public: - // Constructor, destructor - CCommandBuffer( ); - ~CCommandBuffer(); - - // Inserts text into the command buffer - bool AddText( const char *pText, int nTickDelay = 0 ); - - // Used to iterate over all commands appropriate for the current time - void BeginProcessingCommands( int nDeltaTicks ); - bool DequeueNextCommand( ); - int DequeueNextCommand( const char **& ppArgv ); - int ArgC() const; - const char **ArgV() const; - const char *ArgS() const; // All args that occur after the 0th arg, in string form - const char *GetCommandString() const; // The entire command in string form, including the 0th arg - const CCommand& GetCommand() const; - void EndProcessingCommands(); - - // Are we in the middle of processing commands? - bool IsProcessingCommands(); - - // Delays all queued commands to execute at a later time - void DelayAllQueuedCommands( int nTickDelay ); - - // Indicates how long to delay when encoutering a 'wait' command - void SetWaitDelayTime( int nTickDelay ); - - // Returns a handle to the next command to process - // (useful when inserting commands into the buffer during processing - // of commands to force immediate execution of those commands, - // most relevantly, to implement a feature where you stream a file - // worth of commands into the buffer, where the file size is too large - // to entirely contain in the buffer). - CommandHandle_t GetNextCommandHandle(); - - // Specifies a max limit of the args buffer. For unittesting. Size == 0 means use default - void LimitArgumentBufferSize( int nSize ); - -private: - enum - { - ARGS_BUFFER_LENGTH = 8192, - }; - - struct Command_t - { - int m_nTick; - int m_nFirstArgS; - int m_nBufferSize; - }; - - // Insert a command into the command queue at the appropriate time - void InsertCommandAtAppropriateTime( int hCommand ); - - // Insert a command into the command queue - // Only happens if it's inserted while processing other commands - void InsertImmediateCommand( int hCommand ); - - // Insert a command into the command queue - bool InsertCommand( const char *pArgS, int nCommandSize, int nTick ); - - // Returns the length of the next command, as well as the offset to the next command - void GetNextCommandLength( const char *pText, int nMaxLen, int *pCommandLength, int *pNextCommandOffset ); - - // Compacts the command buffer - void Compact(); - - // Parses argv0 out of the buffer - bool ParseArgV0( CUtlBuffer &buf, char *pArgv0, int nMaxLen, const char **pArgs ); - - char m_pArgSBuffer[ ARGS_BUFFER_LENGTH ]; - int m_nLastUsedArgSSize; - int m_nArgSBufferSize; - CUtlFixedLinkedList< Command_t > m_Commands; - int m_nCurrentTick; - int m_nLastTickToProcess; - int m_nWaitDelayTicks; - int m_hNextCommand; - int m_nMaxArgSBufferLength; - bool m_bIsProcessingCommands; - - // NOTE: This is here to avoid the pointers returned by DequeueNextCommand - // to become invalid by calling AddText. Is there a way we can avoid the memcpy? - CCommand m_CurrentCommand; -}; - - -//----------------------------------------------------------------------------- -// Returns the next command -//----------------------------------------------------------------------------- -inline int CCommandBuffer::ArgC() const -{ - return m_CurrentCommand.ArgC(); -} - -inline const char **CCommandBuffer::ArgV() const -{ - return m_CurrentCommand.ArgV(); -} - -inline const char *CCommandBuffer::ArgS() const -{ - return m_CurrentCommand.ArgS(); -} - -inline const char *CCommandBuffer::GetCommandString() const -{ - return m_CurrentCommand.GetCommandString(); -} - -inline const CCommand& CCommandBuffer::GetCommand() const -{ - return m_CurrentCommand; -} - -#endif // COMMANDBUFFER_H diff --git a/Resources/NetHook/tier1/KeyValues.cpp b/Resources/NetHook/tier1/KeyValues.cpp deleted file mode 100644 index 9916ddfd..00000000 --- a/Resources/NetHook/tier1/KeyValues.cpp +++ /dev/null @@ -1,2516 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#if defined( _WIN32 ) && !defined( _X360 ) -#include // for WideCharToMultiByte and MultiByteToWideChar -#elif defined(_LINUX) -#include // wcslen() -#define _alloca alloca -#endif - -#include -#include "filesystem.h" -#include - -#include -#include -#include "tier0/dbg.h" -#include "tier0/mem.h" -#include "utlvector.h" -#include "utlbuffer.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include - -static char * s_LastFileLoadingFrom = "unknown"; // just needed for error messages - -#define KEYVALUES_TOKEN_SIZE 1024 -static char s_pTokenBuf[KEYVALUES_TOKEN_SIZE]; - - -#define INTERNALWRITE( pData, len ) InternalWrite( filesystem, f, pBuf, pData, len ) - - -// a simple class to keep track of a stack of valid parsed symbols -const int MAX_ERROR_STACK = 64; -class CKeyValuesErrorStack -{ -public: - CKeyValuesErrorStack() : m_pFilename("NULL"), m_errorIndex(0), m_maxErrorIndex(0) {} - - void SetFilename( const char *pFilename ) - { - m_pFilename = pFilename; - m_maxErrorIndex = 0; - } - - // entering a new keyvalues block, save state for errors - // Not save symbols instead of pointers because the pointers can move! - int Push( int symName ) - { - if ( m_errorIndex < MAX_ERROR_STACK ) - { - m_errorStack[m_errorIndex] = symName; - } - m_errorIndex++; - m_maxErrorIndex = max( m_maxErrorIndex, (m_errorIndex-1) ); - return m_errorIndex-1; - } - - // exiting block, error isn't in this block, remove. - void Pop() - { - m_errorIndex--; - Assert(m_errorIndex>=0); - } - - // Allows you to keep the same stack level, but change the name as you parse peers - void Reset( int stackLevel, int symName ) - { - Assert( stackLevel >= 0 && stackLevel < m_errorIndex ); - m_errorStack[stackLevel] = symName; - } - - // Hit an error, report it and the parsing stack for context - void ReportError( const char *pError ) - { - Warning( "KeyValues Error: %s in file %s\n", pError, m_pFilename ); - for ( int i = 0; i < m_maxErrorIndex; i++ ) - { - if ( m_errorStack[i] != INVALID_KEY_SYMBOL ) - { - if ( i < m_errorIndex ) - { - Warning( "%s, ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i]) ); - } - else - { - Warning( "(*%s*), ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i]) ); - } - } - } - Warning( "\n" ); - } - -private: - int m_errorStack[MAX_ERROR_STACK]; - const char *m_pFilename; - int m_errorIndex; - int m_maxErrorIndex; -} g_KeyValuesErrorStack; - - -// a simple helper that creates stack entries as it goes in & out of scope -class CKeyErrorContext -{ -public: - CKeyErrorContext( KeyValues *pKv ) - { - Init( pKv->GetNameSymbol() ); - } - - ~CKeyErrorContext() - { - g_KeyValuesErrorStack.Pop(); - } - CKeyErrorContext( int symName ) - { - Init( symName ); - } - void Reset( int symName ) - { - g_KeyValuesErrorStack.Reset( m_stackLevel, symName ); - } -private: - void Init( int symName ) - { - m_stackLevel = g_KeyValuesErrorStack.Push( symName ); - } - - int m_stackLevel; -}; - -// Uncomment this line to hit the ~CLeakTrack assert to see what's looking like it's leaking -// #define LEAKTRACK - -#ifdef LEAKTRACK - -class CLeakTrack -{ -public: - CLeakTrack() - { - } - ~CLeakTrack() - { - if ( keys.Count() != 0 ) - { - Assert( 0 ); - } - } - - struct kve - { - KeyValues *kv; - char name[ 256 ]; - }; - - void AddKv( KeyValues *kv, char const *name ) - { - kve k; - Q_strncpy( k.name, name ? name : "NULL", sizeof( k.name ) ); - k.kv = kv; - - keys.AddToTail( k ); - } - - void RemoveKv( KeyValues *kv ) - { - int c = keys.Count(); - for ( int i = 0; i < c; i++ ) - { - if ( keys[i].kv == kv ) - { - keys.Remove( i ); - break; - } - } - } - - CUtlVector< kve > keys; -}; - -static CLeakTrack track; - -#define TRACK_KV_ADD( ptr, name ) track.AddKv( ptr, name ) -#define TRACK_KV_REMOVE( ptr ) track.RemoveKv( ptr ) - -#else - -#define TRACK_KV_ADD( ptr, name ) -#define TRACK_KV_REMOVE( ptr ) - -#endif - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName ( setName ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const char *firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetString( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const wchar_t *firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetWString( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, int firstValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetInt( firstKey, firstValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, const char *firstValue, const char *secondKey, const char *secondValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetString( firstKey, firstValue ); - SetString( secondKey, secondValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -KeyValues::KeyValues( const char *setName, const char *firstKey, int firstValue, const char *secondKey, int secondValue ) -{ - TRACK_KV_ADD( this, setName ); - - Init(); - SetName( setName ); - SetInt( firstKey, firstValue ); - SetInt( secondKey, secondValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Initialize member variables -//----------------------------------------------------------------------------- -void KeyValues::Init() -{ - m_iKeyName = INVALID_KEY_SYMBOL; - m_iDataType = TYPE_NONE; - - m_pSub = NULL; - m_pPeer = NULL; - m_pChain = NULL; - - m_sValue = NULL; - m_wsValue = NULL; - m_pValue = NULL; - - m_bHasEscapeSequences = false; - - // for future proof - memset( unused, 0, sizeof(unused) ); -} - -//----------------------------------------------------------------------------- -// Purpose: Destructor -//----------------------------------------------------------------------------- -KeyValues::~KeyValues() -{ - TRACK_KV_REMOVE( this ); - - RemoveEverything(); -} - -//----------------------------------------------------------------------------- -// Purpose: remove everything -//----------------------------------------------------------------------------- -void KeyValues::RemoveEverything() -{ - KeyValues *dat; - KeyValues *datNext = NULL; - for ( dat = m_pSub; dat != NULL; dat = datNext ) - { - datNext = dat->m_pPeer; - dat->m_pPeer = NULL; - delete dat; - } - - for ( dat = m_pPeer; dat && dat != this; dat = datNext ) - { - datNext = dat->m_pPeer; - dat->m_pPeer = NULL; - delete dat; - } - - delete [] m_sValue; - m_sValue = NULL; - delete [] m_wsValue; - m_wsValue = NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *f - -//----------------------------------------------------------------------------- - -void KeyValues::RecursiveSaveToFile( CUtlBuffer& buf, int indentLevel ) -{ - RecursiveSaveToFile( NULL, FILESYSTEM_INVALID_HANDLE, &buf, indentLevel ); -} - -//----------------------------------------------------------------------------- -// Adds a chain... if we don't find stuff in this keyvalue, we'll look -// in the one we're chained to. -//----------------------------------------------------------------------------- - -void KeyValues::ChainKeyValue( KeyValues* pChain ) -{ - m_pChain = pChain; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the name of the current key section -//----------------------------------------------------------------------------- -const char *KeyValues::GetName( void ) const -{ - return KeyValuesSystem()->GetStringForSymbol(m_iKeyName); -} - -//----------------------------------------------------------------------------- -// Purpose: Get the symbol name of the current key section -//----------------------------------------------------------------------------- -int KeyValues::GetNameSymbol() const -{ - return m_iKeyName; -} - - -//----------------------------------------------------------------------------- -// Purpose: Read a single token from buffer (0 terminated) -//----------------------------------------------------------------------------- -#pragma warning (disable:4706) -const char *KeyValues::ReadToken( CUtlBuffer &buf, bool &wasQuoted, bool &wasConditional ) -{ - wasQuoted = false; - wasConditional = false; - - if ( !buf.IsValid() ) - return NULL; - - // eating white spaces and remarks loop - while ( true ) - { - buf.EatWhiteSpace(); - if ( !buf.IsValid() ) - return NULL; // file ends after reading whitespaces - - // stop if it's not a comment; a new token starts here - if ( !buf.EatCPPComment() ) - break; - } - - const char *c = (const char*)buf.PeekGet( sizeof(char), 0 ); - if ( !c ) - return NULL; - - // read quoted strings specially - if ( *c == '\"' ) - { - wasQuoted = true; - buf.GetDelimitedString( m_bHasEscapeSequences ? GetCStringCharConversion() : GetNoEscCharConversion(), - s_pTokenBuf, KEYVALUES_TOKEN_SIZE ); - return s_pTokenBuf; - } - - if ( *c == '{' || *c == '}' ) - { - // it's a control char, just add this one char and stop reading - s_pTokenBuf[0] = *c; - s_pTokenBuf[1] = 0; - buf.SeekGet( CUtlBuffer::SEEK_CURRENT, 1 ); - return s_pTokenBuf; - } - - // read in the token until we hit a whitespace or a control character - bool bReportedError = false; - bool bConditionalStart = false; - int nCount = 0; - while ( c = (const char*)buf.PeekGet( sizeof(char), 0 ) ) - { - // end of file - if ( *c == 0 ) - break; - - // break if any control character appears in non quoted tokens - if ( *c == '"' || *c == '{' || *c == '}' ) - break; - - if ( *c == '[' ) - bConditionalStart = true; - - if ( *c == ']' && bConditionalStart ) - { - wasConditional = true; - } - - // break on whitespace - if ( isspace(*c) ) - break; - - if (nCount < (KEYVALUES_TOKEN_SIZE-1) ) - { - s_pTokenBuf[nCount++] = *c; // add char to buffer - } - else if ( !bReportedError ) - { - bReportedError = true; - g_KeyValuesErrorStack.ReportError(" ReadToken overflow" ); - } - - buf.SeekGet( CUtlBuffer::SEEK_CURRENT, 1 ); - } - s_pTokenBuf[ nCount ] = 0; - return s_pTokenBuf; -} -#pragma warning (default:4706) - - - -//----------------------------------------------------------------------------- -// Purpose: if parser should translate escape sequences ( /n, /t etc), set to true -//----------------------------------------------------------------------------- -void KeyValues::UsesEscapeSequences(bool state) -{ - m_bHasEscapeSequences = state; -} - - -//----------------------------------------------------------------------------- -// Purpose: Load keyValues from disk -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID ) -{ - Assert(filesystem); - Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) ); - - FileHandle_t f = filesystem->Open(resourceName, "rb", pathID); - if ( !f ) - return false; - - s_LastFileLoadingFrom = (char*)resourceName; - - // load file into a null-terminated buffer - int fileSize = filesystem->Size( f ); - unsigned bufSize = ((IFileSystem *)filesystem)->GetOptimalReadSize( f, fileSize + 1 ); - - char *buffer = (char*)((IFileSystem *)filesystem)->AllocOptimalReadBuffer( f, bufSize ); - Assert( buffer ); - - // read into local buffer - bool bRetOK = ( ((IFileSystem *)filesystem)->ReadEx( buffer, bufSize, fileSize, f ) != 0 ); - - filesystem->Close( f ); // close file after reading - - if ( bRetOK ) - { - buffer[fileSize] = 0; // null terminate file as EOF - bRetOK = LoadFromBuffer( resourceName, buffer, filesystem ); - } - - ((IFileSystem *)filesystem)->FreeOptimalReadBuffer( buffer ); - - return bRetOK; -} - -//----------------------------------------------------------------------------- -// Purpose: Save the keyvalues to disk -// Creates the path to the file if it doesn't exist -//----------------------------------------------------------------------------- -bool KeyValues::SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID ) -{ - // create a write file - FileHandle_t f = filesystem->Open(resourceName, "wb", pathID); - - if ( f == FILESYSTEM_INVALID_HANDLE ) - { - DevMsg(1, "KeyValues::SaveToFile: couldn't open file \"%s\" in path \"%s\".\n", - resourceName?resourceName:"NULL", pathID?pathID:"NULL" ); - return false; - } - - RecursiveSaveToFile(filesystem, f, NULL, 0); - filesystem->Close(f); - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Write out a set of indenting -//----------------------------------------------------------------------------- -void KeyValues::WriteIndents( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ) -{ - for ( int i = 0; i < indentLevel; i++ ) - { - INTERNALWRITE( "\t", 1 ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Write out a string where we convert the double quotes to backslash double quote -//----------------------------------------------------------------------------- -void KeyValues::WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString ) -{ - // handle double quote chars within the string - // the worst possible case is that the whole string is quotes - int len = Q_strlen(pszString); - char *convertedString = (char *) _alloca ((len + 1) * sizeof(char) * 2); - int j=0; - for (int i=0; i <= len; i++) - { - if (pszString[i] == '\"') - { - convertedString[j] = '\\'; - j++; - } - else if ( m_bHasEscapeSequences && pszString[i] == '\\' ) - { - convertedString[j] = '\\'; - j++; - } - convertedString[j] = pszString[i]; - j++; - } - - INTERNALWRITE(convertedString, strlen(convertedString)); -} - - -void KeyValues::InternalWrite( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len ) -{ - if ( filesystem ) - { - filesystem->Write( pData, len, f ); - } - - if ( pBuf ) - { - pBuf->Put( pData, len ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Save keyvalues from disk, if subkey values are detected, calls -// itself to save those -//----------------------------------------------------------------------------- -void KeyValues::RecursiveSaveToFile( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ) -{ - // write header - WriteIndents( filesystem, f, pBuf, indentLevel ); - INTERNALWRITE("\"", 1); - WriteConvertedString(filesystem, f, pBuf, GetName()); - INTERNALWRITE("\"\n", 2); - WriteIndents( filesystem, f, pBuf, indentLevel ); - INTERNALWRITE("{\n", 2); - - // loop through all our keys writing them to disk - for ( KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer ) - { - if ( dat->m_pSub ) - { - dat->RecursiveSaveToFile( filesystem, f, pBuf, indentLevel + 1 ); - } - else - { - // only write non-empty keys - - switch (dat->m_iDataType) - { - case TYPE_STRING: - { - if (dat->m_sValue && *(dat->m_sValue)) - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - WriteConvertedString(filesystem, f, pBuf, dat->GetName()); - INTERNALWRITE("\"\t\t\"", 4); - - WriteConvertedString(filesystem, f, pBuf, dat->m_sValue); - - INTERNALWRITE("\"\n", 2); - } - break; - } - case TYPE_WSTRING: - { -#ifdef _WIN32 - if ( dat->m_wsValue ) - { - static char buf[KEYVALUES_TOKEN_SIZE]; - // make sure we have enough space - Assert(::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, NULL, 0, NULL, NULL) < KEYVALUES_TOKEN_SIZE); - int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, buf, KEYVALUES_TOKEN_SIZE, NULL, NULL); - if (result) - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - WriteConvertedString(filesystem, f, pBuf, buf); - - INTERNALWRITE("\"\n", 2); - } - } -#endif - break; - } - - case TYPE_INT: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[32]; - Q_snprintf(buf, sizeof( buf ), "%d", dat->m_iValue); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - - case TYPE_UINT64: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[32]; - // write "0x" + 16 char 0-padded hex encoded 64 bit value - Q_snprintf( buf, sizeof( buf ), "0x%016I64X", *( (uint64 *)dat->m_sValue ) ); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - - case TYPE_FLOAT: - { - WriteIndents(filesystem, f, pBuf, indentLevel + 1); - INTERNALWRITE("\"", 1); - INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName())); - INTERNALWRITE("\"\t\t\"", 4); - - char buf[48]; - Q_snprintf(buf, sizeof( buf ), "%f", dat->m_flValue); - - INTERNALWRITE(buf, Q_strlen(buf)); - INTERNALWRITE("\"\n", 2); - break; - } - case TYPE_COLOR: - DevMsg(1, "KeyValues::RecursiveSaveToFile: TODO, missing code for TYPE_COLOR.\n"); - break; - - default: - break; - } - } - } - - // write tail - WriteIndents(filesystem, f, pBuf, indentLevel); - INTERNALWRITE("}\n", 2); -} - -//----------------------------------------------------------------------------- -// Purpose: looks up a key by symbol name -//----------------------------------------------------------------------------- -KeyValues *KeyValues::FindKey(int keySymbol) const -{ - for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - if (dat->m_iKeyName == keySymbol) - return dat; - } - - return NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: Find a keyValue, create it if it is not found. -// Set bCreate to true to create the key if it doesn't already exist -// (which ensures a valid pointer will be returned) -//----------------------------------------------------------------------------- -KeyValues *KeyValues::FindKey(const char *keyName, bool bCreate) -{ - // return the current key if a NULL subkey is asked for - if (!keyName || !keyName[0]) - return this; - - // look for '/' characters deliminating sub fields - char szBuf[256]; - const char *subStr = strchr(keyName, '/'); - const char *searchStr = keyName; - - // pull out the substring if it exists - if (subStr) - { - int size = subStr - keyName; - Q_memcpy( szBuf, keyName, size ); - szBuf[size] = 0; - searchStr = szBuf; - } - - // lookup the symbol for the search string - HKeySymbol iSearchStr = KeyValuesSystem()->GetSymbolForString( searchStr, bCreate ); - if ( iSearchStr == INVALID_KEY_SYMBOL ) - { - // not found, couldn't possibly be in key value list - return NULL; - } - - KeyValues *lastItem = NULL; - KeyValues *dat; - // find the searchStr in the current peer list - for (dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - lastItem = dat; // record the last item looked at (for if we need to append to the end of the list) - - // symbol compare - if (dat->m_iKeyName == iSearchStr) - { - break; - } - } - - if ( !dat && m_pChain ) - { - dat = m_pChain->FindKey(keyName, false); - } - - // make sure a key was found - if (!dat) - { - if (bCreate) - { - // we need to create a new key - dat = new KeyValues( searchStr ); -// Assert(dat != NULL); - - // insert new key at end of list - if (lastItem) - { - lastItem->m_pPeer = dat; - } - else - { - m_pSub = dat; - } - dat->m_pPeer = NULL; - - // a key graduates to be a submsg as soon as it's m_pSub is set - // this should be the only place m_pSub is set - m_iDataType = TYPE_NONE; - } - else - { - return NULL; - } - } - - // if we've still got a subStr we need to keep looking deeper in the tree - if ( subStr ) - { - // recursively chain down through the paths in the string - return dat->FindKey(subStr + 1, bCreate); - } - - return dat; -} - -//----------------------------------------------------------------------------- -// Purpose: Create a new key, with an autogenerated name. -// Name is guaranteed to be an integer, of value 1 higher than the highest -// other integer key name -//----------------------------------------------------------------------------- -KeyValues *KeyValues::CreateNewKey() -{ - int newID = 1; - - // search for any key with higher values - for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer) - { - // case-insensitive string compare - int val = atoi(dat->GetName()); - if (newID <= val) - { - newID = val + 1; - } - } - - char buf[12]; - Q_snprintf( buf, sizeof(buf), "%d", newID ); - - return CreateKey( buf ); -} - - -//----------------------------------------------------------------------------- -// Create a key -//----------------------------------------------------------------------------- -KeyValues* KeyValues::CreateKey( const char *keyName ) -{ - // key wasn't found so just create a new one - KeyValues* dat = new KeyValues( keyName ); - - dat->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // use same format as parent does - - // add into subkey list - AddSubKey( dat ); - - return dat; -} - - -//----------------------------------------------------------------------------- -// Adds a subkey. Make sure the subkey isn't a child of some other keyvalues -//----------------------------------------------------------------------------- -void KeyValues::AddSubKey( KeyValues *pSubkey ) -{ - // Make sure the subkey isn't a child of some other keyvalues - Assert( pSubkey->m_pPeer == NULL ); - - // add into subkey list - if ( m_pSub == NULL ) - { - m_pSub = pSubkey; - } - else - { - KeyValues *pTempDat = m_pSub; - while ( pTempDat->GetNextKey() != NULL ) - { - pTempDat = pTempDat->GetNextKey(); - } - - pTempDat->SetNextKey( pSubkey ); - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Remove a subkey from the list -//----------------------------------------------------------------------------- -void KeyValues::RemoveSubKey(KeyValues *subKey) -{ - if (!subKey) - return; - - // check the list pointer - if (m_pSub == subKey) - { - m_pSub = subKey->m_pPeer; - } - else - { - // look through the list - KeyValues *kv = m_pSub; - while (kv->m_pPeer) - { - if (kv->m_pPeer == subKey) - { - kv->m_pPeer = subKey->m_pPeer; - break; - } - - kv = kv->m_pPeer; - } - } - - subKey->m_pPeer = NULL; -} - - - -//----------------------------------------------------------------------------- -// Purpose: Return the first subkey in the list -//----------------------------------------------------------------------------- -KeyValues *KeyValues::GetFirstSubKey() -{ - return m_pSub; -} - -//----------------------------------------------------------------------------- -// Purpose: Return the next subkey -//----------------------------------------------------------------------------- -KeyValues *KeyValues::GetNextKey() -{ - return m_pPeer; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets this key's peer to the KeyValues passed in -//----------------------------------------------------------------------------- -void KeyValues::SetNextKey( KeyValues *pDat ) -{ - m_pPeer = pDat; -} - - -KeyValues* KeyValues::GetFirstTrueSubKey() -{ - KeyValues *pRet = m_pSub; - while ( pRet && pRet->m_iDataType != TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetNextTrueSubKey() -{ - KeyValues *pRet = m_pPeer; - while ( pRet && pRet->m_iDataType != TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetFirstValue() -{ - KeyValues *pRet = m_pSub; - while ( pRet && pRet->m_iDataType == TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - -KeyValues* KeyValues::GetNextValue() -{ - KeyValues *pRet = m_pPeer; - while ( pRet && pRet->m_iDataType == TYPE_NONE ) - pRet = pRet->m_pPeer; - - return pRet; -} - - -//----------------------------------------------------------------------------- -// Purpose: Get the integer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -int KeyValues::GetInt( const char *keyName, int defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return atoi(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return _wtoi(dat->m_wsValue); -#else - DevMsg( "TODO: implement _wtoi\n"); - return 0; -#endif - case TYPE_FLOAT: - return (int)dat->m_flValue; - case TYPE_UINT64: - // can't convert, since it would lose data - Assert(0); - return 0; - case TYPE_INT: - case TYPE_PTR: - default: - return dat->m_iValue; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the integer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -uint64 KeyValues::GetUint64( const char *keyName, uint64 defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return atoi(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return _wtoi(dat->m_wsValue); -#else - AssertFatal( 0 ); - return 0; -#endif - case TYPE_FLOAT: - return (int)dat->m_flValue; - case TYPE_UINT64: - return *((uint64 *)dat->m_sValue); - case TYPE_INT: - case TYPE_PTR: - default: - return dat->m_iValue; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the pointer value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -void *KeyValues::GetPtr( const char *keyName, void *defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_PTR: - return dat->m_pValue; - - case TYPE_WSTRING: - case TYPE_STRING: - case TYPE_FLOAT: - case TYPE_INT: - case TYPE_UINT64: - default: - return NULL; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the float value of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -float KeyValues::GetFloat( const char *keyName, float defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - switch ( dat->m_iDataType ) - { - case TYPE_STRING: - return (float)atof(dat->m_sValue); - case TYPE_WSTRING: -#ifdef _WIN32 - return (float) _wtof(dat->m_wsValue); // no wtof -#else - Assert(0); - return 0.; -#endif - case TYPE_FLOAT: - return dat->m_flValue; - case TYPE_INT: - return (float)dat->m_iValue; - case TYPE_UINT64: - return (float)(*((uint64 *)dat->m_sValue)); - case TYPE_PTR: - default: - return 0.0f; - }; - } - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the string pointer of a keyName. Default value is returned -// if the keyName can't be found. -//----------------------------------------------------------------------------- -const char *KeyValues::GetString( const char *keyName, const char *defaultValue ) -{ - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - // convert the data to string form then return it - char buf[64]; - switch ( dat->m_iDataType ) - { - case TYPE_FLOAT: - Q_snprintf( buf, sizeof( buf ), "%f", dat->m_flValue ); - SetString( keyName, buf ); - break; - case TYPE_INT: - case TYPE_PTR: - Q_snprintf( buf, sizeof( buf ), "%d", dat->m_iValue ); - SetString( keyName, buf ); - break; - case TYPE_UINT64: - Q_snprintf( buf, sizeof( buf ), "%I64i", *((uint64 *)(dat->m_sValue)) ); - SetString( keyName, buf ); - break; - - case TYPE_WSTRING: - { -#ifdef _WIN32 - // convert the string to char *, set it for future use, and return it - char wideBuf[512]; - int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, wideBuf, 512, NULL, NULL); - if ( result ) - { - // note: this will copy wideBuf - SetString( keyName, wideBuf ); - } - else - { - return defaultValue; - } -#endif - break; - } - case TYPE_STRING: - break; - default: - return defaultValue; - }; - - return dat->m_sValue; - } - return defaultValue; -} - -const wchar_t *KeyValues::GetWString( const char *keyName, const wchar_t *defaultValue) -{ - KeyValues *dat = FindKey( keyName, false ); -#ifdef _WIN32 - if ( dat ) - { - wchar_t wbuf[64]; - switch ( dat->m_iDataType ) - { - case TYPE_FLOAT: - swprintf(wbuf, L"%f", dat->m_flValue); - SetWString( keyName, wbuf); - break; - case TYPE_INT: - case TYPE_PTR: - swprintf( wbuf, L"%d", dat->m_iValue ); - SetWString( keyName, wbuf ); - break; - case TYPE_UINT64: - { - swprintf( wbuf, L"%I64i", *((uint64 *)(dat->m_sValue)) ); - SetWString( keyName, wbuf ); - } - break; - - case TYPE_WSTRING: - break; - case TYPE_STRING: - { - static wchar_t wbuftemp[512]; // convert to wide - int result = ::MultiByteToWideChar(CP_UTF8, 0, dat->m_sValue, -1, wbuftemp, 512); - if ( result ) - { - SetWString( keyName, wbuftemp); - } - else - { - return defaultValue; - } - break; - } - default: - return defaultValue; - }; - - return (const wchar_t* )dat->m_wsValue; - } -#else - DevMsg("TODO: implement wide char functions\n"); -#endif - return defaultValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Gets a color -//----------------------------------------------------------------------------- -Color KeyValues::GetColor( const char *keyName ) -{ - Color color(0, 0, 0, 0); - KeyValues *dat = FindKey( keyName, false ); - if ( dat ) - { - if ( dat->m_iDataType == TYPE_COLOR ) - { - color[0] = dat->m_Color[0]; - color[1] = dat->m_Color[1]; - color[2] = dat->m_Color[2]; - color[3] = dat->m_Color[3]; - } - else if ( dat->m_iDataType == TYPE_FLOAT ) - { - color[0] = dat->m_flValue; - } - else if ( dat->m_iDataType == TYPE_INT ) - { - color[0] = dat->m_iValue; - } - else if ( dat->m_iDataType == TYPE_STRING ) - { - // parse the colors out of the string - float a, b, c, d; - sscanf(dat->m_sValue, "%f %f %f %f", &a, &b, &c, &d); - color[0] = (unsigned char)a; - color[1] = (unsigned char)b; - color[2] = (unsigned char)c; - color[3] = (unsigned char)d; - } - } - return color; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets a color -//----------------------------------------------------------------------------- -void KeyValues::SetColor( const char *keyName, Color value) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_iDataType = TYPE_COLOR; - dat->m_Color[0] = value[0]; - dat->m_Color[1] = value[1]; - dat->m_Color[2] = value[2]; - dat->m_Color[3] = value[3]; - } -} - -void KeyValues::SetStringValue( char const *strValue ) -{ - // delete the old value - delete [] m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] m_wsValue; - m_wsValue = NULL; - - if (!strValue) - { - // ensure a valid value - strValue = ""; - } - - // allocate memory for the new value and copy it in - int len = Q_strlen( strValue ); - m_sValue = new char[len + 1]; - Q_memcpy( m_sValue, strValue, len+1 ); - - m_iDataType = TYPE_STRING; -} - -//----------------------------------------------------------------------------- -// Purpose: Set the string value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetString( const char *keyName, const char *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - // delete the old value - delete [] dat->m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] dat->m_wsValue; - dat->m_wsValue = NULL; - - if (!value) - { - // ensure a valid value - value = ""; - } - - // allocate memory for the new value and copy it in - int len = Q_strlen( value ); - dat->m_sValue = new char[len + 1]; - Q_memcpy( dat->m_sValue, value, len+1 ); - - dat->m_iDataType = TYPE_STRING; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the string value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetWString( const char *keyName, const wchar_t *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - if ( dat ) - { - // delete the old value - delete [] dat->m_wsValue; - // make sure we're not storing the STRING - as we're converting over to WSTRING - delete [] dat->m_sValue; - dat->m_sValue = NULL; - - if (!value) - { - // ensure a valid value - value = L""; - } - - // allocate memory for the new value and copy it in - int len = wcslen( value ); - dat->m_wsValue = new wchar_t[len + 1]; - Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) ); - - dat->m_iDataType = TYPE_WSTRING; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the integer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetInt( const char *keyName, int value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_iValue = value; - dat->m_iDataType = TYPE_INT; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the integer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetUint64( const char *keyName, uint64 value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - // delete the old value - delete [] dat->m_sValue; - // make sure we're not storing the WSTRING - as we're converting over to STRING - delete [] dat->m_wsValue; - dat->m_wsValue = NULL; - - dat->m_sValue = new char[sizeof(uint64)]; - *((uint64 *)dat->m_sValue) = value; - dat->m_iDataType = TYPE_UINT64; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Set the float value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetFloat( const char *keyName, float value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_flValue = value; - dat->m_iDataType = TYPE_FLOAT; - } -} - -void KeyValues::SetName( const char * setName ) -{ - m_iKeyName = KeyValuesSystem()->GetSymbolForString( setName ); -} - -//----------------------------------------------------------------------------- -// Purpose: Set the pointer value of a keyName. -//----------------------------------------------------------------------------- -void KeyValues::SetPtr( const char *keyName, void *value ) -{ - KeyValues *dat = FindKey( keyName, true ); - - if ( dat ) - { - dat->m_pValue = value; - dat->m_iDataType = TYPE_PTR; - } -} - -void KeyValues::RecursiveCopyKeyValues( KeyValues& src ) -{ - // garymcthack - need to check this code for possible buffer overruns. - - m_iKeyName = src.GetNameSymbol(); - - if( !src.m_pSub ) - { - m_iDataType = src.m_iDataType; - char buf[256]; - switch( src.m_iDataType ) - { - case TYPE_NONE: - break; - case TYPE_STRING: - if( src.m_sValue ) - { - int len = Q_strlen(src.m_sValue) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, src.m_sValue, len ); - } - break; - case TYPE_INT: - { - m_iValue = src.m_iValue; - Q_snprintf( buf,sizeof(buf), "%d", m_iValue ); - int len = Q_strlen(buf) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, buf, len ); - } - break; - case TYPE_FLOAT: - { - m_flValue = src.m_flValue; - Q_snprintf( buf,sizeof(buf), "%f", m_flValue ); - int len = Q_strlen(buf) + 1; - m_sValue = new char[len]; - Q_strncpy( m_sValue, buf, len ); - } - break; - case TYPE_PTR: - { - m_pValue = src.m_pValue; - } - break; - case TYPE_UINT64: - { - m_sValue = new char[sizeof(uint64)]; - Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) ); - } - break; - case TYPE_COLOR: - { - m_Color[0] = src.m_Color[0]; - m_Color[1] = src.m_Color[1]; - m_Color[2] = src.m_Color[2]; - m_Color[3] = src.m_Color[3]; - } - break; - - default: - { - // do nothing . .what the heck is this? - Assert( 0 ); - } - break; - } - - } -#if 0 - KeyValues *pDst = this; - for ( KeyValues *pSrc = src.m_pSub; pSrc; pSrc = pSrc->m_pPeer ) - { - if ( pSrc->m_pSub ) - { - pDst->m_pSub = new KeyValues( pSrc->m_pSub->getName() ); - pDst->m_pSub->RecursiveCopyKeyValues( *pSrc->m_pSub ); - } - else - { - // copy non-empty keys - if ( pSrc->m_sValue && *(pSrc->m_sValue) ) - { - pDst->m_pPeer = new KeyValues( - } - } - } -#endif - - // Handle the immediate child - if( src.m_pSub ) - { - m_pSub = new KeyValues( NULL ); - m_pSub->RecursiveCopyKeyValues( *src.m_pSub ); - } - - // Handle the immediate peer - if( src.m_pPeer ) - { - m_pPeer = new KeyValues( NULL ); - m_pPeer->RecursiveCopyKeyValues( *src.m_pPeer ); - } -} - -KeyValues& KeyValues::operator=( KeyValues& src ) -{ - RemoveEverything(); - Init(); // reset all values - RecursiveCopyKeyValues( src ); - return *this; -} - - -//----------------------------------------------------------------------------- -// Make a new copy of all subkeys, add them all to the passed-in keyvalues -//----------------------------------------------------------------------------- -void KeyValues::CopySubkeys( KeyValues *pParent ) const -{ - // recursively copy subkeys - // Also maintain ordering.... - KeyValues *pPrev = NULL; - for ( KeyValues *sub = m_pSub; sub != NULL; sub = sub->m_pPeer ) - { - // take a copy of the subkey - KeyValues *dat = sub->MakeCopy(); - - // add into subkey list - if (pPrev) - { - pPrev->m_pPeer = dat; - } - else - { - pParent->m_pSub = dat; - } - dat->m_pPeer = NULL; - pPrev = dat; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Makes a copy of the whole key-value pair set -//----------------------------------------------------------------------------- -KeyValues *KeyValues::MakeCopy( void ) const -{ - KeyValues *newKeyValue = new KeyValues(GetName()); - - // copy data - newKeyValue->m_iDataType = m_iDataType; - switch ( m_iDataType ) - { - case TYPE_STRING: - { - if ( m_sValue ) - { - int len = Q_strlen( m_sValue ); - Assert( !newKeyValue->m_sValue ); - newKeyValue->m_sValue = new char[len + 1]; - Q_memcpy( newKeyValue->m_sValue, m_sValue, len+1 ); - } - } - break; - case TYPE_WSTRING: - { - if ( m_wsValue ) - { - int len = wcslen( m_wsValue ); - newKeyValue->m_wsValue = new wchar_t[len+1]; - Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t)); - } - } - break; - - case TYPE_INT: - newKeyValue->m_iValue = m_iValue; - break; - - case TYPE_FLOAT: - newKeyValue->m_flValue = m_flValue; - break; - - case TYPE_PTR: - newKeyValue->m_pValue = m_pValue; - break; - - case TYPE_COLOR: - newKeyValue->m_Color[0] = m_Color[0]; - newKeyValue->m_Color[1] = m_Color[1]; - newKeyValue->m_Color[2] = m_Color[2]; - newKeyValue->m_Color[3] = m_Color[3]; - break; - - case TYPE_UINT64: - newKeyValue->m_sValue = new char[sizeof(uint64)]; - Q_memcpy( newKeyValue->m_sValue, m_sValue, sizeof(uint64) ); - break; - }; - - // recursively copy subkeys - CopySubkeys( newKeyValue ); - return newKeyValue; -} - - -//----------------------------------------------------------------------------- -// Purpose: Check if a keyName has no value assigned to it. -//----------------------------------------------------------------------------- -bool KeyValues::IsEmpty(const char *keyName) -{ - KeyValues *dat = FindKey(keyName, false); - if (!dat) - return true; - - if (dat->m_iDataType == TYPE_NONE && dat->m_pSub == NULL) - return true; - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Clear out all subkeys, and the current value -//----------------------------------------------------------------------------- -void KeyValues::Clear( void ) -{ - delete m_pSub; - m_pSub = NULL; - m_iDataType = TYPE_NONE; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the data type of the value stored in a keyName -//----------------------------------------------------------------------------- -KeyValues::types_t KeyValues::GetDataType(const char *keyName) -{ - KeyValues *dat = FindKey(keyName, false); - if (dat) - return (types_t)dat->m_iDataType; - - return TYPE_NONE; -} - -//----------------------------------------------------------------------------- -// Purpose: Deletion, ensures object gets deleted from correct heap -//----------------------------------------------------------------------------- -void KeyValues::deleteThis() -{ - delete this; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : includedKeys - -//----------------------------------------------------------------------------- -void KeyValues::AppendIncludedKeys( CUtlVector< KeyValues * >& includedKeys ) -{ - // Append any included keys, too... - int includeCount = includedKeys.Count(); - int i; - for ( i = 0; i < includeCount; i++ ) - { - KeyValues *kv = includedKeys[ i ]; - Assert( kv ); - - KeyValues *insertSpot = this; - while ( insertSpot->GetNextKey() ) - { - insertSpot = insertSpot->GetNextKey(); - } - - insertSpot->SetNextKey( kv ); - } -} - -void KeyValues::ParseIncludedKeys( char const *resourceName, const char *filetoinclude, - IBaseFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys ) -{ - Assert( resourceName ); - Assert( filetoinclude ); - Assert( pFileSystem ); - - // Load it... - if ( !pFileSystem ) - { - return; - } - - // Get relative subdirectory - char fullpath[ 512 ]; - Q_strncpy( fullpath, resourceName, sizeof( fullpath ) ); - - // Strip off characters back to start or first / - bool done = false; - int len = Q_strlen( fullpath ); - while ( !done ) - { - if ( len <= 0 ) - { - break; - } - - if ( fullpath[ len - 1 ] == '\\' || - fullpath[ len - 1 ] == '/' ) - { - break; - } - - // zero it - fullpath[ len - 1 ] = 0; - --len; - } - - // Append included file - Q_strncat( fullpath, filetoinclude, sizeof( fullpath ), COPY_ALL_CHARACTERS ); - - KeyValues *newKV = new KeyValues( fullpath ); - - // CUtlSymbol save = s_CurrentFileSymbol; // did that had any use ??? - - newKV->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // use same format as parent - - if ( newKV->LoadFromFile( pFileSystem, fullpath, pPathID ) ) - { - includedKeys.AddToTail( newKV ); - } - else - { - DevMsg( "KeyValues::ParseIncludedKeys: Couldn't load included keyvalue file %s\n", fullpath ); - newKV->deleteThis(); - } - - // s_CurrentFileSymbol = save; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : baseKeys - -//----------------------------------------------------------------------------- -void KeyValues::MergeBaseKeys( CUtlVector< KeyValues * >& baseKeys ) -{ - int includeCount = baseKeys.Count(); - int i; - for ( i = 0; i < includeCount; i++ ) - { - KeyValues *kv = baseKeys[ i ]; - Assert( kv ); - - RecursiveMergeKeyValues( kv ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : baseKV - keyvalues we're basing ourselves on -//----------------------------------------------------------------------------- -void KeyValues::RecursiveMergeKeyValues( KeyValues *baseKV ) -{ - // Merge ourselves - // we always want to keep our value, so nothing to do here - - // Now merge our children - for ( KeyValues *baseChild = baseKV->m_pSub; baseChild != NULL; baseChild = baseChild->m_pPeer ) - { - // for each child in base, see if we have a matching kv - - bool bFoundMatch = false; - - // If we have a child by the same name, merge those keys - for ( KeyValues *newChild = m_pSub; newChild != NULL; newChild = newChild->m_pPeer ) - { - if ( !Q_strcmp( baseChild->GetName(), newChild->GetName() ) ) - { - newChild->RecursiveMergeKeyValues( baseChild ); - bFoundMatch = true; - break; - } - } - - // If not merged, append this key - if ( !bFoundMatch ) - { - KeyValues *dat = baseChild->MakeCopy(); - Assert( dat ); - AddSubKey( dat ); - } - } -} - -//----------------------------------------------------------------------------- -// Returns whether a keyvalues conditional evaluates to true or false -// Needs more flexibility with conditionals, checking convars would be nice. -//----------------------------------------------------------------------------- -bool EvaluateConditional( const char *str ) -{ - bool bResult = false; - bool bXboxUI = IsX360(); - - if ( bXboxUI ) - { - bResult = !Q_stricmp( "[$X360]", str ); - } - else - { - bResult = !Q_stricmp( "[$WIN32]", str ); - } - - return bResult; -} - - -//----------------------------------------------------------------------------- -// Read from a buffer... -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IBaseFileSystem* pFileSystem, const char *pPathID ) -{ - KeyValues *pPreviousKey = NULL; - KeyValues *pCurrentKey = this; - CUtlVector< KeyValues * > includedKeys; - CUtlVector< KeyValues * > baseKeys; - bool wasQuoted; - bool wasConditional; - g_KeyValuesErrorStack.SetFilename( resourceName ); - do - { - bool bAccepted = true; - - // the first thing must be a key - const char *s = ReadToken( buf, wasQuoted, wasConditional ); - if ( !buf.IsValid() || !s || *s == 0 ) - break; - - if ( !Q_stricmp( s, "#include" ) ) // special include macro (not a key name) - { - s = ReadToken( buf, wasQuoted, wasConditional ); - // Name of subfile to load is now in s - - if ( !s || *s == 0 ) - { - g_KeyValuesErrorStack.ReportError("#include is NULL " ); - } - else - { - ParseIncludedKeys( resourceName, s, pFileSystem, pPathID, includedKeys ); - } - - continue; - } - else if ( !Q_stricmp( s, "#base" ) ) - { - s = ReadToken( buf, wasQuoted, wasConditional ); - // Name of subfile to load is now in s - - if ( !s || *s == 0 ) - { - g_KeyValuesErrorStack.ReportError("#base is NULL " ); - } - else - { - ParseIncludedKeys( resourceName, s, pFileSystem, pPathID, baseKeys ); - } - - continue; - } - - if ( !pCurrentKey ) - { - pCurrentKey = new KeyValues( s ); - Assert( pCurrentKey ); - - pCurrentKey->UsesEscapeSequences( m_bHasEscapeSequences != 0 ); // same format has parent use - - if ( pPreviousKey ) - { - pPreviousKey->SetNextKey( pCurrentKey ); - } - } - else - { - pCurrentKey->SetName( s ); - } - - // get the '{' - s = ReadToken( buf, wasQuoted, wasConditional ); - - if ( wasConditional ) - { - bAccepted = EvaluateConditional( s ); - - // Now get the '{' - s = ReadToken( buf, wasQuoted, wasConditional ); - } - - if ( s && *s == '{' && !wasQuoted ) - { - // header is valid so load the file - pCurrentKey->RecursiveLoadFromBuffer( resourceName, buf ); - } - else - { - g_KeyValuesErrorStack.ReportError("LoadFromBuffer: missing {" ); - } - - if ( !bAccepted ) - { - if ( pPreviousKey ) - { - pPreviousKey->SetNextKey( NULL ); - } - pCurrentKey->Clear(); - } - else - { - pPreviousKey = pCurrentKey; - pCurrentKey = NULL; - } - } while ( buf.IsValid() ); - - AppendIncludedKeys( includedKeys ); - { - // delete included keys! - int i; - for ( i = includedKeys.Count() - 1; i > 0; i-- ) - { - KeyValues *kv = includedKeys[ i ]; - kv->deleteThis(); - } - } - - MergeBaseKeys( baseKeys ); - { - // delete base keys! - int i; - for ( i = baseKeys.Count() - 1; i >= 0; i-- ) - { - KeyValues *kv = baseKeys[ i ]; - kv->deleteThis(); - } - } - - g_KeyValuesErrorStack.SetFilename( "" ); - - return true; -} - - -//----------------------------------------------------------------------------- -// Read from a buffer... -//----------------------------------------------------------------------------- -bool KeyValues::LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem, const char *pPathID ) -{ - if ( !pBuffer ) - return true; - - int nLen = Q_strlen( pBuffer ); - CUtlBuffer buf( pBuffer, nLen, CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER ); - return LoadFromBuffer( resourceName, buf, pFileSystem, pPathID ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &buf ) -{ - CKeyErrorContext errorReport(this); - bool wasQuoted; - bool wasConditional; - // keep this out of the stack until a key is parsed - CKeyErrorContext errorKey( INVALID_KEY_SYMBOL ); - while ( 1 ) - { - bool bAccepted = true; - - // get the key name - const char * name = ReadToken( buf, wasQuoted, wasConditional ); - - if ( !name ) // EOF stop reading - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got EOF instead of keyname" ); - break; - } - - if ( !*name ) // empty token, maybe "" or EOF - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got empty keyname" ); - break; - } - - if ( *name == '}' && !wasQuoted ) // top level closed, stop reading - break; - - // Always create the key; note that this could potentially - // cause some duplication, but that's what we want sometimes - KeyValues *dat = CreateKey( name ); - - errorKey.Reset( dat->GetNameSymbol() ); - - // get the value - const char * value = ReadToken( buf, wasQuoted, wasConditional ); - - if ( wasConditional && value ) - { - bAccepted = EvaluateConditional( value ); - - // get the real value - value = ReadToken( buf, wasQuoted, wasConditional ); - } - - if ( !value ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got NULL key" ); - break; - } - - if ( *value == '}' && !wasQuoted ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got } in key" ); - break; - } - - if ( *value == '{' && !wasQuoted ) - { - // this isn't a key, it's a section - errorKey.Reset( INVALID_KEY_SYMBOL ); - // sub value list - dat->RecursiveLoadFromBuffer( resourceName, buf ); - } - else - { - if ( wasConditional ) - { - g_KeyValuesErrorStack.ReportError("RecursiveLoadFromBuffer: got conditional between key and value" ); - break; - } - - if (dat->m_sValue) - { - delete[] dat->m_sValue; - dat->m_sValue = NULL; - } - - int len = Q_strlen( value ); - - // Here, let's determine if we got a float or an int.... - char* pIEnd; // pos where int scan ended - char* pFEnd; // pos where float scan ended - const char* pSEnd = value + len ; // pos where token ends - - int ival = strtol( value, &pIEnd, 10 ); - float fval = (float)strtod( value, &pFEnd ); - - if ( *value == 0 ) - { - dat->m_iDataType = TYPE_STRING; - } - else if ( ( 18 == len ) && ( value[0] == '0' ) && ( value[1] == 'x' ) ) - { - // an 18-byte value prefixed with "0x" (followed by 16 hex digits) is an int64 value - int64 retVal = 0; - for( int i=2; i < 2 + 16; i++ ) - { - char digit = value[i]; - if ( digit >= 'a' ) - digit -= 'a' - ( '9' + 1 ); - else - if ( digit >= 'A' ) - digit -= 'A' - ( '9' + 1 ); - retVal = ( retVal * 16 ) + ( digit - '0' ); - } - dat->m_sValue = new char[sizeof(uint64)]; - *((uint64 *)dat->m_sValue) = retVal; - dat->m_iDataType = TYPE_UINT64; - } - else if ( (pFEnd > pIEnd) && (pFEnd == pSEnd) ) - { - dat->m_flValue = fval; - dat->m_iDataType = TYPE_FLOAT; - } - else if (pIEnd == pSEnd) - { - dat->m_iValue = ival; - dat->m_iDataType = TYPE_INT; - } - else - { - dat->m_iDataType = TYPE_STRING; - } - - if (dat->m_iDataType == TYPE_STRING) - { - // copy in the string information - dat->m_sValue = new char[len+1]; - Q_memcpy( dat->m_sValue, value, len+1 ); - } - - // Look ahead one token for a conditional tag - int prevPos = buf.TellGet(); - const char *peek = ReadToken( buf, wasQuoted, wasConditional ); - if ( wasConditional ) - { - bAccepted = EvaluateConditional( peek ); - } - else - { - buf.SeekGet( CUtlBuffer::SEEK_HEAD, prevPos ); - } - } - - if ( !bAccepted ) - { - this->RemoveSubKey( dat ); - dat->deleteThis(); - dat = NULL; - } - } -} - - - -// writes KeyValue as binary data to buffer -bool KeyValues::WriteAsBinary( CUtlBuffer &buffer ) -{ - if ( buffer.IsText() ) // must be a binary buffer - return false; - - if ( !buffer.IsValid() ) // must be valid, no overflows etc - return false; - - // Write subkeys: - - // loop through all our peers - for ( KeyValues *dat = this; dat != NULL; dat = dat->m_pPeer ) - { - // write type - buffer.PutUnsignedChar( dat->m_iDataType ); - - // write name - buffer.PutString( dat->GetName() ); - - // write type - switch (dat->m_iDataType) - { - case TYPE_NONE: - { - dat->m_pSub->WriteAsBinary( buffer ); - break; - } - case TYPE_STRING: - { - if (dat->m_sValue && *(dat->m_sValue)) - { - buffer.PutString( dat->m_sValue ); - } - else - { - buffer.PutString( "" ); - } - break; - } - case TYPE_WSTRING: - { - Assert( !"TYPE_WSTRING" ); - break; - } - - case TYPE_INT: - { - buffer.PutInt( dat->m_iValue ); - break; - } - - case TYPE_UINT64: - { - buffer.PutDouble( *((double *)dat->m_sValue) ); - break; - } - - case TYPE_FLOAT: - { - buffer.PutFloat( dat->m_flValue ); - break; - } - case TYPE_COLOR: - { - buffer.PutUnsignedChar( dat->m_Color[0] ); - buffer.PutUnsignedChar( dat->m_Color[1] ); - buffer.PutUnsignedChar( dat->m_Color[2] ); - buffer.PutUnsignedChar( dat->m_Color[3] ); - break; - } - case TYPE_PTR: - { - buffer.PutUnsignedInt( (int)dat->m_pValue ); - } - - default: - break; - } - } - - // write tail, marks end of peers - buffer.PutUnsignedChar( TYPE_NUMTYPES ); - - return buffer.IsValid(); -} - -// read KeyValues from binary buffer, returns true if parsing was successful -bool KeyValues::ReadAsBinary( CUtlBuffer &buffer ) -{ - if ( buffer.IsText() ) // must be a binary buffer - return false; - - if ( !buffer.IsValid() ) // must be valid, no overflows etc - return false; - - RemoveEverything(); // remove current content - Init(); // reset - - char token[KEYVALUES_TOKEN_SIZE]; - KeyValues *dat = this; - types_t type = (types_t)buffer.GetUnsignedChar(); - - // loop through all our peers - while ( true ) - { - if ( type == TYPE_NUMTYPES ) - break; // no more peers - - dat->m_iDataType = type; - - buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); - token[KEYVALUES_TOKEN_SIZE-1] = 0; - - dat->SetName( token ); - - switch ( type ) - { - case TYPE_NONE: - { - dat->m_pSub = new KeyValues(""); - dat->m_pSub->ReadAsBinary( buffer ); - break; - } - case TYPE_STRING: - { - buffer.GetString( token, KEYVALUES_TOKEN_SIZE-1 ); - token[KEYVALUES_TOKEN_SIZE-1] = 0; - - int len = Q_strlen( token ); - dat->m_sValue = new char[len + 1]; - Q_memcpy( dat->m_sValue, token, len+1 ); - - break; - } - case TYPE_WSTRING: - { - Assert( !"TYPE_WSTRING" ); - break; - } - - case TYPE_INT: - { - dat->m_iValue = buffer.GetInt(); - break; - } - - case TYPE_UINT64: - { - dat->m_sValue = new char[sizeof(uint64)]; - *((double *)dat->m_sValue) = buffer.GetDouble(); - } - - case TYPE_FLOAT: - { - dat->m_flValue = buffer.GetFloat(); - break; - } - case TYPE_COLOR: - { - dat->m_Color[0] = buffer.GetUnsignedChar(); - dat->m_Color[1] = buffer.GetUnsignedChar(); - dat->m_Color[2] = buffer.GetUnsignedChar(); - dat->m_Color[3] = buffer.GetUnsignedChar(); - break; - } - case TYPE_PTR: - { - dat->m_pValue = (void*)buffer.GetUnsignedInt(); - } - - default: - break; - } - - if ( !buffer.IsValid() ) // error occured - return false; - - type = (types_t)buffer.GetUnsignedChar(); - - if ( type == TYPE_NUMTYPES ) - break; - - // new peer follows - dat->m_pPeer = new KeyValues(""); - dat = dat->m_pPeer; - } - - return buffer.IsValid(); -} - -#include "tier0/memdbgoff.h" - -//----------------------------------------------------------------------------- -// Purpose: memory allocator -//----------------------------------------------------------------------------- -void *KeyValues::operator new( unsigned int iAllocSize ) -{ - MEM_ALLOC_CREDIT(); - return KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); -} - -void *KeyValues::operator new( unsigned int iAllocSize, int nBlockUse, const char *pFileName, int nLine ) -{ - MemAlloc_PushAllocDbgInfo( pFileName, nLine ); - void *p = KeyValuesSystem()->AllocKeyValuesMemory(iAllocSize); - MemAlloc_PopAllocDbgInfo(); - return p; -} - -//----------------------------------------------------------------------------- -// Purpose: deallocator -//----------------------------------------------------------------------------- -void KeyValues::operator delete( void *pMem ) -{ - KeyValuesSystem()->FreeKeyValuesMemory(pMem); -} - -void KeyValues::operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) -{ - KeyValuesSystem()->FreeKeyValuesMemory(pMem); -} - -void KeyValues::UnpackIntoStructure( KeyValuesUnpackStructure const *pUnpackTable, void *pDest ) -{ - uint8 *dest=(uint8 *) pDest; - while( pUnpackTable->m_pKeyName ) - { - uint8 *dest_field=dest+pUnpackTable->m_nFieldOffset; - KeyValues *find_it=FindKey( pUnpackTable->m_pKeyName ); - switch( pUnpackTable->m_eDataType ) - { - case UNPACK_TYPE_FLOAT: - { - float default_value=(pUnpackTable->m_pKeyDefault)?atof(pUnpackTable->m_pKeyDefault):0.0; - *( ( float *) dest_field)=GetFloat( pUnpackTable->m_pKeyName, default_value ); - break; - } - break; - - case UNPACK_TYPE_VECTOR: - { - Vector *dest_v=(Vector *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f %f", - &(dest_v->x), &(dest_v->y), &(dest_v->z)) != 3)) - dest_v->Init( 0, 0, 0 ); - } - break; - - case UNPACK_TYPE_FOUR_FLOATS: - { - float *dest_f=(float *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f %f %f", - dest_f,dest_f+1,dest_f+2,dest_f+3)) != 4) - memset( dest_f, 0, 4*sizeof(float) ); - } - break; - - case UNPACK_TYPE_TWO_FLOATS: - { - float *dest_f=(float *) dest_field; - char const *src_string= - GetString( pUnpackTable->m_pKeyName, pUnpackTable->m_pKeyDefault ); - if ( (!src_string) || - ( sscanf(src_string,"%f %f", - dest_f,dest_f+1)) != 2) - memset( dest_f, 0, 2*sizeof(float) ); - } - break; - - case UNPACK_TYPE_STRING: - { - char *dest_s=(char *) dest_field; - strncpy( dest_s, GetString( pUnpackTable->m_pKeyName, - pUnpackTable->m_pKeyDefault ), - pUnpackTable->m_nFieldSize ); - - } - break; - - case UNPACK_TYPE_INT: - { - int *dest_i=(int *) dest_field; - int default_int=0; - if ( pUnpackTable->m_pKeyDefault) - default_int = atoi( pUnpackTable->m_pKeyDefault ); - *(dest_i)=GetInt( pUnpackTable->m_pKeyName, default_int ); - } - break; - - case UNPACK_TYPE_VECTOR_COLOR: - { - Vector *dest_v=(Vector *) dest_field; - if (find_it) - { - Color c=GetColor( pUnpackTable->m_pKeyName ); - dest_v->x = c.r(); - dest_v->y = c.g(); - dest_v->z = c.b(); - } - else - { - if ( pUnpackTable->m_pKeyDefault ) - sscanf(pUnpackTable->m_pKeyDefault,"%f %f %f", - &(dest_v->x), &(dest_v->y), &(dest_v->z)); - else - dest_v->Init( 0, 0, 0 ); - } - *(dest_v) *= (1.0/255); - } - } - pUnpackTable++; - } -} - -//----------------------------------------------------------------------------- -// Helper function for processing a keyvalue tree for console resolution support. -// Alters key/values for easier console video resolution support. -// If running SD (640x480), the presence of "???_lodef" creates or slams "???". -// If running HD (1280x720), the presence of "???_hidef" creates or slams "???". -//----------------------------------------------------------------------------- -bool KeyValues::ProcessResolutionKeys( const char *pResString ) -{ - if ( !pResString ) - { - // not for pc, console only - return false; - } - - KeyValues *pSubKey = GetFirstSubKey(); - if ( !pSubKey ) - { - // not a block - return false; - } - - for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() ) - { - // recursively descend each sub block - pSubKey->ProcessResolutionKeys( pResString ); - - // check to see if our substring is present - if ( Q_stristr( pSubKey->GetName(), pResString ) != NULL ) - { - char normalKeyName[128]; - V_strncpy( normalKeyName, pSubKey->GetName(), sizeof( normalKeyName ) ); - - // substring must match exactly, otherwise keys like "_lodef" and "_lodef_wide" would clash. - char *pString = Q_stristr( normalKeyName, pResString ); - if ( pString && !Q_stricmp( pString, pResString ) ) - { - *pString = '\0'; - - // find and delete the original key (if any) - KeyValues *pKey = FindKey( normalKeyName ); - if ( pKey ) - { - // remove the key - RemoveSubKey( pKey ); - } - - // rename the marked key - pSubKey->SetName( normalKeyName ); - } - } - } - - return true; -} diff --git a/Resources/NetHook/tier1/KeyValues.h b/Resources/NetHook/tier1/KeyValues.h deleted file mode 100644 index 52856d64..00000000 --- a/Resources/NetHook/tier1/KeyValues.h +++ /dev/null @@ -1,357 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef KEYVALUES_H -#define KEYVALUES_H - -#ifdef _WIN32 -#pragma once -#endif - -// #include - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif - -#include "utlvector.h" -#include "Color.h" - -class IBaseFileSystem; -class CUtlBuffer; -class Color; -typedef void * FileHandle_t; - -//----------------------------------------------------------------------------- -// Purpose: Simple recursive data access class -// Used in vgui for message parameters and resource files -// Destructor deletes all child KeyValues nodes -// Data is stored in key (string names) - (string/int/float)value pairs called nodes. -// -// About KeyValues Text File Format: - -// It has 3 control characters '{', '}' and '"'. Names and values may be quoted or -// not. The quote '"' charater must not be used within name or values, only for -// quoting whole tokens. You may use escape sequences wile parsing and add within a -// quoted token a \" to add quotes within your name or token. When using Escape -// Sequence the parser must now that by setting KeyValues::UsesEscapeSequences( true ), -// which it's off by default. Non-quoted tokens ends with a whitespace, '{', '}' and '"'. -// So you may use '{' and '}' within quoted tokens, but not for non-quoted tokens. -// An open bracket '{' after a key name indicates a list of subkeys which is finished -// with a closing bracket '}'. Subkeys use the same definitions recursively. -// Whitespaces are space, return, newline and tabulator. Allowed Escape sequences -// are \n, \t, \\, \n and \". The number character '#' is used for macro purposes -// (eg #include), don't use it as first charater in key names. -//----------------------------------------------------------------------------- -class KeyValues -{ -public: - KeyValues( const char *setName ); - - // - // AutoDelete class to automatically free the keyvalues. - // Simply construct it with the keyvalues you allocated and it will free them when falls out of scope. - // When you decide that keyvalues shouldn't be deleted call Assign(NULL) on it. - // If you constructed AutoDelete(NULL) you can later assign the keyvalues to be deleted with Assign(pKeyValues). - // You can also pass temporary KeyValues object as an argument to a function by wrapping it into KeyValues::AutoDelete - // instance: call_my_function( KeyValues::AutoDelete( new KeyValues( "test" ) ) ) - // - class AutoDelete - { - public: - explicit inline AutoDelete( KeyValues *pKeyValues ) : m_pKeyValues( pKeyValues ) {} - inline ~AutoDelete( void ) { if( m_pKeyValues ) m_pKeyValues->deleteThis(); } - inline void Assign( KeyValues *pKeyValues ) { m_pKeyValues = pKeyValues; } - private: - AutoDelete( AutoDelete const &x ); // forbid - AutoDelete & operator= ( AutoDelete const &x ); // forbid - KeyValues *m_pKeyValues; - }; - - // Quick setup constructors - KeyValues( const char *setName, const char *firstKey, const char *firstValue ); - KeyValues( const char *setName, const char *firstKey, const wchar_t *firstValue ); - KeyValues( const char *setName, const char *firstKey, int firstValue ); - KeyValues( const char *setName, const char *firstKey, const char *firstValue, const char *secondKey, const char *secondValue ); - KeyValues( const char *setName, const char *firstKey, int firstValue, const char *secondKey, int secondValue ); - - // Section name - const char *GetName() const; - void SetName( const char *setName); - - // gets the name as a unique int - int GetNameSymbol() const; - - // File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t) - void UsesEscapeSequences(bool state); // default false - bool LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL ); - bool SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL); - - // Read from a buffer... Note that the buffer must be null terminated - bool LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL ); - - // Read from a utlbuffer... - bool LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL ); - - // Find a keyValue, create it if it is not found. - // Set bCreate to true to create the key if it doesn't already exist (which ensures a valid pointer will be returned) - KeyValues *FindKey(const char *keyName, bool bCreate = false); - KeyValues *FindKey(int keySymbol) const; - KeyValues *CreateNewKey(); // creates a new key, with an autogenerated name. name is guaranteed to be an integer, of value 1 higher than the highest other integer key name - void AddSubKey( KeyValues *pSubkey ); // Adds a subkey. Make sure the subkey isn't a child of some other keyvalues - void RemoveSubKey(KeyValues *subKey); // removes a subkey from the list, DOES NOT DELETE IT - - // Key iteration. - // - // NOTE: GetFirstSubKey/GetNextKey will iterate keys AND values. Use the functions - // below if you want to iterate over just the keys or just the values. - // - KeyValues *GetFirstSubKey(); // returns the first subkey in the list - KeyValues *GetNextKey(); // returns the next subkey - void SetNextKey( KeyValues * pDat); - - // - // These functions can be used to treat it like a true key/values tree instead of - // confusing values with keys. - // - // So if you wanted to iterate all subkeys, then all values, it would look like this: - // for ( KeyValues *pKey = pRoot->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() ) - // { - // Msg( "Key name: %s\n", pKey->GetName() ); - // } - // for ( KeyValues *pValue = pRoot->GetFirstValue(); pKey; pKey = pKey->GetNextValue() ) - // { - // Msg( "Int value: %d\n", pValue->GetInt() ); // Assuming pValue->GetDataType() == TYPE_INT... - // } - KeyValues* GetFirstTrueSubKey(); - KeyValues* GetNextTrueSubKey(); - - KeyValues* GetFirstValue(); // When you get a value back, you can use GetX and pass in NULL to get the value. - KeyValues* GetNextValue(); - - - // Data access - int GetInt( const char *keyName = NULL, int defaultValue = 0 ); - uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 ); - float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f ); - const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ); - const wchar_t *GetWString( const char *keyName = NULL, const wchar_t *defaultValue = L"" ); - void *GetPtr( const char *keyName = NULL, void *defaultValue = (void*)0 ); - Color GetColor( const char *keyName = NULL /* default value is all black */); - bool IsEmpty(const char *keyName = NULL); - - // Data access - int GetInt( int keySymbol, int defaultValue = 0 ); - float GetFloat( int keySymbol, float defaultValue = 0.0f ); - const char *GetString( int keySymbol, const char *defaultValue = "" ); - const wchar_t *GetWString( int keySymbol, const wchar_t *defaultValue = L"" ); - void *GetPtr( int keySymbol, void *defaultValue = (void*)0 ); - Color GetColor( int keySymbol /* default value is all black */); - bool IsEmpty( int keySymbol ); - - // Key writing - void SetWString( const char *keyName, const wchar_t *value ); - void SetString( const char *keyName, const char *value ); - void SetInt( const char *keyName, int value ); - void SetUint64( const char *keyName, uint64 value ); - void SetFloat( const char *keyName, float value ); - void SetPtr( const char *keyName, void *value ); - void SetColor( const char *keyName, Color value); - - // Memory allocation (optimized) - void *operator new( unsigned int iAllocSize ); - void *operator new( unsigned int iAllocSize, int nBlockUse, const char *pFileName, int nLine ); - void operator delete( void *pMem ); - void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ); - - KeyValues& operator=( KeyValues& src ); - - // Adds a chain... if we don't find stuff in this keyvalue, we'll look - // in the one we're chained to. - void ChainKeyValue( KeyValues* pChain ); - - void RecursiveSaveToFile( CUtlBuffer& buf, int indentLevel ); - - bool WriteAsBinary( CUtlBuffer &buffer ); - bool ReadAsBinary( CUtlBuffer &buffer ); - - // Allocate & create a new copy of the keys - KeyValues *MakeCopy( void ) const; - - // Make a new copy of all subkeys, add them all to the passed-in keyvalues - void CopySubkeys( KeyValues *pParent ) const; - - // Clear out all subkeys, and the current value - void Clear( void ); - - // Data type - enum types_t - { - TYPE_NONE = 0, - TYPE_STRING, - TYPE_INT, - TYPE_FLOAT, - TYPE_PTR, - TYPE_WSTRING, - TYPE_COLOR, - TYPE_UINT64, - TYPE_NUMTYPES, - }; - types_t GetDataType(const char *keyName = NULL); - - // Virtual deletion function - ensures that KeyValues object is deleted from correct heap - void deleteThis(); - - void SetStringValue( char const *strValue ); - - // unpack a key values list into a structure - void UnpackIntoStructure( struct KeyValuesUnpackStructure const *pUnpackTable, void *pDest ); - - // Process conditional keys for widescreen support. - bool ProcessResolutionKeys( const char *pResString ); - -private: - KeyValues( KeyValues& ); // prevent copy constructor being used - - // prevent delete being called except through deleteThis() - ~KeyValues(); - - KeyValues* CreateKey( const char *keyName ); - - void RecursiveCopyKeyValues( KeyValues& src ); - void RemoveEverything(); -// void RecursiveSaveToFile( IBaseFileSystem *filesystem, CUtlBuffer &buffer, int indentLevel ); -// void WriteConvertedString( CUtlBuffer &buffer, const char *pszString ); - - // NOTE: If both filesystem and pBuf are non-null, it'll save to both of them. - // If filesystem is null, it'll ignore f. - void RecursiveSaveToFile( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); - void WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString ); - - void RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &buf ); - - // For handling #include "filename" - void AppendIncludedKeys( CUtlVector< KeyValues * >& includedKeys ); - void ParseIncludedKeys( char const *resourceName, const char *filetoinclude, - IBaseFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys ); - - // For handling #base "filename" - void MergeBaseKeys( CUtlVector< KeyValues * >& baseKeys ); - void RecursiveMergeKeyValues( KeyValues *baseKV ); - - // NOTE: If both filesystem and pBuf are non-null, it'll save to both of them. - // If filesystem is null, it'll ignore f. - void InternalWrite( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len ); - - void Init(); - const char * ReadToken( CUtlBuffer &buf, bool &wasQuoted, bool &wasConditional ); - void WriteIndents( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel ); - - void FreeAllocatedValue(); - void AllocateValueBlock(int size); - - int m_iKeyName; // keyname is a symbol defined in KeyValuesSystem - - // These are needed out of the union because the API returns string pointers - char *m_sValue; - wchar_t *m_wsValue; - - // we don't delete these - union - { - int m_iValue; - float m_flValue; - void *m_pValue; - unsigned char m_Color[4]; - }; - - char m_iDataType; - char m_bHasEscapeSequences; // true, if while parsing this KeyValue, Escape Sequences are used (default false) - char unused[2]; - - KeyValues *m_pPeer; // pointer to next key in list - KeyValues *m_pSub; // pointer to Start of a new sub key list - KeyValues *m_pChain;// Search here if it's not in our list -}; - -enum KeyValuesUnpackDestinationTypes_t -{ - UNPACK_TYPE_FLOAT, // dest is a float - UNPACK_TYPE_VECTOR, // dest is a Vector - UNPACK_TYPE_VECTOR_COLOR, // dest is a vector, src is a color - UNPACK_TYPE_STRING, // dest is a char *. unpacker will allocate. - UNPACK_TYPE_INT, // dest is an int - UNPACK_TYPE_FOUR_FLOATS, // dest is an array of 4 floats. source is a string like "1 2 3 4" - UNPACK_TYPE_TWO_FLOATS, // dest is an array of 2 floats. source is a string like "1 2" -}; - -#define UNPACK_FIXED( kname, kdefault, dtype, ofs ) { kname, kdefault, dtype, ofs, 0 } -#define UNPACK_VARIABLE( kname, kdefault, dtype, ofs, sz ) { kname, kdefault, dtype, ofs, sz } -#define UNPACK_END_MARKER { NULL, NULL, UNPACK_TYPE_FLOAT, 0 } - -struct KeyValuesUnpackStructure -{ - char const *m_pKeyName; // null to terminate tbl - char const *m_pKeyDefault; // null ok - KeyValuesUnpackDestinationTypes_t m_eDataType; // UNPACK_TYPE_INT, .. - size_t m_nFieldOffset; // use offsetof to set - size_t m_nFieldSize; // for strings or other variable length -}; - -//----------------------------------------------------------------------------- -// inline methods -//----------------------------------------------------------------------------- -inline int KeyValues::GetInt( int keySymbol, int defaultValue ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetInt( (const char *)NULL, defaultValue ) : defaultValue; -} - -inline float KeyValues::GetFloat( int keySymbol, float defaultValue ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetFloat( (const char *)NULL, defaultValue ) : defaultValue; -} - -inline const char *KeyValues::GetString( int keySymbol, const char *defaultValue ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetString( (const char *)NULL, defaultValue ) : defaultValue; -} - -inline const wchar_t *KeyValues::GetWString( int keySymbol, const wchar_t *defaultValue ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetWString( (const char *)NULL, defaultValue ) : defaultValue; -} - -inline void *KeyValues::GetPtr( int keySymbol, void *defaultValue ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetPtr( (const char *)NULL, defaultValue ) : defaultValue; -} - -inline Color KeyValues::GetColor( int keySymbol ) -{ - Color defaultValue( 0, 0, 0, 0 ); - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->GetColor( ) : defaultValue; -} - -inline bool KeyValues::IsEmpty( int keySymbol ) -{ - KeyValues *dat = FindKey( keySymbol ); - return dat ? dat->IsEmpty( ) : true; -} - -bool EvaluateConditional( const char *str ); - -#endif // KEYVALUES_H diff --git a/Resources/NetHook/tier1/NetAdr.cpp b/Resources/NetHook/tier1/NetAdr.cpp deleted file mode 100644 index 0d636f4f..00000000 --- a/Resources/NetHook/tier1/NetAdr.cpp +++ /dev/null @@ -1,331 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// NetAdr.cpp: implementation of the CNetAdr class. -// -//===========================================================================// -#if defined( _WIN32 ) && !defined( _X360 ) -#include -#endif - -#include "tier0/dbg.h" -#include "netadr.h" -#include "tier1/strtools.h" - -#if defined( _WIN32 ) && !defined( _X360 ) -#define WIN32_LEAN_AND_MEAN -#include -typedef int socklen_t; -#elif !defined( _X360 ) -#include // ntohs() -#include // gethostbyname() -#include // getsockname() -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -bool netadr_t::CompareAdr (const netadr_t &a, bool onlyBase) const -{ - if ( a.type != type ) - return false; - - if ( type == NA_LOOPBACK ) - return true; - - if ( type == NA_BROADCAST ) - return true; - - if ( type == NA_IP ) - { - if ( !onlyBase && (port != a.port) ) - return false; - - if ( a.ip[0] == ip[0] && a.ip[1] == ip[1] && a.ip[2] == ip[2] && a.ip[3] == ip[3] ) - return true; - } - - return false; -} - -bool netadr_t::CompareClassBAdr (const netadr_t &a) const -{ - if ( a.type != type ) - return false; - - if ( type == NA_LOOPBACK ) - return true; - - if ( type == NA_IP ) - { - if (a.ip[0] == ip[0] && a.ip[1] == ip[1] ) - return true; - } - - return false; -} - -bool netadr_t::CompareClassCAdr (const netadr_t &a) const -{ - if ( a.type != type ) - return false; - - if ( type == NA_LOOPBACK ) - return true; - - if ( type == NA_IP ) - { - if (a.ip[0] == ip[0] && a.ip[1] == ip[1] && a.ip[2] == ip[2] ) - return true; - } - - return false; -} -// reserved addresses are not routeable, so they can all be used in a LAN game -bool netadr_t::IsReservedAdr () const -{ - if ( type == NA_LOOPBACK ) - return true; - - if ( type == NA_IP ) - { - if ( (ip[0] == 10) || // 10.x.x.x is reserved - (ip[0] == 127) || // 127.x.x.x - (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || // 172.16.x.x - 172.31.x.x - (ip[0] == 192 && ip[1] >= 168) ) // 192.168.x.x - return true; - } - return false; -} - -const char * netadr_t::ToString(bool baseOnly) const -{ - static char s[64]; - - Q_strncpy (s, "unknown", sizeof( s ) ); - - if (type == NA_LOOPBACK) - { - Q_strncpy (s, "loopback", sizeof( s ) ); - } - else if (type == NA_BROADCAST) - { - Q_strncpy (s, "broadcast", sizeof( s ) ); - } - else if (type == NA_IP) - { - if ( baseOnly) - { - Q_snprintf (s, sizeof( s ), "%i.%i.%i.%i", ip[0], ip[1], ip[2], ip[3]); - } - else - { - Q_snprintf (s, sizeof( s ), "%i.%i.%i.%i:%i", ip[0], ip[1], ip[2], ip[3], ntohs(port)); - } - } - - return s; -} - -bool netadr_t::IsLocalhost() const -{ - // are we 127.0.0.1 ? - return (ip[0] == 127) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 1); -} - -bool netadr_t::IsLoopback() const -{ - // are we useding engine loopback buffers - return type == NA_LOOPBACK; -} - -void netadr_t::Clear() -{ - ip[0] = ip[1] = ip[2] = ip[3] = 0; - port = 0; - type = NA_NULL; -} - -void netadr_t::SetIP(uint8 b1, uint8 b2, uint8 b3, uint8 b4) -{ - ip[0] = b1; - ip[1] = b2; - ip[2] = b3; - ip[3] = b4; -} - -void netadr_t::SetIP(uint unIP) -{ - *((uint*)ip) = BigLong( unIP ); -} - -void netadr_t::SetType(netadrtype_t newtype) -{ - type = newtype; -} - -netadrtype_t netadr_t::GetType() const -{ - return type; -} - -unsigned short netadr_t::GetPort() const -{ - return BigShort( port ); -} - -unsigned int netadr_t::GetIP() const -{ - return *(unsigned int *)&ip;; -} - -unsigned long netadr_t::addr_ntohl() const -{ - return ntohl( GetIP() ); -} - -unsigned long netadr_t::addr_htonl() const -{ - return htonl( GetIP() ); -} - - -void netadr_t::ToSockadr (struct sockaddr * s) const -{ - Q_memset ( s, 0, sizeof(struct sockaddr)); - - if (type == NA_BROADCAST) - { - ((struct sockaddr_in*)s)->sin_family = AF_INET; - ((struct sockaddr_in*)s)->sin_port = port; - ((struct sockaddr_in*)s)->sin_addr.s_addr = INADDR_BROADCAST; - } - else if (type == NA_IP) - { - ((struct sockaddr_in*)s)->sin_family = AF_INET; - ((struct sockaddr_in*)s)->sin_addr.s_addr = *(int *)&ip; - ((struct sockaddr_in*)s)->sin_port = port; - } - else if (type == NA_LOOPBACK ) - { - ((struct sockaddr_in*)s)->sin_family = AF_INET; - ((struct sockaddr_in*)s)->sin_port = port; - ((struct sockaddr_in*)s)->sin_addr.s_addr = INADDR_LOOPBACK ; - } -} - -bool netadr_t::SetFromSockadr(const struct sockaddr * s) -{ - if (s->sa_family == AF_INET) - { - type = NA_IP; - *(int *)&ip = ((struct sockaddr_in *)s)->sin_addr.s_addr; - port = ((struct sockaddr_in *)s)->sin_port; - return true; - } - else - { - Clear(); - return false; - } -} - -bool netadr_t::IsValid() const -{ - return ( (port !=0 ) && (type != NA_NULL) && - ( ip[0] != 0 || ip[1] != 0 || ip[2] != 0 || ip[3] != 0 ) ); -} - -#ifdef _WIN32 -#undef SetPort // get around stupid WINSPOOL.H macro -#endif - -void netadr_t::SetPort(unsigned short newport) -{ - port = BigShort( newport ); -} - -void netadr_t::SetFromString( const char *pch, bool bUseDNS ) -{ - Clear(); - type = NA_IP; - - Assert( pch ); // invalid to call this with NULL pointer; fix your code bug! - if ( !pch ) // but let's not crash - return; - - - if ( pch[0] >= '0' && pch[0] <= '9' && strchr( pch, '.' ) ) - { - int n1, n2, n3, n4, n5; - int nRes = sscanf( pch, "%d.%d.%d.%d:%d", &n1, &n2, &n3, &n4, &n5 ); - if ( nRes >= 4 ) - { - SetIP( n1, n2, n3, n4 ); - } - - if ( nRes == 5 ) - { - SetPort( ( uint16 ) n5 ); - } - } - else if ( bUseDNS ) - { -// X360TBD: -#if !defined( _X360 ) - char szHostName[ 256 ]; - Q_strncpy( szHostName, pch, sizeof(szHostName) ); - char *pchColon = strchr( szHostName, ':' ); - if ( pchColon ) - { - *pchColon = 0; - } - - // DNS it - struct hostent *h = gethostbyname( szHostName ); - if ( !h ) - return; - - SetIP( ntohl( *(int *)h->h_addr_list[0] ) ); - - if ( pchColon ) - { - SetPort( atoi( ++pchColon ) ); - } -#else - Assert( 0 ); -#endif - } -} - -bool netadr_t::operator<(const netadr_t &netadr) const -{ - if ( *((uint *)netadr.ip) < *((uint *)ip) ) - return true; - else if ( *((uint *)netadr.ip) > *((uint *)ip) ) - return false; - return ( netadr.port < port ); -} - - -void netadr_t::SetFromSocket( int hSocket ) -{ -#if !defined(_X360) - Clear(); - type = NA_IP; - - struct sockaddr address; - int namelen = sizeof(address); - if ( getsockname( hSocket, (struct sockaddr *)&address, (int *)&namelen) == 0 ) - { - SetFromSockadr( &address ); - } -#else - Assert(0); -#endif -} diff --git a/Resources/NetHook/tier1/UtlSortVector.h b/Resources/NetHook/tier1/UtlSortVector.h deleted file mode 100644 index e57ff78b..00000000 --- a/Resources/NetHook/tier1/UtlSortVector.h +++ /dev/null @@ -1,311 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// $Header: $ -// $NoKeywords: $ -// -// A growable array class that keeps all elements in order using binary search -//===========================================================================// - -#ifndef UTLSORTVECTOR_H -#define UTLSORTVECTOR_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "utlvector.h" - - -//----------------------------------------------------------------------------- -// class CUtlSortVector: -// description: -// This in an sorted order-preserving vector. Items may be inserted or removed -// at any point in the vector. When an item is inserted, all elements are -// moved down by one element using memmove. When an item is removed, all -// elements are shifted back down. Items are searched for in the vector -// using a binary search technique. Clients must pass in a Less() function -// into the constructor of the vector to determine the sort order. -//----------------------------------------------------------------------------- - -#ifndef _WIN32 -// gcc has no qsort_s, so i need to use a static var to hold the sort context. this makes cutlsortvector _not_ thread sfae under linux -extern void *g_pUtlSortVectorQSortContext; -#endif - -template -class CUtlSortVector : public CUtlVector -{ -public: - - // constructor - CUtlSortVector( int nGrowSize = 0, int initSize = 0 ); - CUtlSortVector( T* pMemory, int numElements ); - - // inserts (copy constructs) an element in sorted order into the list - int Insert( const T& src ); - - // Finds an element within the list using a binary search - int Find( const T& search ) const; - int FindLessOrEqual( const T& search ) const; - int FindLess( const T& search ) const; - - // Removes a particular element - void Remove( const T& search ); - void Remove( int i ); - - // Allows methods to set a context to be used with the less function.. - void SetLessContext( void *pCtx ); - - // Note that you can only use this index until sorting is redone!!! - int InsertNoSort( const T& src ); - void RedoSort( bool bForceSort = false ); - -protected: - // No copy constructor - CUtlSortVector( const CUtlSortVector & ); - - // never call these; illegal for this class - int AddToHead(); - int AddToTail(); - int InsertBefore( int elem ); - int InsertAfter( int elem ); - int AddToHead( const T& src ); - int AddToTail( const T& src ); - int InsertBefore( int elem, const T& src ); - int InsertAfter( int elem, const T& src ); - int AddMultipleToHead( int num ); - int AddMultipleToTail( int num, const T *pToCopy=NULL ); - int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); - int InsertMultipleAfter( int elem, int num ); - int AddVectorToTail( CUtlVector const &src ); - - struct QSortContext_t - { - void *m_pLessContext; - LessFunc *m_pLessFunc; - }; - -#ifdef _WIN32 - static int CompareHelper( void *context, const T *lhs, const T *rhs ) - { - QSortContext_t *ctx = reinterpret_cast< QSortContext_t * >( context ); - if ( ctx->m_pLessFunc->Less( *lhs, *rhs, ctx->m_pLessContext ) ) - return -1; - if ( ctx->m_pLessFunc->Less( *rhs, *lhs, ctx->m_pLessContext ) ) - return 1; - return 0; - } -#else - static int CompareHelper( const T *lhs, const T *rhs ) - { - QSortContext_t *ctx = reinterpret_cast< QSortContext_t * >( g_pUtlSortVectorQSortContext ); - if ( ctx->m_pLessFunc->Less( *lhs, *rhs, ctx->m_pLessContext ) ) - return -1; - if ( ctx->m_pLessFunc->Less( *rhs, *lhs, ctx->m_pLessContext ) ) - return 1; - return 0; - } -#endif - - void *m_pLessContext; - bool m_bNeedsSort; - -private: - void QuickSort( LessFunc& less, int X, int I ); -}; - - -//----------------------------------------------------------------------------- -// constructor -//----------------------------------------------------------------------------- -template -CUtlSortVector::CUtlSortVector( int nGrowSize, int initSize ) : - m_pLessContext(NULL), CUtlVector( nGrowSize, initSize ), m_bNeedsSort( false ) -{ -} - -template -CUtlSortVector::CUtlSortVector( T* pMemory, int numElements ) : - m_pLessContext(NULL), CUtlVector( pMemory, numElements ), m_bNeedsSort( false ) -{ -} - -//----------------------------------------------------------------------------- -// Allows methods to set a context to be used with the less function.. -//----------------------------------------------------------------------------- -template -void CUtlSortVector::SetLessContext( void *pCtx ) -{ - m_pLessContext = pCtx; -} - -//----------------------------------------------------------------------------- -// grows the vector -//----------------------------------------------------------------------------- -template -int CUtlSortVector::Insert( const T& src ) -{ - AssertFatal( !m_bNeedsSort ); - - int pos = FindLessOrEqual( src ) + 1; - GrowVector(); - ShiftElementsRight(pos); - CopyConstruct( &Element(pos), src ); - return pos; -} - -template -int CUtlSortVector::InsertNoSort( const T& src ) -{ - m_bNeedsSort = true; - int lastElement = CUtlVector::m_Size; - // Just stick the new element at the end of the vector, but don't do a sort - GrowVector(); - ShiftElementsRight(lastElement); - CopyConstruct( &Element(lastElement), src ); - return lastElement; -} - -template -void CUtlSortVector::QuickSort( LessFunc& less, int nLower, int nUpper ) -{ -#ifdef _WIN32 - typedef int (__cdecl *QSortCompareFunc_t)(void *context, const void *, const void *); - if ( Count() > 1 ) - { - QSortContext_t ctx; - ctx.m_pLessContext = m_pLessContext; - ctx.m_pLessFunc = &less; - - qsort_s( Base(), Count(), sizeof(T), (QSortCompareFunc_t)&CUtlSortVector::CompareHelper, &ctx ); - } -#else - typedef int (__cdecl *QSortCompareFunc_t)( const void *, const void *); - if ( Count() > 1 ) - { - QSortContext_t ctx; - ctx.m_pLessContext = m_pLessContext; - ctx.m_pLessFunc = &less; - g_pUtlSortVectorQSortContext = &ctx; - - qsort( Base(), Count(), sizeof(T), (QSortCompareFunc_t)&CUtlSortVector::CompareHelper ); - } -#endif -} - -template -void CUtlSortVector::RedoSort( bool bForceSort /*= false */ ) -{ - if ( !m_bNeedsSort && !bForceSort ) - return; - - m_bNeedsSort = false; - LessFunc less; - QuickSort( less, 0, Count() - 1 ); -} - -//----------------------------------------------------------------------------- -// finds a particular element -//----------------------------------------------------------------------------- -template -int CUtlSortVector::Find( const T& src ) const -{ - AssertFatal( !m_bNeedsSort ); - - LessFunc less; - - int start = 0, end = Count() - 1; - while (start <= end) - { - int mid = (start + end) >> 1; - if ( less.Less( Element(mid), src, m_pLessContext ) ) - { - start = mid + 1; - } - else if ( less.Less( src, Element(mid), m_pLessContext ) ) - { - end = mid - 1; - } - else - { - return mid; - } - } - return -1; -} - - -//----------------------------------------------------------------------------- -// finds a particular element -//----------------------------------------------------------------------------- -template -int CUtlSortVector::FindLessOrEqual( const T& src ) const -{ - AssertFatal( !m_bNeedsSort ); - - LessFunc less; - int start = 0, end = Count() - 1; - while (start <= end) - { - int mid = (start + end) >> 1; - if ( less.Less( Element(mid), src, m_pLessContext ) ) - { - start = mid + 1; - } - else if ( less.Less( src, Element(mid), m_pLessContext ) ) - { - end = mid - 1; - } - else - { - return mid; - } - } - return end; -} - -template -int CUtlSortVector::FindLess( const T& src ) const -{ - AssertFatal( !m_bNeedsSort ); - - LessFunc less; - int start = 0, end = Count() - 1; - while (start <= end) - { - int mid = (start + end) >> 1; - if ( less.Less( Element(mid), src, m_pLessContext ) ) - { - start = mid + 1; - } - else - { - end = mid - 1; - } - } - return end; -} - - -//----------------------------------------------------------------------------- -// Removes a particular element -//----------------------------------------------------------------------------- -template -void CUtlSortVector::Remove( const T& search ) -{ - AssertFatal( !m_bNeedsSort ); - - int pos = Find(search); - if (pos != -1) - { - CUtlVector::Remove(pos); - } -} - -template -void CUtlSortVector::Remove( int i ) -{ - CUtlVector::Remove( i ); -} - -#endif // UTLSORTVECTOR_H diff --git a/Resources/NetHook/tier1/UtlStringMap.h b/Resources/NetHook/tier1/UtlStringMap.h deleted file mode 100644 index e1e11ba1..00000000 --- a/Resources/NetHook/tier1/UtlStringMap.h +++ /dev/null @@ -1,99 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#ifndef UTLSTRINGMAP_H -#define UTLSTRINGMAP_H -#ifdef _WIN32 -#pragma once -#endif - -#include "utlsymbol.h" - -template -class CUtlStringMap -{ -public: - CUtlStringMap( bool caseInsensitive = true ) : m_SymbolTable( 0, 32, caseInsensitive ) - { - } - - // Get data by the string itself: - T& operator[]( const char *pString ) - { - CUtlSymbol symbol = m_SymbolTable.AddString( pString ); - int index = ( int )( UtlSymId_t )symbol; - if( m_Vector.Count() <= index ) - { - m_Vector.EnsureCount( index + 1 ); - } - return m_Vector[index]; - } - - // Get data by the string's symbol table ID - only used to retrieve a pre-existing symbol, not create a new one! - T& operator[]( UtlSymId_t n ) - { - Assert( n >=0 && n <= m_Vector.Count() ); - return m_Vector[n]; - } - - const T& operator[]( UtlSymId_t n ) const - { - Assert( n >=0 && n <= m_Vector.Count() ); - return m_Vector[n]; - } - - bool Defined( const char *pString ) const - { - return m_SymbolTable.Find( pString ) != UTL_INVAL_SYMBOL; - } - - UtlSymId_t Find( const char *pString ) const - { - return m_SymbolTable.Find( pString ); - } - - static UtlSymId_t InvalidIndex() - { - return UTL_INVAL_SYMBOL; - } - - int GetNumStrings( void ) const - { - return m_SymbolTable.GetNumStrings(); - } - - const char *String( int n ) const - { - return m_SymbolTable.String( n ); - } - - // Clear all of the data from the map - void Clear() - { - m_Vector.RemoveAll(); - m_SymbolTable.RemoveAll(); - } - - void Purge() - { - m_Vector.Purge(); - m_SymbolTable.RemoveAll(); - } - - void PurgeAndDeleteElements() - { - m_Vector.PurgeAndDeleteElements(); - m_SymbolTable.RemoveAll(); - } - - - -private: - CUtlVector m_Vector; - CUtlSymbolTable m_SymbolTable; -}; - -#endif // UTLSTRINGMAP_H diff --git a/Resources/NetHook/tier1/bitbuf.cpp b/Resources/NetHook/tier1/bitbuf.cpp deleted file mode 100644 index 933b02d1..00000000 --- a/Resources/NetHook/tier1/bitbuf.cpp +++ /dev/null @@ -1,1269 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#include "bitbuf.h" -#include "coordsize.h" -#include "mathlib/vector.h" -#include "mathlib/mathlib.h" -#include "tier1/strtools.h" -#include "bitvec.h" - -// FIXME: Can't use this until we get multithreaded allocations in tier0 working for tools -// This is used by VVIS and fails to link -// NOTE: This must be the last file included!!! -//#include "tier0/memdbgon.h" - -#ifdef _X360 -// mandatory ... wary of above comment and isolating, tier0 is built as MT though -#include "tier0/memdbgon.h" -#endif - -#if _WIN32 -#define FAST_BIT_SCAN 1 -#if _X360 -#define CountLeadingZeros(x) _CountLeadingZeros(x) -inline unsigned int CountTrailingZeros( unsigned int elem ) -{ - // this implements CountTrailingZeros() / BitScanForward() - unsigned int mask = elem-1; - unsigned int comp = ~elem; - elem = mask & comp; - return (32 - _CountLeadingZeros(elem)); -} -#else -#include -#pragma intrinsic(_BitScanReverse) -#pragma intrinsic(_BitScanForward) - -inline unsigned int CountLeadingZeros(unsigned int x) -{ - unsigned long firstBit; - if ( _BitScanReverse(&firstBit,x) ) - return 31 - firstBit; - return 32; -} -inline unsigned int CountTrailingZeros(unsigned int elem) -{ - unsigned long out; - if ( _BitScanForward(&out, elem) ) - return out; - return 32; -} - -#endif -#else -#define FAST_BIT_SCAN 0 -#endif - - -static BitBufErrorHandler g_BitBufErrorHandler = 0; - -inline int BitForBitnum(int bitnum) -{ - return GetBitForBitnum(bitnum); -} - -void InternalBitBufErrorHandler( BitBufErrorType errorType, const char *pDebugName ) -{ - if ( g_BitBufErrorHandler ) - g_BitBufErrorHandler( errorType, pDebugName ); -} - - -void SetBitBufErrorHandler( BitBufErrorHandler fn ) -{ - g_BitBufErrorHandler = fn; -} - - -// #define BB_PROFILING - - -// Precalculated bit masks for WriteUBitLong. Using these tables instead of -// doing the calculations gives a 33% speedup in WriteUBitLong. -unsigned long g_BitWriteMasks[32][33]; - -// (1 << i) - 1 -unsigned long g_ExtraMasks[32]; - -class CBitWriteMasksInit -{ -public: - CBitWriteMasksInit() - { - for( unsigned int startbit=0; startbit < 32; startbit++ ) - { - for( unsigned int nBitsLeft=0; nBitsLeft < 33; nBitsLeft++ ) - { - unsigned int endbit = startbit + nBitsLeft; - g_BitWriteMasks[startbit][nBitsLeft] = BitForBitnum(startbit) - 1; - if(endbit < 32) - g_BitWriteMasks[startbit][nBitsLeft] |= ~(BitForBitnum(endbit) - 1); - } - } - - for ( unsigned int maskBit=0; maskBit < 32; maskBit++ ) - g_ExtraMasks[maskBit] = BitForBitnum(maskBit) - 1; - } -}; -CBitWriteMasksInit g_BitWriteMasksInit; - - -// ---------------------------------------------------------------------------------------- // -// old_bf_write -// ---------------------------------------------------------------------------------------- // - -old_bf_write::old_bf_write() -{ - m_pData = NULL; - m_nDataBytes = 0; - m_nDataBits = -1; // set to -1 so we generate overflow on any operation - m_iCurBit = 0; - m_bOverflow = false; - m_bAssertOnOverflow = true; - m_pDebugName = NULL; -} - -old_bf_write::old_bf_write( const char *pDebugName, void *pData, int nBytes, int nBits ) -{ - m_bAssertOnOverflow = true; - m_pDebugName = pDebugName; - StartWriting( pData, nBytes, 0, nBits ); -} - -old_bf_write::old_bf_write( void *pData, int nBytes, int nBits ) -{ - m_bAssertOnOverflow = true; - m_pDebugName = NULL; - StartWriting( pData, nBytes, 0, nBits ); -} - -void old_bf_write::StartWriting( void *pData, int nBytes, int iStartBit, int nBits ) -{ - // Make sure it's dword aligned and padded. - Assert( (nBytes % 4) == 0 ); - Assert(((unsigned long)pData & 3) == 0); - - // The writing code will overrun the end of the buffer if it isn't dword aligned, so truncate to force alignment - nBytes &= ~3; - - m_pData = (unsigned char*)pData; - m_nDataBytes = nBytes; - - if ( nBits == -1 ) - { - m_nDataBits = nBytes << 3; - } - else - { - Assert( nBits <= nBytes*8 ); - m_nDataBits = nBits; - } - - m_iCurBit = iStartBit; - m_bOverflow = false; -} - -void old_bf_write::Reset() -{ - m_iCurBit = 0; - m_bOverflow = false; -} - - -void old_bf_write::SetAssertOnOverflow( bool bAssert ) -{ - m_bAssertOnOverflow = bAssert; -} - - -const char* old_bf_write::GetDebugName() -{ - return m_pDebugName; -} - - -void old_bf_write::SetDebugName( const char *pDebugName ) -{ - m_pDebugName = pDebugName; -} - - -void old_bf_write::SeekToBit( int bitPos ) -{ - m_iCurBit = bitPos; -} - - -// Sign bit comes first -void old_bf_write::WriteSBitLong( int data, int numbits ) -{ - // Do we have a valid # of bits to encode with? - Assert( numbits >= 1 ); - - // Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer. - // (Some old code writes direct integers right into the buffer). - if(data < 0) - { -#ifdef _DEBUG - if( numbits < 32 ) - { - // Make sure it doesn't overflow. - - if( data < 0 ) - { - Assert( data >= -(BitForBitnum(numbits-1)) ); - } - else - { - Assert( data < (BitForBitnum(numbits-1)) ); - } - } -#endif - - WriteUBitLong( (unsigned int)(0x80000000 + data), numbits - 1, false ); - WriteOneBit( 1 ); - } - else - { - WriteUBitLong((unsigned int)data, numbits - 1); - WriteOneBit( 0 ); - } -} - -#if _WIN32 -inline unsigned int BitCountNeededToEncode(unsigned int data) -{ -#if defined(_X360) - return (32 - CountLeadingZeros(data+1)) - 1; -#else - unsigned long firstBit; - _BitScanReverse(&firstBit,data+1); - return firstBit; -#endif -} -#endif // _WIN32 - -// writes an unsigned integer with variable bit length -void old_bf_write::WriteUBitVar( unsigned int data ) -{ - if ( ( data &0xf ) == data ) - { - WriteUBitLong( 0, 2 ); - WriteUBitLong( data, 4 ); - } - else - { - if ( ( data & 0xff ) == data ) - { - WriteUBitLong( 1, 2 ); - WriteUBitLong( data, 8 ); - } - else - { - if ( ( data & 0xfff ) == data ) - { - WriteUBitLong( 2, 2 ); - WriteUBitLong( data, 12 ); - } - else - { - WriteUBitLong( 0x3, 2 ); - WriteUBitLong( data, 32 ); - } - } - } -#if 0 -#if !FAST_BIT_SCAN - unsigned int bits = 0; - unsigned int base = 0; - - while (data > (base<<1)) - { - bits++; - base = BitForBitnum(bits)-1; - } -#else - unsigned int bits = BitCountNeededToEncode(data); - unsigned int base = GetBitForBitnum(bits)-1; -#endif - - // how many bits do we use - WriteUBitLong( 0, bits ); - - // end marker - WriteOneBit( 1 ); - - // write the value - if ( bits > 0) - WriteUBitLong( data - base , bits ); -#endif -} - -void old_bf_write::WriteBitLong(unsigned int data, int numbits, bool bSigned) -{ - if(bSigned) - WriteSBitLong((int)data, numbits); - else - WriteUBitLong(data, numbits); -} - -bool old_bf_write::WriteBits(const void *pInData, int nBits) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::WriteBits" ); -#endif - - unsigned char *pOut = (unsigned char*)pInData; - int nBitsLeft = nBits; - - // Bounds checking.. - if ( (m_iCurBit+nBits) > m_nDataBits ) - { - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); - return false; - } - - // Align output to dword boundary - while (((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8) - { - - WriteUBitLong( *pOut, 8, false ); - ++pOut; - nBitsLeft -= 8; - } - - if ( IsPC() && (nBitsLeft >= 32) && (m_iCurBit & 7) == 0 ) - { - // current bit is byte aligned, do block copy - int numbytes = nBitsLeft >> 3; - int numbits = numbytes << 3; - - Q_memcpy( m_pData+(m_iCurBit>>3), pOut, numbytes ); - pOut += numbytes; - nBitsLeft -= numbits; - m_iCurBit += numbits; - } - - // X360TBD: Can't write dwords in WriteBits because they'll get swapped - if ( IsPC() && nBitsLeft >= 32 ) - { - unsigned long iBitsRight = (m_iCurBit & 31); - unsigned long iBitsLeft = 32 - iBitsRight; - unsigned long bitMaskLeft = g_BitWriteMasks[iBitsRight][32]; - unsigned long bitMaskRight = g_BitWriteMasks[0][iBitsRight]; - - unsigned long *pData = &((unsigned long*)m_pData)[m_iCurBit>>5]; - - // Read dwords. - while(nBitsLeft >= 32) - { - unsigned long curData = *(unsigned long*)pOut; - pOut += sizeof(unsigned long); - - *pData &= bitMaskLeft; - *pData |= curData << iBitsRight; - - pData++; - - if ( iBitsLeft < 32 ) - { - curData >>= iBitsLeft; - *pData &= bitMaskRight; - *pData |= curData; - } - - nBitsLeft -= 32; - m_iCurBit += 32; - } - } - - - // write remaining bytes - while ( nBitsLeft >= 8 ) - { - WriteUBitLong( *pOut, 8, false ); - ++pOut; - nBitsLeft -= 8; - } - - // write remaining bits - if ( nBitsLeft ) - { - WriteUBitLong( *pOut, nBitsLeft, false ); - } - - return !IsOverflowed(); -} - - -bool old_bf_write::WriteBitsFromBuffer( bf_read *pIn, int nBits ) -{ - // This could be optimized a little by - while ( nBits > 32 ) - { - WriteUBitLong( pIn->ReadUBitLong( 32 ), 32 ); - nBits -= 32; - } - - WriteUBitLong( pIn->ReadUBitLong( nBits ), nBits ); - return !IsOverflowed() && !pIn->IsOverflowed(); -} - - -void old_bf_write::WriteBitAngle( float fAngle, int numbits ) -{ - int d; - unsigned int mask; - unsigned int shift; - - shift = BitForBitnum(numbits); - mask = shift - 1; - - d = (int)( (fAngle / 360.0) * shift ); - d &= mask; - - WriteUBitLong((unsigned int)d, numbits); -} - -void old_bf_write::WriteBitCoordMP( const float f, bool bIntegral, bool bLowPrecision ) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::WriteBitCoordMP" ); -#endif - int signbit = (f <= -( bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION )); - int intval = (int)abs(f); - int fractval = bLowPrecision ? - ( abs((int)(f*COORD_DENOMINATOR_LOWPRECISION)) & (COORD_DENOMINATOR_LOWPRECISION-1) ) : - ( abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1) ); - - - bool bInBounds = intval < (1 << COORD_INTEGER_BITS_MP ); - - WriteOneBit( bInBounds ); - - if ( bIntegral ) - { - // Send the sign bit - WriteOneBit( intval ); - if ( intval ) - { - WriteOneBit( signbit ); - // Send the integer if we have one. - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - if ( bInBounds ) - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS_MP ); - } - else - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - } - } - else - { - // Send the bit flags that indicate whether we have an integer part and/or a fraction part. - WriteOneBit( intval ); - // Send the sign bit - WriteOneBit( signbit ); - - if ( intval ) - { - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - if ( bInBounds ) - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS_MP ); - } - else - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - } - WriteUBitLong( (unsigned int)fractval, bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS ); - } -} - -void old_bf_write::WriteBitCoord (const float f) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::WriteBitCoord" ); -#endif - int signbit = (f <= -COORD_RESOLUTION); - int intval = (int)abs(f); - int fractval = abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1); - - - // Send the bit flags that indicate whether we have an integer part and/or a fraction part. - WriteOneBit( intval ); - WriteOneBit( fractval ); - - if ( intval || fractval ) - { - // Send the sign bit - WriteOneBit( signbit ); - - // Send the integer if we have one. - if ( intval ) - { - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - - // Send the fraction if we have one - if ( fractval ) - { - WriteUBitLong( (unsigned int)fractval, COORD_FRACTIONAL_BITS ); - } - } -} - -void old_bf_write::WriteBitFloat(float val) -{ - long intVal; - - Assert(sizeof(long) == sizeof(float)); - Assert(sizeof(float) == 4); - - intVal = *((long*)&val); - WriteUBitLong( intVal, 32 ); -} - -void old_bf_write::WriteBitVec3Coord( const Vector& fa ) -{ - int xflag, yflag, zflag; - - xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION); - yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION); - zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION); - - WriteOneBit( xflag ); - WriteOneBit( yflag ); - WriteOneBit( zflag ); - - if ( xflag ) - WriteBitCoord( fa[0] ); - if ( yflag ) - WriteBitCoord( fa[1] ); - if ( zflag ) - WriteBitCoord( fa[2] ); -} - -void old_bf_write::WriteBitNormal( float f ) -{ - int signbit = (f <= -NORMAL_RESOLUTION); - - // NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones - unsigned int fractval = abs( (int)(f*NORMAL_DENOMINATOR) ); - - // clamp.. - if (fractval > NORMAL_DENOMINATOR) - fractval = NORMAL_DENOMINATOR; - - // Send the sign bit - WriteOneBit( signbit ); - - // Send the fractional component - WriteUBitLong( fractval, NORMAL_FRACTIONAL_BITS ); -} - -void old_bf_write::WriteBitVec3Normal( const Vector& fa ) -{ - int xflag, yflag; - - xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION); - yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION); - - WriteOneBit( xflag ); - WriteOneBit( yflag ); - - if ( xflag ) - WriteBitNormal( fa[0] ); - if ( yflag ) - WriteBitNormal( fa[1] ); - - // Write z sign bit - int signbit = (fa[2] <= -NORMAL_RESOLUTION); - WriteOneBit( signbit ); -} - -void old_bf_write::WriteBitAngles( const QAngle& fa ) -{ - // FIXME: - Vector tmp( fa.x, fa.y, fa.z ); - WriteBitVec3Coord( tmp ); -} - -void old_bf_write::WriteChar(int val) -{ - WriteSBitLong(val, sizeof(char) << 3); -} - -void old_bf_write::WriteByte(int val) -{ - WriteUBitLong(val, sizeof(unsigned char) << 3); -} - -void old_bf_write::WriteShort(int val) -{ - WriteSBitLong(val, sizeof(short) << 3); -} - -void old_bf_write::WriteWord(int val) -{ - WriteUBitLong(val, sizeof(unsigned short) << 3); -} - -void old_bf_write::WriteLong(long val) -{ - WriteSBitLong(val, sizeof(long) << 3); -} - -void old_bf_write::WriteLongLong(int64 val) -{ - uint *pLongs = (uint*)&val; - - // Insert the two DWORDS according to network endian - const short endianIndex = 0x0100; - byte *idx = (byte*)&endianIndex; - WriteUBitLong(pLongs[*idx++], sizeof(long) << 3); - WriteUBitLong(pLongs[*idx], sizeof(long) << 3); -} - -void old_bf_write::WriteFloat(float val) -{ - // Pre-swap the float, since WriteBits writes raw data - LittleFloat( &val, &val ); - - WriteBits(&val, sizeof(val) << 3); -} - -bool old_bf_write::WriteBytes( const void *pBuf, int nBytes ) -{ - return WriteBits(pBuf, nBytes << 3); -} - -bool old_bf_write::WriteString(const char *pStr) -{ - if(pStr) - { - do - { - WriteChar( *pStr ); - ++pStr; - } while( *(pStr-1) != 0 ); - } - else - { - WriteChar( 0 ); - } - - return !IsOverflowed(); -} - -// ---------------------------------------------------------------------------------------- // -// old_bf_read -// ---------------------------------------------------------------------------------------- // - -old_bf_read::old_bf_read() -{ - m_pData = NULL; - m_nDataBytes = 0; - m_nDataBits = -1; // set to -1 so we overflow on any operation - m_iCurBit = 0; - m_bOverflow = false; - m_bAssertOnOverflow = true; - m_pDebugName = NULL; -} - -old_bf_read::old_bf_read( const void *pData, int nBytes, int nBits ) -{ - m_bAssertOnOverflow = true; - StartReading( pData, nBytes, 0, nBits ); -} - -old_bf_read::old_bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits ) -{ - m_bAssertOnOverflow = true; - m_pDebugName = pDebugName; - StartReading( pData, nBytes, 0, nBits ); -} - -void old_bf_read::StartReading( const void *pData, int nBytes, int iStartBit, int nBits ) -{ - // Make sure we're dword aligned. - Assert(((unsigned long)pData & 3) == 0); - - m_pData = (unsigned char*)pData; - m_nDataBytes = nBytes; - - if ( nBits == -1 ) - { - m_nDataBits = m_nDataBytes << 3; - } - else - { - Assert( nBits <= nBytes*8 ); - m_nDataBits = nBits; - } - - m_iCurBit = iStartBit; - m_bOverflow = false; -} - -void old_bf_read::Reset() -{ - m_iCurBit = 0; - m_bOverflow = false; -} - -void old_bf_read::SetAssertOnOverflow( bool bAssert ) -{ - m_bAssertOnOverflow = bAssert; -} - -const char* old_bf_read::GetDebugName() -{ - return m_pDebugName; -} - -void old_bf_read::SetDebugName( const char *pName ) -{ - m_pDebugName = pName; -} - -unsigned int old_bf_read::CheckReadUBitLong(int numbits) -{ - // Ok, just read bits out. - int i, nBitValue; - unsigned int r = 0; - - for(i=0; i < numbits; i++) - { - nBitValue = ReadOneBitNoCheck(); - r |= nBitValue << i; - } - m_iCurBit -= numbits; - - return r; -} - -void old_bf_read::ReadBits(void *pOutData, int nBits) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::ReadBits" ); -#endif - - unsigned char *pOut = (unsigned char*)pOutData; - int nBitsLeft = nBits; - - - // align output to dword boundary - while( ((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8 ) - { - *pOut = (unsigned char)ReadUBitLong(8); - ++pOut; - nBitsLeft -= 8; - } - - // X360TBD: Can't read dwords in ReadBits because they'll get swapped - if ( IsPC() ) - { - // read dwords - while ( nBitsLeft >= 32 ) - { - *((unsigned long*)pOut) = ReadUBitLong(32); - pOut += sizeof(unsigned long); - nBitsLeft -= 32; - } - } - - // read remaining bytes - while ( nBitsLeft >= 8 ) - { - *pOut = ReadUBitLong(8); - ++pOut; - nBitsLeft -= 8; - } - - // read remaining bits - if ( nBitsLeft ) - { - *pOut = ReadUBitLong(nBitsLeft); - } - -} - -float old_bf_read::ReadBitAngle( int numbits ) -{ - float fReturn; - int i; - float shift; - - shift = (float)( BitForBitnum(numbits) ); - - i = ReadUBitLong( numbits ); - fReturn = (float)i * (360.0 / shift); - - return fReturn; -} - -unsigned int old_bf_read::PeekUBitLong( int numbits ) -{ - unsigned int r; - int i, nBitValue; -#ifdef BIT_VERBOSE - int nShifts = numbits; -#endif - - old_bf_read savebf; - - savebf = *this; // Save current state info - - r = 0; - for(i=0; i < numbits; i++) - { - nBitValue = ReadOneBit(); - - // Append to current stream - if ( nBitValue ) - { - r |= BitForBitnum(i); - } - } - - *this = savebf; - -#ifdef BIT_VERBOSE - Con_Printf( "PeekBitLong: %i %i\n", nShifts, (unsigned int)r ); -#endif - - return r; -} - -// Append numbits least significant bits from data to the current bit stream -int old_bf_read::ReadSBitLong( int numbits ) -{ - int r, sign; - - r = ReadUBitLong(numbits - 1); - - // Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer. - // (Some old code writes direct integers right into the buffer). - sign = ReadOneBit(); - if(sign) - r = -((BitForBitnum(numbits-1)) - r); - - return r; -} - -const byte g_BitMask[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; -const byte g_TrailingMask[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; - -inline int old_bf_read::CountRunOfZeros() -{ - int bits = 0; - if ( m_iCurBit + 32 < m_nDataBits ) - { -#if !FAST_BIT_SCAN - while (true) - { - int value = (m_pData[m_iCurBit >> 3] & g_BitMask[m_iCurBit & 7]); - ++m_iCurBit; - if ( value ) - return bits; - ++bits; - } -#else - while (true) - { - int value = (m_pData[m_iCurBit >> 3] & g_TrailingMask[m_iCurBit & 7]); - if ( !value ) - { - int zeros = (8-(m_iCurBit&7)); - bits += zeros; - m_iCurBit += zeros; - } - else - { - int zeros = CountTrailingZeros(value) - (m_iCurBit & 7); - m_iCurBit += zeros + 1; - bits += zeros; - return bits; - } - } -#endif - } - else - { - while ( ReadOneBit() == 0 ) - bits++; - } - return bits; -} - -unsigned int old_bf_read::ReadUBitVar() -{ - switch( ReadUBitLong( 2 ) ) - { - case 0: - return ReadUBitLong( 4 ); - - case 1: - return ReadUBitLong( 8 ); - - case 2: - return ReadUBitLong( 12 ); - - default: - case 3: - return ReadUBitLong( 32 ); - } -#if 0 - int bits = CountRunOfZeros(); - - unsigned int data = BitForBitnum(bits)-1; - - // read the value - if ( bits > 0) - data += ReadUBitLong( bits ); - - return data; -#endif -} - - -unsigned int old_bf_read::ReadBitLong(int numbits, bool bSigned) -{ - if(bSigned) - return (unsigned int)ReadSBitLong(numbits); - else - return ReadUBitLong(numbits); -} - - -// Basic Coordinate Routines (these contain bit-field size AND fixed point scaling constants) -float old_bf_read::ReadBitCoord (void) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::ReadBitCoord" ); -#endif - int intval=0,fractval=0,signbit=0; - float value = 0.0; - - - // Read the required integer and fraction flags - intval = ReadOneBit(); - fractval = ReadOneBit(); - - // If we got either parse them, otherwise it's a zero. - if ( intval || fractval ) - { - // Read the sign bit - signbit = ReadOneBit(); - - // If there's an integer, read it in - if ( intval ) - { - // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] - intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - - // If there's a fraction, read it in - if ( fractval ) - { - fractval = ReadUBitLong( COORD_FRACTIONAL_BITS ); - } - - // Calculate the correct floating point value - value = intval + ((float)fractval * COORD_RESOLUTION); - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - } - - return value; -} - -float old_bf_read::ReadBitCoordMP( bool bIntegral, bool bLowPrecision ) -{ -#if defined( BB_PROFILING ) - VPROF( "old_bf_write::ReadBitCoordMP" ); -#endif - int intval=0,fractval=0,signbit=0; - float value = 0.0; - - - bool bInBounds = ReadOneBit() ? true : false; - - if ( bIntegral ) - { - // Read the required integer and fraction flags - intval = ReadOneBit(); - // If we got either parse them, otherwise it's a zero. - if ( intval ) - { - // Read the sign bit - signbit = ReadOneBit(); - - // If there's an integer, read it in - // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] - if ( bInBounds ) - { - value = ReadUBitLong( COORD_INTEGER_BITS_MP ) + 1; - } - else - { - value = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - } - } - else - { - // Read the required integer and fraction flags - intval = ReadOneBit(); - - // Read the sign bit - signbit = ReadOneBit(); - - // If we got either parse them, otherwise it's a zero. - if ( intval ) - { - if ( bInBounds ) - { - intval = ReadUBitLong( COORD_INTEGER_BITS_MP ) + 1; - } - else - { - intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - } - - // If there's a fraction, read it in - fractval = ReadUBitLong( bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS ); - - // Calculate the correct floating point value - value = intval + ((float)fractval * ( bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION ) ); - } - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - - return value; -} - -void old_bf_read::ReadBitVec3Coord( Vector& fa ) -{ - int xflag, yflag, zflag; - - // This vector must be initialized! Otherwise, If any of the flags aren't set, - // the corresponding component will not be read and will be stack garbage. - fa.Init( 0, 0, 0 ); - - xflag = ReadOneBit(); - yflag = ReadOneBit(); - zflag = ReadOneBit(); - - if ( xflag ) - fa[0] = ReadBitCoord(); - if ( yflag ) - fa[1] = ReadBitCoord(); - if ( zflag ) - fa[2] = ReadBitCoord(); -} - -float old_bf_read::ReadBitNormal (void) -{ - // Read the sign bit - int signbit = ReadOneBit(); - - // Read the fractional part - unsigned int fractval = ReadUBitLong( NORMAL_FRACTIONAL_BITS ); - - // Calculate the correct floating point value - float value = (float)fractval * NORMAL_RESOLUTION; - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - - return value; -} - -void old_bf_read::ReadBitVec3Normal( Vector& fa ) -{ - int xflag = ReadOneBit(); - int yflag = ReadOneBit(); - - if (xflag) - fa[0] = ReadBitNormal(); - else - fa[0] = 0.0f; - - if (yflag) - fa[1] = ReadBitNormal(); - else - fa[1] = 0.0f; - - // The first two imply the third (but not its sign) - int znegative = ReadOneBit(); - - float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1]; - if (fafafbfb < 1.0f) - fa[2] = sqrt( 1.0f - fafafbfb ); - else - fa[2] = 0.0f; - - if (znegative) - fa[2] = -fa[2]; -} - -void old_bf_read::ReadBitAngles( QAngle& fa ) -{ - Vector tmp; - ReadBitVec3Coord( tmp ); - fa.Init( tmp.x, tmp.y, tmp.z ); -} - -int old_bf_read::ReadChar() -{ - return ReadSBitLong(sizeof(char) << 3); -} - -int old_bf_read::ReadByte() -{ - return ReadUBitLong(sizeof(unsigned char) << 3); -} - -int old_bf_read::ReadShort() -{ - return ReadSBitLong(sizeof(short) << 3); -} - -int old_bf_read::ReadWord() -{ - return ReadUBitLong(sizeof(unsigned short) << 3); -} - -long old_bf_read::ReadLong() -{ - return ReadSBitLong(sizeof(long) << 3); -} - -int64 old_bf_read::ReadLongLong() -{ - int64 retval; - uint *pLongs = (uint*)&retval; - - // Read the two DWORDs according to network endian - const short endianIndex = 0x0100; - byte *idx = (byte*)&endianIndex; - pLongs[*idx++] = ReadUBitLong(sizeof(long) << 3); - pLongs[*idx] = ReadUBitLong(sizeof(long) << 3); - - return retval; -} - -float old_bf_read::ReadFloat() -{ - float ret; - Assert( sizeof(ret) == 4 ); - ReadBits(&ret, 32); - - // Swap the float, since ReadBits reads raw data - LittleFloat( &ret, &ret ); - return ret; -} - -bool old_bf_read::ReadBytes(void *pOut, int nBytes) -{ - ReadBits(pOut, nBytes << 3); - return !IsOverflowed(); -} - -bool old_bf_read::ReadString( char *pStr, int maxLen, bool bLine, int *pOutNumChars ) -{ - Assert( maxLen != 0 ); - - bool bTooSmall = false; - int iChar = 0; - while(1) - { - char val = ReadChar(); - if ( val == 0 ) - break; - else if ( bLine && val == '\n' ) - break; - - if ( iChar < (maxLen-1) ) - { - pStr[iChar] = val; - ++iChar; - } - else - { - bTooSmall = true; - } - } - - // Make sure it's null-terminated. - Assert( iChar < maxLen ); - pStr[iChar] = 0; - - if ( pOutNumChars ) - *pOutNumChars = iChar; - - return !IsOverflowed() && !bTooSmall; -} - - -char* old_bf_read::ReadAndAllocateString( bool *pOverflow ) -{ - char str[2048]; - - int nChars; - bool bOverflow = !ReadString( str, sizeof( str ), false, &nChars ); - if ( pOverflow ) - *pOverflow = bOverflow; - - // Now copy into the output and return it; - char *pRet = new char[ nChars + 1 ]; - for ( int i=0; i <= nChars; i++ ) - pRet[i] = str[i]; - - return pRet; -} - -void old_bf_read::ExciseBits( int startbit, int bitstoremove ) -{ - int endbit = startbit + bitstoremove; - int remaining_to_end = m_nDataBits - endbit; - - old_bf_write temp; - temp.StartWriting( (void *)m_pData, m_nDataBits << 3, startbit ); - - Seek( endbit ); - - for ( int i = 0; i < remaining_to_end; i++ ) - { - temp.WriteOneBit( ReadOneBit() ); - } - - Seek( startbit ); - - m_nDataBits -= bitstoremove; - m_nDataBytes = m_nDataBits >> 3; -} - - diff --git a/Resources/NetHook/tier1/bitbuf.h b/Resources/NetHook/tier1/bitbuf.h deleted file mode 100644 index f72bf4c2..00000000 --- a/Resources/NetHook/tier1/bitbuf.h +++ /dev/null @@ -1,1500 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -// NOTE: old_bf_read is guaranteed to return zeros if it overflows. - -#ifndef BITBUF_H -#define BITBUF_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include "mathlib/mathlib.h" -#include "mathlib/vector.h" -#include "basetypes.h" -#include "tier0/dbg.h" - - - - -//----------------------------------------------------------------------------- -// Forward declarations. -//----------------------------------------------------------------------------- - -class Vector; -class QAngle; - -//----------------------------------------------------------------------------- -// You can define a handler function that will be called in case of -// out-of-range values and overruns here. -// -// NOTE: the handler is only called in debug mode. -// -// Call SetBitBufErrorHandler to install a handler. -//----------------------------------------------------------------------------- - -typedef enum -{ - BITBUFERROR_VALUE_OUT_OF_RANGE=0, // Tried to write a value with too few bits. - BITBUFERROR_BUFFER_OVERRUN, // Was about to overrun a buffer. - - BITBUFERROR_NUM_ERRORS -} BitBufErrorType; - - -typedef void (*BitBufErrorHandler)( BitBufErrorType errorType, const char *pDebugName ); - - -#if defined( _DEBUG ) - extern void InternalBitBufErrorHandler( BitBufErrorType errorType, const char *pDebugName ); - #define CallErrorHandler( errorType, pDebugName ) InternalBitBufErrorHandler( errorType, pDebugName ); -#else - #define CallErrorHandler( errorType, pDebugName ) -#endif - - -// Use this to install the error handler. Call with NULL to uninstall your error handler. -void SetBitBufErrorHandler( BitBufErrorHandler fn ); - - -//----------------------------------------------------------------------------- -// Helpers. -//----------------------------------------------------------------------------- - -inline int BitByte( int bits ) -{ - // return PAD_NUMBER( bits, 8 ) >> 3; - return (bits + 7) >> 3; -} - -//----------------------------------------------------------------------------- -// Used for serialization -//----------------------------------------------------------------------------- - -class old_bf_write -{ -public: - old_bf_write(); - - // nMaxBits can be used as the number of bits in the buffer. - // It must be <= nBytes*8. If you leave it at -1, then it's set to nBytes * 8. - old_bf_write( void *pData, int nBytes, int nMaxBits = -1 ); - old_bf_write( const char *pDebugName, void *pData, int nBytes, int nMaxBits = -1 ); - - // Start writing to the specified buffer. - // nMaxBits can be used as the number of bits in the buffer. - // It must be <= nBytes*8. If you leave it at -1, then it's set to nBytes * 8. - void StartWriting( void *pData, int nBytes, int iStartBit = 0, int nMaxBits = -1 ); - - // Restart buffer writing. - void Reset(); - - // Get the base pointer. - unsigned char* GetBasePointer() { return m_pData; } - - // Enable or disable assertion on overflow. 99% of the time, it's a bug that we need to catch, - // but there may be the occasional buffer that is allowed to overflow gracefully. - void SetAssertOnOverflow( bool bAssert ); - - // This can be set to assign a name that gets output if the buffer overflows. - const char* GetDebugName(); - void SetDebugName( const char *pDebugName ); - - -// Seek to a specific position. -public: - - void SeekToBit( int bitPos ); - - -// Bit functions. -public: - - void WriteOneBit(int nValue); - void WriteOneBitNoCheck(int nValue); - void WriteOneBitAt( int iBit, int nValue ); - - // Write signed or unsigned. Range is only checked in debug. - void WriteUBitLong( unsigned int data, int numbits, bool bCheckRange=true ); - void WriteSBitLong( int data, int numbits ); - - // Tell it whether or not the data is unsigned. If it's signed, - // cast to unsigned before passing in (it will cast back inside). - void WriteBitLong(unsigned int data, int numbits, bool bSigned); - - // Write a list of bits in. - bool WriteBits(const void *pIn, int nBits); - - // writes an unsigned integer with variable bit length - void WriteUBitVar( unsigned int data ); - - // Copy the bits straight out of pIn. This seeks pIn forward by nBits. - // Returns an error if this buffer or the read buffer overflows. - bool WriteBitsFromBuffer( class bf_read *pIn, int nBits ); - - void WriteBitAngle( float fAngle, int numbits ); - void WriteBitCoord (const float f); - void WriteBitCoordMP( const float f, bool bIntegral, bool bLowPrecision ); - void WriteBitFloat(float val); - void WriteBitVec3Coord( const Vector& fa ); - void WriteBitNormal( float f ); - void WriteBitVec3Normal( const Vector& fa ); - void WriteBitAngles( const QAngle& fa ); - - -// Byte functions. -public: - - void WriteChar(int val); - void WriteByte(int val); - void WriteShort(int val); - void WriteWord(int val); - void WriteLong(long val); - void WriteLongLong(int64 val); - void WriteFloat(float val); - bool WriteBytes( const void *pBuf, int nBytes ); - - // Returns false if it overflows the buffer. - bool WriteString(const char *pStr); - - -// Status. -public: - - // How many bytes are filled in? - int GetNumBytesWritten(); - int GetNumBitsWritten(); - int GetMaxNumBits(); - int GetNumBitsLeft(); - int GetNumBytesLeft(); - unsigned char* GetData(); - - // Has the buffer overflowed? - bool CheckForOverflow(int nBits); - inline bool IsOverflowed() const {return m_bOverflow;} - - inline void SetOverflowFlag(); - - -public: - // The current buffer. - unsigned char* m_pData; - int m_nDataBytes; - int m_nDataBits; - - // Where we are in the buffer. - int m_iCurBit; - -private: - - // Errors? - bool m_bOverflow; - - bool m_bAssertOnOverflow; - const char *m_pDebugName; -}; - - -//----------------------------------------------------------------------------- -// Inlined methods -//----------------------------------------------------------------------------- - -// How many bytes are filled in? -inline int old_bf_write::GetNumBytesWritten() -{ - return BitByte(m_iCurBit); -} - -inline int old_bf_write::GetNumBitsWritten() -{ - return m_iCurBit; -} - -inline int old_bf_write::GetMaxNumBits() -{ - return m_nDataBits; -} - -inline int old_bf_write::GetNumBitsLeft() -{ - return m_nDataBits - m_iCurBit; -} - -inline int old_bf_write::GetNumBytesLeft() -{ - return GetNumBitsLeft() >> 3; -} - -inline unsigned char* old_bf_write::GetData() -{ - return m_pData; -} - -inline bool old_bf_write::CheckForOverflow(int nBits) -{ - if ( m_iCurBit + nBits > m_nDataBits ) - { - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); - } - - return m_bOverflow; -} - -inline void old_bf_write::SetOverflowFlag() -{ - if ( m_bAssertOnOverflow ) - { - Assert( false ); - } - - m_bOverflow = true; -} - -inline void old_bf_write::WriteOneBitNoCheck(int nValue) -{ - if(nValue) - m_pData[m_iCurBit >> 3] |= (1 << (m_iCurBit & 7)); - else - m_pData[m_iCurBit >> 3] &= ~(1 << (m_iCurBit & 7)); - - ++m_iCurBit; -} - -inline void old_bf_write::WriteOneBit(int nValue) -{ - if( !CheckForOverflow(1) ) - WriteOneBitNoCheck( nValue ); -} - - -inline void old_bf_write::WriteOneBitAt( int iBit, int nValue ) -{ - if( iBit+1 > m_nDataBits ) - { - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); - return; - } - - if( nValue ) - m_pData[iBit >> 3] |= (1 << (iBit & 7)); - else - m_pData[iBit >> 3] &= ~(1 << (iBit & 7)); -} - - -inline void old_bf_write::WriteUBitLong( unsigned int curData, int numbits, bool bCheckRange ) -{ -#ifdef _DEBUG - // Make sure it doesn't overflow. - if ( bCheckRange && numbits < 32 ) - { - if ( curData >= (unsigned long)(1 << numbits) ) - { - CallErrorHandler( BITBUFERROR_VALUE_OUT_OF_RANGE, GetDebugName() ); - } - } - Assert( numbits >= 0 && numbits <= 32 ); -#endif - - extern unsigned long g_BitWriteMasks[32][33]; - - // Bounds checking.. - if ((m_iCurBit+numbits) > m_nDataBits) - { - m_iCurBit = m_nDataBits; - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); - return; - } - - int nBitsLeft = numbits; - int iCurBit = m_iCurBit; - - // Mask in a dword. - unsigned int iDWord = iCurBit >> 5; - Assert( (iDWord*4 + sizeof(long)) <= (unsigned int)m_nDataBytes ); - - unsigned long iCurBitMasked = iCurBit & 31; - - unsigned long dword = LoadLittleDWord( (unsigned long*)m_pData, iDWord ); - - dword &= g_BitWriteMasks[iCurBitMasked][nBitsLeft]; - dword |= curData << iCurBitMasked; - - // write to stream (lsb to msb ) properly - StoreLittleDWord( (unsigned long*)m_pData, iDWord, dword ); - - // Did it span a dword? - int nBitsWritten = 32 - iCurBitMasked; - if ( nBitsWritten < nBitsLeft ) - { - nBitsLeft -= nBitsWritten; - curData >>= nBitsWritten; - - // read from stream (lsb to msb) properly - dword = LoadLittleDWord( (unsigned long*)m_pData, iDWord+1 ); - - dword &= g_BitWriteMasks[0][nBitsLeft]; - dword |= curData; - - // write to stream (lsb to msb) properly - StoreLittleDWord( (unsigned long*)m_pData, iDWord+1, dword ); - } - - m_iCurBit += numbits; -} - - -//----------------------------------------------------------------------------- -// This is useful if you just want a buffer to write into on the stack. -//----------------------------------------------------------------------------- - -template -class old_bf_write_static : public old_bf_write -{ -public: - inline old_bf_write_static() : old_bf_write(m_StaticData, SIZE) {} - - char m_StaticData[SIZE]; -}; - - - -//----------------------------------------------------------------------------- -// Used for unserialization -//----------------------------------------------------------------------------- - -class old_bf_read -{ -public: - old_bf_read(); - - // nMaxBits can be used as the number of bits in the buffer. - // It must be <= nBytes*8. If you leave it at -1, then it's set to nBytes * 8. - old_bf_read( const void *pData, int nBytes, int nBits = -1 ); - old_bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits = -1 ); - - // Start reading from the specified buffer. - // pData's start address must be dword-aligned. - // nMaxBits can be used as the number of bits in the buffer. - // It must be <= nBytes*8. If you leave it at -1, then it's set to nBytes * 8. - void StartReading( const void *pData, int nBytes, int iStartBit = 0, int nBits = -1 ); - - // Restart buffer reading. - void Reset(); - - // Enable or disable assertion on overflow. 99% of the time, it's a bug that we need to catch, - // but there may be the occasional buffer that is allowed to overflow gracefully. - void SetAssertOnOverflow( bool bAssert ); - - // This can be set to assign a name that gets output if the buffer overflows. - const char* GetDebugName(); - void SetDebugName( const char *pName ); - - void ExciseBits( int startbit, int bitstoremove ); - - -// Bit functions. -public: - - // Returns 0 or 1. - int ReadOneBit(); - - -protected: - - unsigned int CheckReadUBitLong(int numbits); // For debugging. - int ReadOneBitNoCheck(); // Faster version, doesn't check bounds and is inlined. - bool CheckForOverflow(int nBits); - - -public: - - // Get the base pointer. - const unsigned char* GetBasePointer() { return m_pData; } - - FORCEINLINE int TotalBytesAvailable( void ) const - { - return m_nDataBytes; - } - - // Read a list of bits in.. - void ReadBits(void *pOut, int nBits); - - float ReadBitAngle( int numbits ); - - unsigned int ReadUBitLong( int numbits ); - unsigned int PeekUBitLong( int numbits ); - int ReadSBitLong( int numbits ); - - // reads an unsigned integer with variable bit length - unsigned int ReadUBitVar(); - - // You can read signed or unsigned data with this, just cast to - // a signed int if necessary. - unsigned int ReadBitLong(int numbits, bool bSigned); - - float ReadBitCoord(); - float ReadBitCoordMP( bool bIntegral, bool bLowPrecision ); - float ReadBitFloat(); - float ReadBitNormal(); - void ReadBitVec3Coord( Vector& fa ); - void ReadBitVec3Normal( Vector& fa ); - void ReadBitAngles( QAngle& fa ); - - -// Byte functions (these still read data in bit-by-bit). -public: - - int ReadChar(); - int ReadByte(); - int ReadShort(); - int ReadWord(); - long ReadLong(); - int64 ReadLongLong(); - float ReadFloat(); - bool ReadBytes(void *pOut, int nBytes); - - // Returns false if bufLen isn't large enough to hold the - // string in the buffer. - // - // Always reads to the end of the string (so you can read the - // next piece of data waiting). - // - // If bLine is true, it stops when it reaches a '\n' or a null-terminator. - // - // pStr is always null-terminated (unless bufLen is 0). - // - // pOutNumChars is set to the number of characters left in pStr when the routine is - // complete (this will never exceed bufLen-1). - // - bool ReadString( char *pStr, int bufLen, bool bLine=false, int *pOutNumChars=NULL ); - - // Reads a string and allocates memory for it. If the string in the buffer - // is > 2048 bytes, then pOverflow is set to true (if it's not NULL). - char* ReadAndAllocateString( bool *pOverflow = 0 ); - -// Status. -public: - int GetNumBytesLeft(); - int GetNumBytesRead(); - int GetNumBitsLeft(); - int GetNumBitsRead() const; - - // Has the buffer overflowed? - inline bool IsOverflowed() const {return m_bOverflow;} - - inline bool Seek(int iBit); // Seek to a specific bit. - inline bool SeekRelative(int iBitDelta); // Seek to an offset from the current position. - - // Called when the buffer is overflowed. - inline void SetOverflowFlag(); - - -public: - - // The current buffer. - const unsigned char* m_pData; - int m_nDataBytes; - int m_nDataBits; - - // Where we are in the buffer. - int m_iCurBit; - - -private: - // used by varbit reads internally - inline int CountRunOfZeros(); - - // Errors? - bool m_bOverflow; - - // For debugging.. - bool m_bAssertOnOverflow; - - const char *m_pDebugName; -}; - -//----------------------------------------------------------------------------- -// Inlines. -//----------------------------------------------------------------------------- - -inline int old_bf_read::GetNumBytesRead() -{ - return BitByte(m_iCurBit); -} - -inline int old_bf_read::GetNumBitsLeft() -{ - return m_nDataBits - m_iCurBit; -} - -inline int old_bf_read::GetNumBytesLeft() -{ - return GetNumBitsLeft() >> 3; -} - -inline int old_bf_read::GetNumBitsRead() const -{ - return m_iCurBit; -} - -inline void old_bf_read::SetOverflowFlag() -{ - if ( m_bAssertOnOverflow ) - { - Assert( false ); - } - - m_bOverflow = true; -} - -inline bool old_bf_read::Seek(int iBit) -{ - if(iBit < 0 || iBit > m_nDataBits) - { - SetOverflowFlag(); - m_iCurBit = m_nDataBits; - return false; - } - else - { - m_iCurBit = iBit; - return true; - } -} - -// Seek to an offset from the current position. -inline bool old_bf_read::SeekRelative(int iBitDelta) -{ - return Seek(m_iCurBit+iBitDelta); -} - -inline bool old_bf_read::CheckForOverflow(int nBits) -{ - if( m_iCurBit + nBits > m_nDataBits ) - { - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); - } - - return m_bOverflow; -} - -inline int old_bf_read::ReadOneBitNoCheck() -{ - int value = m_pData[m_iCurBit >> 3] & (1 << (m_iCurBit & 7)); - ++m_iCurBit; - return !!value; -} - -inline int old_bf_read::ReadOneBit() -{ - return (!CheckForOverflow(1)) ? ReadOneBitNoCheck() : 0; -} - -inline float old_bf_read::ReadBitFloat() -{ - long val; - - Assert(sizeof(float) == sizeof(long)); - Assert(sizeof(float) == 4); - - if(CheckForOverflow(32)) - return 0.0f; - - int bit = m_iCurBit & 0x7; - int byte = m_iCurBit >> 3; - val = m_pData[byte] >> bit; - val |= ((int)m_pData[byte + 1]) << (8 - bit); - val |= ((int)m_pData[byte + 2]) << (16 - bit); - val |= ((int)m_pData[byte + 3]) << (24 - bit); - if (bit != 0) - val |= ((int)m_pData[byte + 4]) << (32 - bit); - m_iCurBit += 32; - return *((float*)&val); -} - - -inline unsigned int old_bf_read::ReadUBitLong( int numbits ) -{ - extern unsigned long g_ExtraMasks[32]; - - if ( (m_iCurBit+numbits) > m_nDataBits ) - { - m_iCurBit = m_nDataBits; - SetOverflowFlag(); - return 0; - } - - Assert( numbits > 0 && numbits <= 32 ); - - // Read the current dword. - int idword1 = m_iCurBit >> 5; - unsigned int dword1 = LoadLittleDWord( (unsigned long*)m_pData, idword1 ); - - dword1 >>= (m_iCurBit & 31); // Get the bits we're interested in. - - m_iCurBit += numbits; - unsigned int ret = dword1; - - // Does it span this dword? - if ( (m_iCurBit-1) >> 5 == idword1 ) - { - if (numbits != 32) - ret &= g_ExtraMasks[numbits]; - } - else - { - int nExtraBits = m_iCurBit & 31; - unsigned int dword2 = LoadLittleDWord( (unsigned long*)m_pData, idword1+1 ); - - dword2 &= g_ExtraMasks[nExtraBits]; - - // No need to mask since we hit the end of the dword. - // Shift the second dword's part into the high bits. - ret |= (dword2 << (numbits - nExtraBits)); - } - - return ret; -} - - -class CBitBuffer -{ -public: - char const * m_pDebugName; - bool m_bOverflow; - int m_nDataBits; - size_t m_nDataBytes; - - void SetDebugName( char const *pName ) - { - m_pDebugName = pName; - } - - CBitBuffer( void ) - { - m_bOverflow = false; - m_pDebugName = NULL; - m_nDataBits = -1; - m_nDataBytes = 0; - } - - FORCEINLINE void SetOverflowFlag( void ) - { - m_bOverflow = true; - } - - FORCEINLINE bool IsOverflowed( void ) const - { - return m_bOverflow; - } - - static const uint32 s_nMaskTable[33]; // 0 1 3 7 15 .. - -}; - - -class CBitWrite : public CBitBuffer -{ - uint32 m_nOutBufWord; - int m_nOutBitsAvail; - uint32 *m_pDataOut; - uint32 *m_pBufferEnd; - uint32 *m_pData; - bool m_bFlushed; - -public: - void StartWriting( void *pData, int nBytes, int iStartBit = 0, int nMaxBits = -1 ); - - - CBitWrite( void *pData, int nBytes, int nBits = -1 ) - { - m_bFlushed = false; - StartWriting( pData, nBytes, 0, nBits ); - } - - CBitWrite( const char *pDebugName, void *pData, int nBytes, int nBits = -1 ) - { - m_bFlushed = false; - SetDebugName( pDebugName ); - StartWriting( pData, nBytes, 0, nBits ); - } - - CBitWrite( void ) - { - m_bFlushed = false; - } - - ~CBitWrite( void ) - { - TempFlush(); - Assert( (! m_pData ) || m_bFlushed ); - } - FORCEINLINE int GetNumBitsLeft( void ) const - { - return m_nOutBitsAvail + ( 32 * ( m_pBufferEnd - m_pDataOut -1 ) ); - } - - FORCEINLINE void Reset( void ) - { - m_bOverflow = false; - m_nOutBitsAvail = 32; - m_pDataOut = m_pData; - m_nOutBufWord = 0; - - } - - FORCEINLINE void TempFlush( void ) - { - // someone wants to know how much data we have written, or the pointer to it, so we'd better make - // sure we write our data - if ( m_nOutBitsAvail != 32 ) - { - if ( m_pDataOut == m_pBufferEnd ) - { - SetOverflowFlag(); - } - else - { - *( m_pDataOut ) = (*m_pDataOut & ~s_nMaskTable[ 32 - m_nOutBitsAvail ] ) | m_nOutBufWord; - m_bFlushed = true; - } - } - } - - FORCEINLINE unsigned char *GetBasePointer() - { - TempFlush(); - return reinterpret_cast< unsigned char *>( m_pData ); - } - - FORCEINLINE unsigned char *GetData() - { - return GetBasePointer(); - } - - FORCEINLINE void Finish(); - FORCEINLINE void Flush(); - FORCEINLINE void FlushNoCheck(); - FORCEINLINE void WriteOneBit(int nValue); - FORCEINLINE void WriteOneBitNoCheck(int nValue); - FORCEINLINE void WriteUBitLong( unsigned int data, int numbits, bool bCheckRange=true ); - FORCEINLINE void WriteSBitLong( int data, int numbits ); - FORCEINLINE void WriteUBitVar( unsigned int data ); - FORCEINLINE void WriteBitFloat( float flValue ); - FORCEINLINE void WriteFloat( float flValue ); - bool WriteBits(const void *pInData, int nBits); - void WriteBytes( const void *pBuf, int nBytes ); - void SeekToBit( int nSeekPos ); - - FORCEINLINE int GetNumBitsWritten( void ) const - { - return ( 32 - m_nOutBitsAvail ) + ( 32 * ( m_pDataOut - m_pData ) ); - } - - FORCEINLINE int GetNumBytesWritten( void ) const - { - return ( GetNumBitsWritten() + 7 ) >> 3; - } - - - FORCEINLINE void WriteLong(long val) - { - WriteSBitLong( val, 32 ); - } - - - - FORCEINLINE void WriteChar( int val ) - { - WriteSBitLong(val, sizeof(char) << 3 ); - } - - FORCEINLINE void WriteByte( int val ) - { - WriteUBitLong(val, sizeof(unsigned char) << 3, false ); - } - - FORCEINLINE void WriteShort(int val) - { - WriteSBitLong(val, sizeof(short) << 3); - } - - FORCEINLINE void WriteWord(int val) - { - WriteUBitLong(val, sizeof(unsigned short) << 3); - } - - bool WriteString( const char *pStr ); - - void WriteLongLong( int64 val ); - - void WriteBitAngle( float fAngle, int numbits ); - void WriteBitCoord (const float f); - void WriteBitCoordMP( const float f, bool bIntegral, bool bLowPrecision ); - void WriteBitVec3Coord( const Vector& fa ); - void WriteBitNormal( float f ); - void WriteBitVec3Normal( const Vector& fa ); - void WriteBitAngles( const QAngle& fa ); - - // Copy the bits straight out of pIn. This seeks pIn forward by nBits. - // Returns an error if this buffer or the read buffer overflows. - bool WriteBitsFromBuffer( class bf_read *pIn, int nBits ); - -}; - -void CBitWrite::Finish( void ) -{ - if ( m_nOutBitsAvail != 32 ) - { - if ( m_pDataOut == m_pBufferEnd ) - { - SetOverflowFlag(); - } - *( m_pDataOut ) = m_nOutBufWord; - } -} - -void CBitWrite::FlushNoCheck( void ) -{ - *( m_pDataOut++ ) = m_nOutBufWord; - m_nOutBitsAvail = 32; - m_nOutBufWord = 0; // ugh - I need this because of 32 bit writes. a<<=32 is a nop - -} -void CBitWrite::Flush( void ) -{ - if ( m_pDataOut == m_pBufferEnd ) - { - SetOverflowFlag(); - } - else - *( m_pDataOut++ ) = m_nOutBufWord; - m_nOutBufWord = 0; // ugh - I need this because of 32 bit writes. a<<=32 is a nop - m_nOutBitsAvail = 32; - -} -void CBitWrite::WriteOneBitNoCheck( int nValue ) -{ - m_nOutBufWord |= ( nValue & 1 ) << ( 32 - m_nOutBitsAvail ); - if ( --m_nOutBitsAvail == 0 ) - { - FlushNoCheck(); - } -} - -void CBitWrite::WriteOneBit( int nValue ) -{ - m_nOutBufWord |= ( nValue & 1 ) << ( 32 - m_nOutBitsAvail ); - if ( --m_nOutBitsAvail == 0 ) - { - Flush(); - } -} - -FORCEINLINE void CBitWrite::WriteUBitLong( unsigned int nData, int nNumBits, bool bCheckRange ) -{ - -#ifdef _DEBUG - // Make sure it doesn't overflow. - if ( bCheckRange && nNumBits < 32 ) - { - Assert( nData <= (unsigned long)(1 << nNumBits ) ); - } - Assert( nNumBits >= 0 && nNumBits <= 32 ); -#endif - if ( nNumBits <= m_nOutBitsAvail ) - { - if ( bCheckRange ) - m_nOutBufWord |= ( nData ) << ( 32 - m_nOutBitsAvail ); - else - m_nOutBufWord |= ( nData & s_nMaskTable[ nNumBits] ) << ( 32 - m_nOutBitsAvail ); - m_nOutBitsAvail -= nNumBits; - if ( m_nOutBitsAvail == 0 ) - { - Flush(); - } - } - else - { - // split dwords case - int nOverflowBits = ( nNumBits - m_nOutBitsAvail ); - m_nOutBufWord |= ( nData & s_nMaskTable[m_nOutBitsAvail] ) << ( 32 - m_nOutBitsAvail ); - Flush(); - m_nOutBufWord = ( nData >> ( nNumBits - nOverflowBits ) ); - m_nOutBitsAvail = 32 - nOverflowBits; - } -} - -FORCEINLINE void CBitWrite::WriteSBitLong( int nData, int nNumBits ) -{ - WriteUBitLong( ( uint32 ) nData, nNumBits, false ); -} - -FORCEINLINE void CBitWrite::WriteUBitVar( unsigned int data ) -{ - if ( ( data &0xf ) == data ) - { - WriteUBitLong( 0, 2 ); - WriteUBitLong( data, 4 ); - } - else - { - if ( ( data & 0xff ) == data ) - { - WriteUBitLong( 1, 2 ); - WriteUBitLong( data, 8 ); - } - else - { - if ( ( data & 0xfff ) == data ) - { - WriteUBitLong( 2, 2 ); - WriteUBitLong( data, 12 ); - } - else - { - WriteUBitLong( 0x3, 2 ); - WriteUBitLong( data, 32 ); - } - } - } -} - -FORCEINLINE void CBitWrite::WriteBitFloat( float flValue ) -{ - WriteUBitLong( *((uint32 *) &flValue ), 32 ); -} - -FORCEINLINE void CBitWrite::WriteFloat( float flValue ) -{ - // Pre-swap the float, since WriteBits writes raw data - LittleFloat( &flValue, &flValue ); - WriteUBitLong( *((uint32 *) &flValue ), 32 ); -} - -class CBitRead : public CBitBuffer -{ - uint32 m_nInBufWord; - int m_nBitsAvail; - uint32 const *m_pDataIn; - uint32 const *m_pBufferEnd; - uint32 const *m_pData; - -public: - CBitRead( const void *pData, int nBytes, int nBits = -1 ) - { - StartReading( pData, nBytes, 0, nBits ); - } - - CBitRead( const char *pDebugName, const void *pData, int nBytes, int nBits = -1 ) - { - SetDebugName( pDebugName ); - StartReading( pData, nBytes, 0, nBits ); - } - - CBitRead( void ) : CBitBuffer() - { - } - - FORCEINLINE int Tell( void ) const - { - return GetNumBitsRead(); - } - - FORCEINLINE size_t TotalBytesAvailable( void ) const - { - return m_nDataBytes; - } - - FORCEINLINE int GetNumBitsLeft() const - { - return m_nDataBits - Tell(); - } - - FORCEINLINE int GetNumBytesLeft() const - { - return GetNumBitsLeft() >> 3; - } - - bool Seek( int nPosition ); - - FORCEINLINE bool SeekRelative( int nOffset ) - { - return Seek( GetNumBitsRead() + nOffset ); - } - - FORCEINLINE unsigned char const * GetBasePointer() - { - return reinterpret_cast< unsigned char const *>( m_pData ); - } - - void StartReading( const void *pData, int nBytes, int iStartBit = 0, int nBits = -1 ); - - FORCEINLINE int CBitRead::GetNumBitsRead( void ) const; - - FORCEINLINE void GrabNextDWord( bool bOverFlowImmediately = false ); - FORCEINLINE void FetchNext( void ); - FORCEINLINE unsigned int ReadUBitLong( int numbits ); - FORCEINLINE int ReadSBitLong( int numbits ); - FORCEINLINE unsigned int ReadUBitVar( void ); - FORCEINLINE unsigned int PeekUBitLong( int numbits ); - FORCEINLINE float ReadBitFloat( void ); - float ReadBitCoord(); - float ReadBitCoordMP( bool bIntegral, bool bLowPrecision ); - float ReadBitNormal(); - void ReadBitVec3Coord( Vector& fa ); - void ReadBitVec3Normal( Vector& fa ); - void ReadBitAngles( QAngle& fa ); - bool ReadBytes(void *pOut, int nBytes); - float ReadBitAngle( int numbits ); - - // Returns 0 or 1. - FORCEINLINE int ReadOneBit( void ); - FORCEINLINE int ReadLong( void ); - FORCEINLINE int ReadChar( void ); - FORCEINLINE int ReadByte( void ); - FORCEINLINE int ReadShort( void ); - FORCEINLINE int ReadWord( void ); - FORCEINLINE float ReadFloat( void ); - void ReadBits(void *pOut, int nBits); - - // Returns false if bufLen isn't large enough to hold the - // string in the buffer. - // - // Always reads to the end of the string (so you can read the - // next piece of data waiting). - // - // If bLine is true, it stops when it reaches a '\n' or a null-terminator. - // - // pStr is always null-terminated (unless bufLen is 0). - // - // pOutN m_pBufferEnd ) - { - SetOverflowFlag(); - m_nInBufWord = 0; - } - else - { - Assert( reinterpret_cast(m_pDataIn) + 3 < reinterpret_cast(m_pBufferEnd)); - m_nInBufWord = LittleDWord( *( m_pDataIn++ ) ); - } -} - -FORCEINLINE void CBitRead::FetchNext( void ) -{ - m_nBitsAvail = 32; - GrabNextDWord( false ); -} - -int CBitRead::ReadOneBit( void ) -{ - int nRet = m_nInBufWord & 1; - if ( --m_nBitsAvail == 0 ) - { - FetchNext(); - } - else - m_nInBufWord >>= 1; - return nRet; -} - - -unsigned int CBitRead::ReadUBitLong( int numbits ) -{ - if ( m_nBitsAvail >= numbits ) - { - unsigned int nRet = m_nInBufWord & s_nMaskTable[ numbits ]; - m_nBitsAvail -= numbits; - if ( m_nBitsAvail ) - { - m_nInBufWord >>= numbits; - } - else - { - FetchNext(); - } - return nRet; - } - else - { - // need to merge words - unsigned int nRet = m_nInBufWord; - numbits -= m_nBitsAvail; - GrabNextDWord( true ); - if ( m_bOverflow ) - return 0; - nRet |= ( ( m_nInBufWord & s_nMaskTable[numbits] ) << m_nBitsAvail ); - m_nBitsAvail = 32 - numbits; - m_nInBufWord >>= numbits; - return nRet; - } -} - -FORCEINLINE unsigned int CBitRead::PeekUBitLong( int numbits ) -{ - int nSaveBA = m_nBitsAvail; - int nSaveW = m_nInBufWord; - uint32 const *pSaveP = m_pDataIn; - unsigned int nRet = ReadUBitLong( numbits ); - m_nBitsAvail = nSaveBA; - m_nInBufWord = nSaveW; - m_pDataIn = pSaveP; - return nRet; -} - -FORCEINLINE int CBitRead::ReadSBitLong( int numbits ) -{ - int nRet = ReadUBitLong( numbits ); - // sign extend - return ( nRet << ( 32 - numbits ) ) >> ( 32 - numbits ); -} - -FORCEINLINE int CBitRead::ReadLong( void ) -{ - return ( int ) ReadUBitLong( sizeof(long) << 3 ); -} - -FORCEINLINE float CBitRead::ReadFloat( void ) -{ - uint32 nUval = ReadUBitLong( sizeof(long) << 3 ); - return * ( ( float * ) &nUval ); -} - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4715) // disable warning on not all cases - // returning a value. throwing default: - // in measurably reduces perf in bit - // packing benchmark -#endif -FORCEINLINE unsigned int CBitRead::ReadUBitVar( void ) -{ - switch( ReadUBitLong( 2 ) ) - { - case 0: - return ReadUBitLong( 4 ); - - case 1: - return ReadUBitLong( 8 ); - - case 2: - return ReadUBitLong( 12 ); - - case 3: - return ReadUBitLong( 32 ); - } -} -#ifdef _WIN32 -#pragma warning(pop) -#endif - -FORCEINLINE float CBitRead::ReadBitFloat( void ) -{ - uint32 nvalue = ReadUBitLong( 32 ); - return *( ( float * ) &nvalue ); -} - -int CBitRead::ReadChar( void ) -{ - return ReadSBitLong(sizeof(char) << 3); -} - -int CBitRead::ReadByte( void ) -{ - return ReadUBitLong(sizeof(unsigned char) << 3); -} - -int CBitRead::ReadShort( void ) -{ - return ReadSBitLong(sizeof(short) << 3); -} - -int CBitRead::ReadWord( void ) -{ - return ReadUBitLong(sizeof(unsigned short) << 3); -} - -#define WRAP_READ( bc ) \ -class bf_read : public bc \ -{ \ -public: \ - FORCEINLINE bf_read( void ) : bc( ) \ - { \ - } \ - \ - FORCEINLINE bf_read( const void *pData, int nBytes, int nBits = -1 ) : bc( pData, nBytes, nBits ) \ - { \ - } \ - \ - FORCEINLINE bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits = -1 ) : bc( pDebugName, pData, nBytes, nBits ) \ - { \ - } \ -}; - -#define WRAP_WRITE( bc ) \ -class bf_write : public bc \ -{ \ -public: \ - FORCEINLINE bf_write(void) : bc() \ - { \ - } \ - FORCEINLINE bf_write( void *pData, int nBytes, int nMaxBits = -1 ) : bc( pData, nBytes, nMaxBits ) \ - { \ - } \ - \ - FORCEINLINE bf_write( const char *pDebugName, void *pData, int nBytes, int nMaxBits = -1 ) : bc( pDebugName, pData, nBytes, nMaxBits ) \ - { \ - } \ -}; -#if 0 - - -#define DELEGATE0( t, m ) t m() \ -{ \ - Check(); \ - t nOld = old1.m(); \ - t nNew = new1.m(); \ - Assert( nOld == nNew ); \ - Check(); \ - return nOld; \ -} -#define DELEGATE1( t, m, t1 ) t m( t1 x) \ -{ \ - Check(); \ - t nOld = old1.m( x); \ - t nNew = new1.m( x ); \ - Assert( nOld == nNew ); \ - Check(); \ - return nOld; \ -} - -#define DELEGATE0I( m ) DELEGATE0( int, m ) -#define DELEGATE0LL( m ) DELEGATE0( int64, m ) - -class bf_read -{ - old_bf_read old1; - CBitRead new1; - - void Check( void ) const - { - int n=new1.GetNumBitsRead(); - int o=old1.GetNumBitsRead(); - Assert( n == o ); - Assert( old1.IsOverflowed() == new1.IsOverflowed() ); - } - -public: - FORCEINLINE bf_read( void ) : old1(), new1() - { - } - - FORCEINLINE bf_read( const void *pData, int nBytes, int nBits = -1 ) : old1( pData, nBytes, nBits ),new1( pData, nBytes, nBits ) - { - } - - FORCEINLINE bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits = -1 ) : old1( pDebugName, pData, nBytes, nBits ), new1( pDebugName, pData, nBytes, nBits ) - { - } - - FORCEINLINE bool IsOverflowed( void ) const - { - bool bOld = old1.IsOverflowed(); - bool bNew = new1.IsOverflowed(); - Assert( bOld == bNew ); - Check(); - return bOld; - - } - - void ReadBits(void *pOut, int nBits) - { - old1.ReadBits( pOut, nBits ); - void *mem=stackalloc( 1+ ( nBits / 8 ) ); - new1.ReadBits( mem, nBits ); - Assert( memcmp( mem, pOut, nBits / 8 ) == 0 ); - } - - bool ReadBytes(void *pOut, int nBytes) - { - ReadBits(pOut, nBytes << 3); - return ! IsOverflowed(); - } - - - unsigned int ReadUBitLong( int numbits ) - { - unsigned int nOld = old1.ReadUBitLong( numbits ); - unsigned int nNew = new1.ReadUBitLong( numbits ); - Assert( nOld == nNew ); - Check(); - return nOld; - } - - unsigned const char* GetBasePointer() - { - Assert( old1.GetBasePointer() == new1.GetBasePointer() ); - Check(); - return old1.GetBasePointer(); - } - void SetDebugName( const char *pDebugName ) - { - old1.SetDebugName( pDebugName ); - new1.SetDebugName( pDebugName ); - Check(); - } - - void StartReading( const void *pData, int nBytes, int iStartBit = 0, int nBits = -1 ) - { - old1.StartReading( pData, nBytes, iStartBit, nBits ); - new1.StartReading( pData, nBytes, iStartBit, nBits ); - Check(); - } - - void SetAssertOnOverflow( bool bAssert ) - { - old1.SetAssertOnOverflow( bAssert ); -// new1.SetAssertOnOverflow( bAssert ); - Check(); - } - - DELEGATE0I( ReadOneBit ); - DELEGATE0I( ReadByte ); - DELEGATE0I( ReadWord ); - DELEGATE0I( ReadLong ); - DELEGATE0I( GetNumBytesLeft ); - DELEGATE0I( ReadShort ); - DELEGATE1( int, PeekUBitLong, int ); - DELEGATE0I( ReadChar ); - DELEGATE0I( GetNumBitsRead ); - DELEGATE0LL( ReadLongLong ); - DELEGATE0( float, ReadFloat); - DELEGATE0( unsigned int, ReadUBitVar ); - DELEGATE0( float, ReadBitCoord); - DELEGATE2( float, ReadBitCoordMP, bool, bool ); - DELEGATE0( float, ReadBitFloat); - DELEGATE0( float, ReadBitNormal); - DELEGATE1( bool,Seek, int ); - DELEGATE1( float, ReadBitAngle, int ); - DELEGATE1( bool,SeekRelative,int); - DELEGATE0I( GetNumBitsLeft ); - DELEGATE0I( TotalBytesAvailable ); - - void SetOverflowFlag() - { - old1.SetOverflowFlag(); - new1.SetOverflowFlag(); - Check(); - } - - bool ReadString( char *pStr, int bufLen, bool bLine=false, int *pOutNumChars=NULL ) - { - Check(); - int oldn, newn; - bool bOld = old1.ReadString( pStr, bufLen, bLine, &oldn ); - bool bNew = new1.ReadString( pStr, bufLen, bLine, &newn ); - Assert( bOld == bNew ); - Assert( oldn == newn ); - if ( pOutNumChars ) - *pOutNumChars = oldn; - Check(); - return bOld; - } - - void ReadBitVec3Coord( Vector& fa ) - { - Check(); - old1.ReadBitVec3Coord( fa ); - Vector test; - new1.ReadBitVec3Coord( test ); - Assert( VectorsAreEqual( fa, test )); - Check(); - } - void ReadBitVec3Normal( Vector& fa ) - { - Check(); - old1.ReadBitVec3Coord( fa ); - Vector test; - new1.ReadBitVec3Coord( test ); - Assert( VectorsAreEqual( fa, test )); - Check(); - } - - char* ReadAndAllocateString( bool *pOverflow = NULL ) - { - Check(); - bool bold, bnew; - char *pold = old1.ReadAndAllocateString( &bold ); - char *pnew = new1.ReadAndAllocateString( &bnew ); - Assert( bold == bnew ); - Assert(strcmp( pold, pnew ) == 0 ); - delete[] pnew; - Check(); - if ( pOverflow ) - *pOverflow = bold; - return pold; - - } - - DELEGATE1( int, ReadSBitLong, int ); - -}; -#endif - - -#ifdef _LINUX -WRAP_READ( old_bf_read ); -#else -WRAP_READ( CBitRead ); -#endif -WRAP_WRITE( old_bf_write ); - - -#endif - - - diff --git a/Resources/NetHook/tier1/byteswap.cpp b/Resources/NetHook/tier1/byteswap.cpp deleted file mode 100644 index e43f5da5..00000000 --- a/Resources/NetHook/tier1/byteswap.cpp +++ /dev/null @@ -1,90 +0,0 @@ -//========= Copyright © 1996-2006, Valve LLC, All rights reserved. ============ -// -// Purpose: Low level byte swapping routines. -// -// $NoKeywords: $ -//============================================================================= - -#include "byteswap.h" - -//----------------------------------------------------------------------------- -// Copy a single field from the input buffer to the output buffer, swapping the bytes if necessary -//----------------------------------------------------------------------------- -void CByteswap::SwapFieldToTargetEndian( void* pOutputBuffer, void *pData, typedescription_t *pField ) -{ - switch ( pField->fieldType ) - { - case FIELD_CHARACTER: - SwapBufferToTargetEndian( (char*)pOutputBuffer, (char*)pData, pField->fieldSize ); - break; - - case FIELD_BOOLEAN: - SwapBufferToTargetEndian( (bool*)pOutputBuffer, (bool*)pData, pField->fieldSize ); - break; - - case FIELD_SHORT: - SwapBufferToTargetEndian( (short*)pOutputBuffer, (short*)pData, pField->fieldSize ); - break; - - case FIELD_FLOAT: - SwapBufferToTargetEndian( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize ); - break; - - case FIELD_INTEGER: - SwapBufferToTargetEndian( (int*)pOutputBuffer, (int*)pData, pField->fieldSize ); - break; - - case FIELD_VECTOR: - SwapBufferToTargetEndian( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 3 ); - break; - - case FIELD_VECTOR2D: - SwapBufferToTargetEndian( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 2 ); - break; - - case FIELD_QUATERNION: - SwapBufferToTargetEndian( (uint*)pOutputBuffer, (uint*)pData, pField->fieldSize * 4 ); - break; - - case FIELD_EMBEDDED: - { - typedescription_t *pEmbed = pField->td->dataDesc; - for ( int i = 0; i < pField->fieldSize; ++i ) - { - SwapFieldsToTargetEndian( (byte*)pOutputBuffer + pEmbed->fieldOffset[ TD_OFFSET_NORMAL ], - (byte*)pData + pEmbed->fieldOffset[ TD_OFFSET_NORMAL ], - pField->td ); - - pOutputBuffer = (byte*)pOutputBuffer + pField->fieldSizeInBytes; - pData = (byte*)pData + pField->fieldSizeInBytes; - } - } - break; - - default: - assert(0); - } -} - -//----------------------------------------------------------------------------- -// Write a block of fields. Works a bit like the saverestore code. -//----------------------------------------------------------------------------- -void CByteswap::SwapFieldsToTargetEndian( void *pOutputBuffer, void *pBaseData, datamap_t *pDataMap ) -{ - // deal with base class first - if ( pDataMap->baseMap ) - { - SwapFieldsToTargetEndian( pOutputBuffer, pBaseData, pDataMap->baseMap ); - } - - typedescription_t *pFields = pDataMap->dataDesc; - int fieldCount = pDataMap->dataNumFields; - for ( int i = 0; i < fieldCount; ++i ) - { - typedescription_t *pField = &pFields[i]; - SwapFieldToTargetEndian( (BYTE*)pOutputBuffer + pField->fieldOffset[ TD_OFFSET_NORMAL ], - (BYTE*)pBaseData + pField->fieldOffset[ TD_OFFSET_NORMAL ], - pField ); - } -} - diff --git a/Resources/NetHook/tier1/byteswap.h b/Resources/NetHook/tier1/byteswap.h deleted file mode 100644 index 253ae4fd..00000000 --- a/Resources/NetHook/tier1/byteswap.h +++ /dev/null @@ -1,249 +0,0 @@ -//========= Copyright © 1996-2006, Valve LLC, All rights reserved. ============ -// -// Purpose: Low level byte swapping routines. -// -// $NoKeywords: $ -//============================================================================= -#ifndef BYTESWAP_H -#define BYTESWAP_H -#if defined(_WIN32) -#pragma once -#endif - -#include "datamap.h" // Needed for typedescription_t. Note datamap.h is tier1 as well. - -class CByteswap -{ -public: - CByteswap() - { - // Default behavior sets the target endian to match the machine native endian (no swap). - SetTargetBigEndian( IsMachineBigEndian() ); - } - - //----------------------------------------------------------------------------- - // Write a single field. - //----------------------------------------------------------------------------- - void SwapFieldToTargetEndian( void* pOutputBuffer, void *pData, typedescription_t *pField ); - - //----------------------------------------------------------------------------- - // Write a block of fields. Works a bit like the saverestore code. - //----------------------------------------------------------------------------- - void SwapFieldsToTargetEndian( void *pOutputBuffer, void *pBaseData, datamap_t *pDataMap ); - - // Swaps fields for the templated type to the output buffer. - template inline void SwapFieldsToTargetEndian( T* pOutputBuffer, void *pBaseData, unsigned int objectCount = 1 ) - { - for ( unsigned int i = 0; i < objectCount; ++i, ++pOutputBuffer ) - { - SwapFieldsToTargetEndian( (void*)pOutputBuffer, pBaseData, &T::m_DataMap ); - pBaseData = (byte*)pBaseData + sizeof(T); - } - } - - // Swaps fields for the templated type in place. - template inline void SwapFieldsToTargetEndian( T* pOutputBuffer, unsigned int objectCount = 1 ) - { - SwapFieldsToTargetEndian( pOutputBuffer, (void*)pOutputBuffer, objectCount ); - } - - //----------------------------------------------------------------------------- - // True if the current machine is detected as big endian. - // (Endienness is effectively detected at compile time when optimizations are - // enabled) - //----------------------------------------------------------------------------- - static bool IsMachineBigEndian() - { - short nIsBigEndian = 1; - - // if we are big endian, the first byte will be a 0, if little endian, it will be a one. - return (bool)(0 == *(char *)&nIsBigEndian ); - } - - //----------------------------------------------------------------------------- - // Sets the target byte ordering we are swapping to or from. - // - // Braindead Endian Reference: - // x86 is LITTLE Endian - // PowerPC is BIG Endian - //----------------------------------------------------------------------------- - inline void SetTargetBigEndian( bool bigEndian ) - { - m_bBigEndian = bigEndian; - m_bSwapBytes = IsMachineBigEndian() != bigEndian; - } - - // Changes target endian - inline void FlipTargetEndian( void ) - { - m_bSwapBytes = !m_bSwapBytes; - m_bBigEndian = !m_bBigEndian; - } - - // Forces byte swapping state, regardless of endianess - inline void ActivateByteSwapping( bool bActivate ) - { - SetTargetBigEndian( IsMachineBigEndian() != bActivate ); - } - - //----------------------------------------------------------------------------- - // Returns true if the target machine is the same as this one in endianness. - // - // Used to determine when a byteswap needs to take place. - //----------------------------------------------------------------------------- - inline bool IsSwappingBytes( void ) // Are bytes being swapped? - { - return m_bSwapBytes; - } - - inline bool IsTargetBigEndian( void ) // What is the current target endian? - { - return m_bBigEndian; - } - - //----------------------------------------------------------------------------- - // IsByteSwapped() - // - // When supplied with a chunk of input data and a constant or magic number - // (in native format) determines the endienness of the current machine in - // relation to the given input data. - // - // Returns: - // 1 if input is the same as nativeConstant. - // 0 if input is byteswapped relative to nativeConstant. - // -1 if input is not the same as nativeConstant and not byteswapped either. - // - // ( This is useful for detecting byteswapping in magic numbers in structure - // headers for example. ) - //----------------------------------------------------------------------------- - template inline int SourceIsNativeEndian( T input, T nativeConstant ) - { - // If it's the same, it isn't byteswapped: - if( input == nativeConstant ) - return 1; - - int output; - LowLevelByteSwap( &output, &input ); - if( output == nativeConstant ) - return 0; - - assert( 0 ); // if we get here, input is neither a swapped nor unswapped version of nativeConstant. - return -1; - } - - //----------------------------------------------------------------------------- - // Swaps an input buffer full of type T into the given output buffer. - // - // Swaps [count] items from the inputBuffer to the outputBuffer. - // If inputBuffer is omitted or NULL, then it is assumed to be the same as - // outputBuffer - effectively swapping the contents of the buffer in place. - //----------------------------------------------------------------------------- - template inline void SwapBuffer( T* outputBuffer, T* inputBuffer = NULL, int count = 1 ) - { - assert( count >= 0 ); - assert( outputBuffer ); - - // Fail gracefully in release: - if( count <=0 || !outputBuffer ) - return; - - // Optimization for the case when we are swapping in place. - if( inputBuffer == NULL ) - { - inputBuffer = outputBuffer; - } - - // Swap everything in the buffer: - for( int i = 0; i < count; i++ ) - { - LowLevelByteSwap( &outputBuffer[i], &inputBuffer[i] ); - } - } - - //----------------------------------------------------------------------------- - // Swaps an input buffer full of type T into the given output buffer. - // - // Swaps [count] items from the inputBuffer to the outputBuffer. - // If inputBuffer is omitted or NULL, then it is assumed to be the same as - // outputBuffer - effectively swapping the contents of the buffer in place. - //----------------------------------------------------------------------------- - template inline void SwapBufferToTargetEndian( T* outputBuffer, T* inputBuffer = NULL, int count = 1 ) - { - assert( count >= 0 ); - assert( outputBuffer ); - - // Fail gracefully in release: - if( count <=0 || !outputBuffer ) - return; - - // Optimization for the case when we are swapping in place. - if( inputBuffer == NULL ) - { - inputBuffer = outputBuffer; - } - - // Are we already the correct endienness? ( or are we swapping 1 byte items? ) - if( !m_bSwapBytes || ( sizeof(T) == 1 ) ) - { - // If we were just going to swap in place then return. - if( !inputBuffer ) - return; - - // Otherwise copy the inputBuffer to the outputBuffer: - memcpy( outputBuffer, inputBuffer, count * sizeof( T ) ); - return; - - } - - // Swap everything in the buffer: - for( int i = 0; i < count; i++ ) - { - LowLevelByteSwap( &outputBuffer[i], &inputBuffer[i] ); - } - } - -private: - //----------------------------------------------------------------------------- - // The lowest level byte swapping workhorse of doom. output always contains the - // swapped version of input. ( Doesn't compare machine to target endianness ) - //----------------------------------------------------------------------------- - template static void LowLevelByteSwap( T *output, T *input ) - { - T temp = *output; -#if defined( _X360 ) - // Intrinsics need the source type to be fixed-point - DWORD* word = (DWORD*)input; - switch( sizeof(T) ) - { - case 8: - { - __storewordbytereverse( *word, 0, &temp ); - __storewordbytereverse( *(word+1), 4, &temp ); - } - break; - - case 4: - __storewordbytereverse( *word, 0, &temp ); - break; - - case 2: - __storeshortbytereverse( *input, 0, &temp ); - break; - - default: - Assert( "Invalid size in CByteswap::LowLevelByteSwap" && 0 ); - } -#else - for( int i = 0; i < sizeof(T); i++ ) - { - ((unsigned char* )&temp)[i] = ((unsigned char*)input)[sizeof(T)-(i+1)]; - } -#endif - Q_memcpy( output, &temp, sizeof(T) ); - } - - unsigned int m_bSwapBytes : 1; - unsigned int m_bBigEndian : 1; -}; - -#endif /* !BYTESWAP_H */ diff --git a/Resources/NetHook/tier1/callqueue.h b/Resources/NetHook/tier1/callqueue.h deleted file mode 100644 index 4a385b28..00000000 --- a/Resources/NetHook/tier1/callqueue.h +++ /dev/null @@ -1,203 +0,0 @@ -//========== Copyright © 2006, Valve Corporation, All rights reserved. ======== -// -// Purpose: -// -//============================================================================= - -#ifndef CALLQUEUE_H -#define CALLQUEUE_H - -#include "tier0/tslist.h" -#include "functors.h" - -#if defined( _WIN32 ) -#pragma once -#endif - -//----------------------------------------------------- -// Avert thy eyes! Imagine rather: -// -// void QueueCall( , [args1, [arg2,]...] -// void QueueCall( , , [args1, [arg2,]...] -// void QueueRefCall( , <, [args1, [arg2,]...] -//----------------------------------------------------- - -#define DEFINE_CALLQUEUE_NONMEMBER_QUEUE_CALL(N) \ - template \ - void QueueCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - QueueFunctorInternal( CreateFunctor( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \ - } - -//------------------------------------- - -#define DEFINE_CALLQUEUE_MEMBER_QUEUE_CALL(N) \ - template \ - void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - QueueFunctorInternal( CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \ - } - -//------------------------------------- - -#define DEFINE_CALLQUEUE_CONST_MEMBER_QUEUE_CALL(N) \ - template \ - void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - QueueFunctorInternal( CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \ - } - -//------------------------------------- - -#define DEFINE_CALLQUEUE_REF_COUNTING_MEMBER_QUEUE_CALL(N) \ - template \ - void QueueRefCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - QueueFunctorInternal( CreateRefCountingFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \ - } - -//------------------------------------- - -#define DEFINE_CALLQUEUE_REF_COUNTING_CONST_MEMBER_QUEUE_CALL(N) \ - template \ - void QueueRefCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - QueueFunctorInternal( CreateRefCountingFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \ - \ - } - -#define FUNC_GENERATE_QUEUE_METHODS() \ - FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_NONMEMBER_QUEUE_CALL ); \ - FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_MEMBER_QUEUE_CALL ); \ - FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_CONST_MEMBER_QUEUE_CALL );\ - FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_REF_COUNTING_MEMBER_QUEUE_CALL ); \ - FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_REF_COUNTING_CONST_MEMBER_QUEUE_CALL ) - -//----------------------------------------------------- - -template > -class CCallQueueT -{ -public: - CCallQueueT() - : m_bNoQueue( false ) - { -#ifdef _DEBUG - m_nCurSerialNumber = 0; - m_nBreakSerialNumber = (unsigned)-1; -#endif - } - - void DisableQueue( bool bDisable ) - { - if ( m_bNoQueue == bDisable ) - { - return; - } - if ( !m_bNoQueue ) - CallQueued(); - - m_bNoQueue = bDisable; - } - - bool IsDisabled() const - { - return m_bNoQueue; - } - - int Count() - { - return m_queue.Count(); - } - - void CallQueued() - { - if ( !m_queue.Count() ) - { - return; - } - - m_queue.PushItem( NULL ); - - CFunctor *pFunctor; - - while ( m_queue.PopItem( &pFunctor ) && pFunctor != NULL ) - { -#ifdef _DEBUG - if ( pFunctor->m_nUserID == m_nBreakSerialNumber) - { - m_nBreakSerialNumber = (unsigned)-1; - } -#endif - (*pFunctor)(); - pFunctor->Release(); - } - - } - - void QueueFunctor( CFunctor *pFunctor ) - { - Assert( pFunctor ); - QueueFunctorInternal( RetAddRef( pFunctor ) ); - } - - void Flush() - { - m_queue.PushItem( NULL ); - - CFunctor *pFunctor; - - while ( m_queue.PopItem( &pFunctor ) && pFunctor != NULL ) - { - pFunctor->Release(); - } - } - - FUNC_GENERATE_QUEUE_METHODS(); - -private: - void QueueFunctorInternal( CFunctor *pFunctor ) - { - if ( !m_bNoQueue ) - { -#ifdef _DEBUG - pFunctor->m_nUserID = m_nCurSerialNumber++; -#endif - m_queue.PushItem( pFunctor ); - } - else - { - (*pFunctor)(); - pFunctor->Release(); - } - } - - QUEUE_TYPE m_queue; - bool m_bNoQueue; - unsigned m_nCurSerialNumber; - unsigned m_nBreakSerialNumber; -}; - -class CCallQueue : public CCallQueueT<> -{ -}; - -//----------------------------------------------------- -// Optional interface that can be bound to concrete CCallQueue -//----------------------------------------------------- - -class ICallQueue -{ -public: - void QueueFunctor( CFunctor *pFunctor ) - { - QueueFunctorInternal( RetAddRef( pFunctor ) ); - } - - FUNC_GENERATE_QUEUE_METHODS(); - -private: - virtual void QueueFunctorInternal( CFunctor *pFunctor ) = 0; -}; - -#endif // CALLQUEUE_H diff --git a/Resources/NetHook/tier1/characterset.cpp b/Resources/NetHook/tier1/characterset.cpp deleted file mode 100644 index 0fa3fced..00000000 --- a/Resources/NetHook/tier1/characterset.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include -#include "characterset.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Purpose: builds a simple lookup table of a group of important characters -// Input : *pParseGroup - pointer to the buffer for the group -// *pGroupString - null terminated list of characters to flag -//----------------------------------------------------------------------------- -void CharacterSetBuild( characterset_t *pSetBuffer, const char *pszSetString ) -{ - int i = 0; - - // Test our pointers - if ( !pSetBuffer || !pszSetString ) - return; - - memset( pSetBuffer->set, 0, sizeof(pSetBuffer->set) ); - - while ( pszSetString[i] ) - { - pSetBuffer->set[ pszSetString[i] ] = 1; - i++; - } - -} diff --git a/Resources/NetHook/tier1/characterset.h b/Resources/NetHook/tier1/characterset.h deleted file mode 100644 index 53734a27..00000000 --- a/Resources/NetHook/tier1/characterset.h +++ /dev/null @@ -1,43 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: Shared code for parsing / searching for characters in a string -// using lookup tables -// -// $Workfile: $ -// $Date: $ -// $NoKeywords: $ -//===========================================================================// - -#ifndef CHARACTERSET_H -#define CHARACTERSET_H - -#ifdef _WIN32 -#pragma once -#endif - - -struct characterset_t -{ - char set[256]; -}; - - -// This is essentially a strpbrk() using a precalculated lookup table -//----------------------------------------------------------------------------- -// Purpose: builds a simple lookup table of a group of important characters -// Input : *pSetBuffer - pointer to the buffer for the group -// *pSetString - list of characters to flag -//----------------------------------------------------------------------------- -extern void CharacterSetBuild( characterset_t *pSetBuffer, const char *pSetString ); - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pSetBuffer - pre-build group buffer -// character - character to lookup -// Output : int - 1 if the character was in the set -//----------------------------------------------------------------------------- -#define IN_CHARACTERSET( SetBuffer, character ) ((SetBuffer).set[(character)]) - - -#endif // CHARACTERSET_H diff --git a/Resources/NetHook/tier1/checksum_crc.cpp b/Resources/NetHook/tier1/checksum_crc.cpp deleted file mode 100644 index 3e0f20d4..00000000 --- a/Resources/NetHook/tier1/checksum_crc.cpp +++ /dev/null @@ -1,180 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic CRC functions -// -//=============================================================================// - -#include "basetypes.h" -#include "commonmacros.h" -#include "checksum_crc.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define CRC32_INIT_VALUE 0xFFFFFFFFUL -#define CRC32_XOR_VALUE 0xFFFFFFFFUL - -#define NUM_BYTES 256 -static const CRC32_t pulCRCTable[NUM_BYTES] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -void CRC32_Init(CRC32_t *pulCRC) -{ - *pulCRC = CRC32_INIT_VALUE; -} - -void CRC32_Final(CRC32_t *pulCRC) -{ - *pulCRC ^= CRC32_XOR_VALUE; -} - -CRC32_t CRC32_GetTableEntry( unsigned int slot ) -{ - return pulCRCTable[(unsigned char)slot]; -} - -void CRC32_ProcessBuffer(CRC32_t *pulCRC, const void *pBuffer, int nBuffer) -{ - CRC32_t ulCrc = *pulCRC; - unsigned char *pb = (unsigned char *)pBuffer; - unsigned int nFront; - int nMain; - -JustAfew: - - switch (nBuffer) - { - case 7: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 6: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 5: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 4: - ulCrc ^= LittleLong( *(CRC32_t *)pb ); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - *pulCRC = ulCrc; - return; - - case 3: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 2: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 1: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - - case 0: - *pulCRC = ulCrc; - return; - } - - // We may need to do some alignment work up front, and at the end, so that - // the main loop is aligned and only has to worry about 8 byte at a time. - // - // The low-order two bits of pb and nBuffer in total control the - // upfront work. - // - nFront = ((unsigned int)pb) & 3; - nBuffer -= nFront; - switch (nFront) - { - case 3: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - case 2: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - case 1: - ulCrc = pulCRCTable[*pb++ ^ (unsigned char)ulCrc] ^ (ulCrc >> 8); - } - - nMain = nBuffer >> 3; - while (nMain--) - { - ulCrc ^= LittleLong( *(CRC32_t *)pb ); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc ^= LittleLong( *(CRC32_t *)(pb + 4) ); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - ulCrc = pulCRCTable[(unsigned char)ulCrc] ^ (ulCrc >> 8); - pb += 8; - } - - nBuffer &= 7; - goto JustAfew; -} diff --git a/Resources/NetHook/tier1/checksum_crc.h b/Resources/NetHook/tier1/checksum_crc.h deleted file mode 100644 index 3f6e9ec1..00000000 --- a/Resources/NetHook/tier1/checksum_crc.h +++ /dev/null @@ -1,31 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic CRC functions -// -// $NoKeywords: $ -//=============================================================================// -#ifndef CHECKSUM_CRC_H -#define CHECKSUM_CRC_H -#ifdef _WIN32 -#pragma once -#endif - -typedef unsigned long CRC32_t; - -void CRC32_Init( CRC32_t *pulCRC ); -void CRC32_ProcessBuffer( CRC32_t *pulCRC, const void *p, int len ); -void CRC32_Final( CRC32_t *pulCRC ); -CRC32_t CRC32_GetTableEntry( unsigned int slot ); - -inline CRC32_t CRC32_ProcessSingleBuffer( const void *p, int len ) -{ - CRC32_t crc; - - CRC32_Init( &crc ); - CRC32_ProcessBuffer( &crc, p, len ); - CRC32_Final( &crc ); - - return crc; -} - -#endif // CHECKSUM_CRC_H diff --git a/Resources/NetHook/tier1/checksum_md5.cpp b/Resources/NetHook/tier1/checksum_md5.cpp deleted file mode 100644 index d41f1de2..00000000 --- a/Resources/NetHook/tier1/checksum_md5.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#include "basetypes.h" -#include "commonmacros.h" -#include "checksum_md5.h" -#include -#include -#include "tier1/strtools.h" -#include "tier0/dbg.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// The four core functions - F1 is optimized somewhat -// #define F1(x, y, z) (x & y | ~x & z) -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -// This is the central step in the MD5 algorithm. -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -//----------------------------------------------------------------------------- -// Purpose: The core of the MD5 algorithm, this alters an existing MD5 hash to -// reflect the addition of 16 longwords of new data. MD5Update blocks -// the data and converts bytes into longwords for this routine. -// Input : buf[4] - -// in[16] - -// Output : static void -//----------------------------------------------------------------------------- -static void MD5Transform(unsigned int buf[4], unsigned int const in[16]) -{ - register unsigned int a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -//----------------------------------------------------------------------------- -// Purpose: Start MD5 accumulation. Set bit count to 0 and buffer to mysterious initialization constants. - -// Input : *ctx - -//----------------------------------------------------------------------------- -void MD5Init(MD5Context_t *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Update context to reflect the concatenation of another buffer full of bytes. -// Input : *ctx - -// *buf - -// len - -//----------------------------------------------------------------------------- -void MD5Update(MD5Context_t *ctx, unsigned char const *buf, unsigned int len) -{ - unsigned int t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((unsigned int) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) - { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) - { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - //byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (unsigned int *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) - { - memcpy(ctx->in, buf, 64); - //byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (unsigned int *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - memcpy(ctx->in, buf, len); -} - -//----------------------------------------------------------------------------- -// Purpose: Final wrapup - pad to 64-byte boundary with the bit pattern -// 1 0* (64-bit count of bits processed, MSB-first) -// Input : digest[MD5_DIGEST_LENGTH] - -// *ctx - -//----------------------------------------------------------------------------- -void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5Context_t *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) - { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - //byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (unsigned int *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } - else - { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - //byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((unsigned int *) ctx->in)[14] = ctx->bits[0]; - ((unsigned int *) ctx->in)[15] = ctx->bits[1]; - - MD5Transform(ctx->buf, (unsigned int *) ctx->in); - //byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, MD5_DIGEST_LENGTH); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *hash - -// hashlen - -// Output : char -//----------------------------------------------------------------------------- -char *MD5_Print( unsigned char *hash, int hashlen ) -{ - static char szReturn[64]; - - Assert( hashlen <= 32 ); - - Q_binarytohex( hash, hashlen, szReturn, sizeof( szReturn ) ); - return szReturn; -} - -//----------------------------------------------------------------------------- -// Purpose: generate pseudo random number from a seed number -// Input : seed number -// Output : pseudo random number -//----------------------------------------------------------------------------- -unsigned int MD5_PseudoRandom(unsigned int nSeed) -{ - MD5Context_t ctx; - unsigned char digest[MD5_DIGEST_LENGTH]; // The MD5 Hash - - memset( &ctx, 0, sizeof( ctx ) ); - - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char*)&nSeed, sizeof(nSeed) ); - MD5Final(digest, &ctx); - - return *(unsigned int*)(digest+6); // use 4 middle bytes for random value -} diff --git a/Resources/NetHook/tier1/checksum_md5.h b/Resources/NetHook/tier1/checksum_md5.h deleted file mode 100644 index 134d2b52..00000000 --- a/Resources/NetHook/tier1/checksum_md5.h +++ /dev/null @@ -1,33 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic MD5 hashing algo -// -//=============================================================================// - -#ifndef CHECKSUM_MD5_H -#define CHECKSUM_MD5_H - -#ifdef _WIN32 -#pragma once -#endif - -// 16 bytes == 128 bit digest -#define MD5_DIGEST_LENGTH 16 - -// MD5 Hash -typedef struct -{ - unsigned int buf[4]; - unsigned int bits[2]; - unsigned char in[64]; -} MD5Context_t; - -void MD5Init( MD5Context_t *context ); -void MD5Update( MD5Context_t *context, unsigned char const *buf, unsigned int len ); -void MD5Final( unsigned char digest[ MD5_DIGEST_LENGTH ], MD5Context_t *context ); - -char *MD5_Print(unsigned char *digest, int hashlen ); - -unsigned int MD5_PseudoRandom(unsigned int nSeed); - -#endif // CHECKSUM_MD5_H diff --git a/Resources/NetHook/tier1/commandbuffer.cpp b/Resources/NetHook/tier1/commandbuffer.cpp deleted file mode 100644 index a8f600a7..00000000 --- a/Resources/NetHook/tier1/commandbuffer.cpp +++ /dev/null @@ -1,636 +0,0 @@ -//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// $NoKeywords: $ -//===========================================================================// - -#include "tier1/CommandBuffer.h" -#include "tier1/utlbuffer.h" -#include "tier1/strtools.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define MAX_ALIAS_NAME 32 -#define MAX_COMMAND_LENGTH 1024 - -struct cmdalias_t -{ - cmdalias_t *next; - char name[ MAX_ALIAS_NAME ]; - char *value; -}; - - -//----------------------------------------------------------------------------- -// Constructor, destructor -//----------------------------------------------------------------------------- -CCommandBuffer::CCommandBuffer( ) : m_Commands( 32, 32 ) -{ - m_hNextCommand = m_Commands.InvalidIndex(); - m_nWaitDelayTicks = 1; - m_nCurrentTick = 0; - m_nLastTickToProcess = -1; - m_nArgSBufferSize = 0; - m_bIsProcessingCommands = false; - m_nMaxArgSBufferLength = ARGS_BUFFER_LENGTH; -} - -CCommandBuffer::~CCommandBuffer() -{ -} - - -//----------------------------------------------------------------------------- -// Indicates how long to delay when encoutering a 'wait' command -//----------------------------------------------------------------------------- -void CCommandBuffer::SetWaitDelayTime( int nTickDelay ) -{ - Assert( nTickDelay >= 0 ); - m_nWaitDelayTicks = nTickDelay; -} - - -//----------------------------------------------------------------------------- -// Specifies a max limit of the args buffer. For unittesting. Size == 0 means use default -//----------------------------------------------------------------------------- -void CCommandBuffer::LimitArgumentBufferSize( int nSize ) -{ - if ( nSize > ARGS_BUFFER_LENGTH ) - { - nSize = ARGS_BUFFER_LENGTH; - } - - m_nMaxArgSBufferLength = ( nSize == 0 ) ? ARGS_BUFFER_LENGTH : nSize; -} - - -//----------------------------------------------------------------------------- -// Parses argv0 out of the buffer -//----------------------------------------------------------------------------- -bool CCommandBuffer::ParseArgV0( CUtlBuffer &buf, char *pArgV0, int nMaxLen, const char **pArgS ) -{ - pArgV0[0] = 0; - *pArgS = NULL; - - if ( !buf.IsValid() ) - return false; - - int nSize = buf.ParseToken( CCommand::DefaultBreakSet(), pArgV0, nMaxLen ); - if ( ( nSize <= 0 ) || ( nMaxLen == nSize ) ) - return false; - - int nArgSLen = buf.TellMaxPut() - buf.TellGet(); - *pArgS = (nArgSLen > 0) ? (const char*)buf.PeekGet() : NULL; - return true; -} - - -//----------------------------------------------------------------------------- -// Insert a command into the command queue -//----------------------------------------------------------------------------- -void CCommandBuffer::InsertCommandAtAppropriateTime( int hCommand ) -{ - int i; - Command_t &command = m_Commands[hCommand]; - for ( i = m_Commands.Head(); i != m_Commands.InvalidIndex(); i = m_Commands.Next(i) ) - { - if ( m_Commands[i].m_nTick > command.m_nTick ) - break; - } - m_Commands.LinkBefore( i, hCommand ); -} - - -//----------------------------------------------------------------------------- -// Insert a command into the command queue at the appropriate time -//----------------------------------------------------------------------------- -void CCommandBuffer::InsertImmediateCommand( int hCommand ) -{ - m_Commands.LinkBefore( m_hNextCommand, hCommand ); -} - - -//----------------------------------------------------------------------------- -// Insert a command into the command queue -//----------------------------------------------------------------------------- -bool CCommandBuffer::InsertCommand( const char *pArgS, int nCommandSize, int nTick ) -{ - if ( nCommandSize >= CCommand::MaxCommandLength() ) - { - Warning( "WARNING: Command too long... ignoring!\n%s\n", pArgS ); - return false; - } - - // Add one for null termination - if ( m_nArgSBufferSize + nCommandSize + 1 > m_nMaxArgSBufferLength ) - { - Compact(); - if ( m_nArgSBufferSize + nCommandSize + 1 > m_nMaxArgSBufferLength ) - return false; - } - - memcpy( &m_pArgSBuffer[m_nArgSBufferSize], pArgS, nCommandSize ); - m_pArgSBuffer[m_nArgSBufferSize + nCommandSize] = 0; - ++nCommandSize; - - int hCommand = m_Commands.Alloc(); - Command_t &command = m_Commands[hCommand]; - command.m_nTick = nTick; - command.m_nFirstArgS = m_nArgSBufferSize; - command.m_nBufferSize = nCommandSize; - - m_nArgSBufferSize += nCommandSize; - - if ( !m_bIsProcessingCommands || ( nTick > m_nCurrentTick ) ) - { - InsertCommandAtAppropriateTime( hCommand ); - } - else - { - InsertImmediateCommand( hCommand ); - } - return true; -} - - -//----------------------------------------------------------------------------- -// Returns the length of the next command -//----------------------------------------------------------------------------- -void CCommandBuffer::GetNextCommandLength( const char *pText, int nMaxLen, int *pCommandLength, int *pNextCommandOffset ) -{ - int nCommandLength = 0; - int nNextCommandOffset; - bool bIsQuoted = false; - bool bIsCommented = false; - for ( nNextCommandOffset=0; nNextCommandOffset < nMaxLen; ++nNextCommandOffset, nCommandLength += bIsCommented ? 0 : 1 ) - { - char c = pText[nNextCommandOffset]; - if ( !bIsCommented ) - { - if ( c == '"' ) - { - bIsQuoted = !bIsQuoted; - continue; - } - - // don't break if inside a C++ style comment - if ( !bIsQuoted && c == '/' ) - { - bIsCommented = ( nNextCommandOffset < nMaxLen-1 ) && pText[nNextCommandOffset+1] == '/'; - if ( bIsCommented ) - { - ++nNextCommandOffset; - continue; - } - } - - // don't break if inside a quoted string - if ( !bIsQuoted && c == ';' ) - break; - } - - // FIXME: This is legacy behavior; should we not break if a \n is inside a quoted string? - if ( c == '\n' ) - break; - } - - *pCommandLength = nCommandLength; - *pNextCommandOffset = nNextCommandOffset; -} - - -//----------------------------------------------------------------------------- -// Add text to command buffer, return false if it couldn't owing to overflow -//----------------------------------------------------------------------------- -bool CCommandBuffer::AddText( const char *pText, int nTickDelay ) -{ - Assert( nTickDelay >= 0 ); - - int nLen = Q_strlen( pText ); - int nTick = m_nCurrentTick + nTickDelay; - - // Parse the text into distinct commands - const char *pCurrentCommand = pText; - int nOffsetToNextCommand; - for( ; nLen > 0; nLen -= nOffsetToNextCommand+1, pCurrentCommand += nOffsetToNextCommand+1 ) - { - // find a \n or ; line break - int nCommandLength; - GetNextCommandLength( pCurrentCommand, nLen, &nCommandLength, &nOffsetToNextCommand ); - if ( nCommandLength <= 0 ) - continue; - - const char *pArgS; - char *pArgV0 = (char*)_alloca( nCommandLength+1 ); - CUtlBuffer bufParse( pCurrentCommand, nCommandLength, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY ); - ParseArgV0( bufParse, pArgV0, nCommandLength+1, &pArgS ); - if ( pArgV0[0] == 0 ) - continue; - - // Deal with the special 'wait' command - if ( !Q_stricmp( pArgV0, "wait" ) ) - { - int nDelay = pArgS ? atoi( pArgS ) : m_nWaitDelayTicks; - nTick += nDelay; - continue; - } - - if ( !InsertCommand( pCurrentCommand, nCommandLength, nTick ) ) - return false; - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Are we in the middle of processing commands? -//----------------------------------------------------------------------------- -bool CCommandBuffer::IsProcessingCommands() -{ - return m_bIsProcessingCommands; -} - - -//----------------------------------------------------------------------------- -// Delays all queued commands to execute at a later time -//----------------------------------------------------------------------------- -void CCommandBuffer::DelayAllQueuedCommands( int nDelay ) -{ - if ( nDelay <= 0 ) - return; - - for ( int i = m_Commands.Head(); i != m_Commands.InvalidIndex(); i = m_Commands.Next(i) ) - { - m_Commands[i].m_nTick += nDelay; - } -} - - -//----------------------------------------------------------------------------- -// Call this to begin iterating over all commands up to flCurrentTime -//----------------------------------------------------------------------------- -void CCommandBuffer::BeginProcessingCommands( int nDeltaTicks ) -{ - if ( nDeltaTicks == 0 ) - return; - - Assert( !m_bIsProcessingCommands ); - m_bIsProcessingCommands = true; - m_nLastTickToProcess = m_nCurrentTick + nDeltaTicks - 1; - - // Necessary to insert commands while commands are being processed - m_hNextCommand = m_Commands.Head(); -} - - -//----------------------------------------------------------------------------- -// Returns the next command -//----------------------------------------------------------------------------- -bool CCommandBuffer::DequeueNextCommand( ) -{ - m_CurrentCommand.Reset(); - - Assert( m_bIsProcessingCommands ); - if ( m_Commands.Count() == 0 ) - return false; - - int nHead = m_Commands.Head(); - Command_t &command = m_Commands[ nHead ]; - if ( command.m_nTick > m_nLastTickToProcess ) - return false; - - m_nCurrentTick = command.m_nTick; - - // Copy the current command into a temp buffer - // NOTE: This is here to avoid the pointers returned by DequeueNextCommand - // to become invalid by calling AddText. Is there a way we can avoid the memcpy? - if ( command.m_nBufferSize > 0 ) - { - m_CurrentCommand.Tokenize( &m_pArgSBuffer[command.m_nFirstArgS] ); - } - - m_Commands.Remove( nHead ); - - // Necessary to insert commands while commands are being processed - m_hNextCommand = m_Commands.Head(); - -// Msg("Dequeue : "); -// for ( int i = 0; i < nArgc; ++i ) -// { -// Msg("%s ", m_pCurrentArgv[i] ); -// } -// Msg("\n"); - return true; -} - - -//----------------------------------------------------------------------------- -// Returns the next command -//----------------------------------------------------------------------------- -int CCommandBuffer::DequeueNextCommand( const char **& ppArgv ) -{ - DequeueNextCommand(); - ppArgv = ArgV(); - return ArgC(); -} - - -//----------------------------------------------------------------------------- -// Compacts the command buffer -//----------------------------------------------------------------------------- -void CCommandBuffer::Compact() -{ - // Compress argvbuffer + argv - // NOTE: I'm using this choice instead of calling malloc + free - // per command to allocate arguments because I expect to post a - // bunch of commands but not have many delayed commands; - // avoiding the allocation cost seems more important that the memcpy - // cost here since I expect to not have much to copy. - m_nArgSBufferSize = 0; - - char pTempBuffer[ ARGS_BUFFER_LENGTH ]; - for ( int i = m_Commands.Head(); i != m_Commands.InvalidIndex(); i = m_Commands.Next(i) ) - { - Command_t &command = m_Commands[ i ]; - - memcpy( &pTempBuffer[m_nArgSBufferSize], &m_pArgSBuffer[command.m_nFirstArgS], command.m_nBufferSize ); - command.m_nFirstArgS = m_nArgSBufferSize; - m_nArgSBufferSize += command.m_nBufferSize; - } - - // NOTE: We could also store 2 buffers in the command buffer and switch - // between the two to avoid the 2nd memcpy; but again I'm guessing the memory - // tradeoff isn't worth it - memcpy( m_pArgSBuffer, pTempBuffer, m_nArgSBufferSize ); -} - - -//----------------------------------------------------------------------------- -// Call this to finish iterating over all commands -//----------------------------------------------------------------------------- -void CCommandBuffer::EndProcessingCommands() -{ - Assert( m_bIsProcessingCommands ); - m_bIsProcessingCommands = false; - m_nCurrentTick = m_nLastTickToProcess + 1; - m_hNextCommand = m_Commands.InvalidIndex(); - - // Extract commands that are before the end time - // NOTE: This is a bug for this to - int i = m_Commands.Head(); - if ( i == m_Commands.InvalidIndex() ) - { - m_nArgSBufferSize = 0; - return; - } - - while ( i != m_Commands.InvalidIndex() ) - { - if ( m_Commands[i].m_nTick >= m_nCurrentTick ) - break; - - AssertMsgOnce( false, "CCommandBuffer::EndProcessingCommands() called before all appropriate commands were dequeued.\n" ); - int nNext = i; - Msg( "Warning: Skipping command %s\n", m_pArgSBuffer[ m_Commands[i].m_nFirstArgS ] ); - m_Commands.Remove( i ); - i = nNext; - } - - Compact(); -} - - -//----------------------------------------------------------------------------- -// Returns a handle to the next command to process -//----------------------------------------------------------------------------- -CommandHandle_t CCommandBuffer::GetNextCommandHandle() -{ - Assert( m_bIsProcessingCommands ); - return m_Commands.Head(); -} - - -#if 0 -/* -=============== -Cmd_Alias_f - -Creates a new command that executes a command string (possibly ; seperated) -=============== -*/ -void Cmd_Alias_f (void) -{ - cmdalias_t *a; - char cmd[MAX_COMMAND_LENGTH]; - int i, c; - char *s; - - if (Cmd_Argc() == 1) - { - Con_Printf ("Current alias commands:\n"); - for (a = cmd_alias ; a ; a=a->next) - Con_Printf ("%s : %s\n", a->name, a->value); - return; - } - - s = Cmd_Argv(1); - if (strlen(s) >= MAX_ALIAS_NAME) - { - Con_Printf ("Alias name is too long\n"); - return; - } - -// copy the rest of the command line - cmd[0] = 0; // start out with a null string - c = Cmd_Argc(); - for (i=2 ; i< c ; i++) - { - Q_strncat(cmd, Cmd_Argv(i), sizeof( cmd ), COPY_ALL_CHARACTERS); - if (i != c) - { - Q_strncat (cmd, " ", sizeof( cmd ), COPY_ALL_CHARACTERS ); - } - } - Q_strncat (cmd, "\n", sizeof( cmd ), COPY_ALL_CHARACTERS); - - // if the alias already exists, reuse it - for (a = cmd_alias ; a ; a=a->next) - { - if (!strcmp(s, a->name)) - { - if ( !strcmp( a->value, cmd ) ) // Re-alias the same thing - return; - - delete[] a->value; - break; - } - } - - if (!a) - { - a = (cmdalias_t *)new cmdalias_t; - a->next = cmd_alias; - cmd_alias = a; - } - Q_strncpy (a->name, s, sizeof( a->name ) ); - - a->value = COM_StringCopy(cmd); -} - - - -/* -============================================================================= - - COMMAND EXECUTION - -============================================================================= -*/ - -#define MAX_ARGS 80 - -static int cmd_argc; -static char *cmd_argv[MAX_ARGS]; -static char *cmd_null_string = ""; -static const char *cmd_args = NULL; - -cmd_source_t cmd_source; - -//----------------------------------------------------------------------------- -// Purpose: -// Output : void Cmd_Init -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void Cmd_Shutdown( void ) -{ - // TODO, cleanup - while ( cmd_alias ) - { - cmdalias_t *next = cmd_alias->next; - delete cmd_alias->value; // created by StringCopy() - delete cmd_alias; - cmd_alias = next; - } -} - - - -/* -============ -Cmd_ExecuteString - -A complete command line has been parsed, so try to execute it -FIXME: lookupnoadd the token to speed search? -============ -*/ -const ConCommandBase *Cmd_ExecuteString (const char *text, cmd_source_t src) -{ - cmdalias_t *a; - - cmd_source = src; - Cmd_TokenizeString (text); - -// execute the command line - if (!Cmd_Argc()) - return NULL; // no tokens - -// check alias - for (a=cmd_alias ; a ; a=a->next) - { - if (!Q_strcasecmp (cmd_argv[0], a->name)) - { - Cbuf_InsertText (a->value); - return NULL; - } - } - -// check ConCommands - ConCommandBase const *pCommand = ConCommandBase::FindCommand( cmd_argv[ 0 ] ); - if ( pCommand && pCommand->IsCommand() ) - { - bool isServerCommand = ( pCommand->IsBitSet( FCVAR_GAMEDLL ) && - // Typed at console - cmd_source == src_command && - // Not HLDS - !sv.IsDedicated() ); - - // Hook to allow game .dll to figure out who type the message on a listen server - if ( serverGameClients ) - { - // We're actually the server, so set it up locally - if ( sv.IsActive() ) - { - g_pServerPluginHandler->SetCommandClient( -1 ); - -#ifndef SWDS - // Special processing for listen server player - if ( isServerCommand ) - { - g_pServerPluginHandler->SetCommandClient( cl.m_nPlayerSlot ); - } -#endif - } - // We're not the server, but we've been a listen server (game .dll loaded) - // forward this command tot he server instead of running it locally if we're still - // connected - // Otherwise, things like "say" won't work unless you quit and restart - else if ( isServerCommand ) - { - if ( cl.IsConnected() ) - { - Cmd_ForwardToServer(); - return NULL; - } - else - { - // It's a server command, but we're not connected to a server. Don't try to execute it. - return NULL; - } - } - } - - // Allow cheat commands in singleplayer, debug, or multiplayer with sv_cheats on -#ifndef _DEBUG - if ( pCommand->IsBitSet( FCVAR_CHEAT ) ) - { - if ( !Host_IsSinglePlayerGame() && sv_cheats.GetInt() == 0 ) - { - Msg( "Can't use cheat command %s in multiplayer, unless the server has sv_cheats set to 1.\n", pCommand->GetName() ); - return NULL; - } - } -#endif - - (( ConCommand * )pCommand )->Dispatch(); - return pCommand; - } - - // check cvars - if ( cv->IsCommand() ) - { - return pCommand; - } - - // forward the command line to the server, so the entity DLL can parse it - if ( cmd_source == src_command ) - { - if ( cl.IsConnected() ) - { - Cmd_ForwardToServer(); - return NULL; - } - } - - Msg("Unknown command \"%s\"\n", Cmd_Argv(0)); - - return NULL; -} -#endif diff --git a/Resources/NetHook/tier1/convar.cpp b/Resources/NetHook/tier1/convar.cpp deleted file mode 100644 index d246eb58..00000000 --- a/Resources/NetHook/tier1/convar.cpp +++ /dev/null @@ -1,1241 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// - -#include -#include -#include -#include "basetypes.h" -#include "tier1/convar.h" -#include "tier1/strtools.h" -#include "tier1/characterset.h" -#include "tier1/utlbuffer.h" -#include "tier1/tier1.h" -#include "tier1/convar_serverbounded.h" -#include "icvar.h" -#include "tier0/dbg.h" -#include "Color.h" -#if defined( _X360 ) -#include "xbox/xbox_console.h" -#endif -#include "tier0/memdbgon.h" - - -// Comment this out when we release. -//#define ALLOW_DEVELOPMENT_CVARS - - - -//----------------------------------------------------------------------------- -// Statically constructed list of ConCommandBases, -// used for registering them with the ICVar interface -//----------------------------------------------------------------------------- -ConCommandBase *ConCommandBase::s_pConCommandBases = NULL; -IConCommandBaseAccessor *ConCommandBase::s_pAccessor = NULL; -static int s_nCVarFlag = 0; -static int s_nDLLIdentifier = -1; // A unique identifier indicating which DLL this convar came from -static bool s_bRegistered = false; - -class CDefaultAccessor : public IConCommandBaseAccessor -{ -public: - virtual bool RegisterConCommandBase( ConCommandBase *pVar ) - { - // Link to engine's list instead - g_pCVar->RegisterConCommand( pVar ); - return true; - } -}; - -static CDefaultAccessor s_DefaultAccessor; - -//----------------------------------------------------------------------------- -// Called by the framework to register ConCommandBases with the ICVar -//----------------------------------------------------------------------------- -void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor ) -{ - if ( !g_pCVar || s_bRegistered ) - return; - - Assert( s_nDLLIdentifier < 0 ); - s_bRegistered = true; - s_nCVarFlag = nCVarFlag; - s_nDLLIdentifier = g_pCVar->AllocateDLLIdentifier(); - - ConCommandBase *pCur, *pNext; - - ConCommandBase::s_pAccessor = pAccessor ? pAccessor : &s_DefaultAccessor; - pCur = ConCommandBase::s_pConCommandBases; - while ( pCur ) - { - pNext = pCur->m_pNext; - pCur->AddFlags( s_nCVarFlag ); - pCur->Init(); - pCur = pNext; - } - - ConCommandBase::s_pConCommandBases = NULL; -} - -void ConVar_Unregister( ) -{ - if ( !g_pCVar || !s_bRegistered ) - return; - - Assert( s_nDLLIdentifier >= 0 ); - g_pCVar->UnregisterConCommands( s_nDLLIdentifier ); - s_nDLLIdentifier = -1; - s_bRegistered = false; -} - - -//----------------------------------------------------------------------------- -// Purpose: Default constructor -//----------------------------------------------------------------------------- -ConCommandBase::ConCommandBase( void ) -{ - m_bRegistered = false; - m_pszName = NULL; - m_pszHelpString = NULL; - - m_nFlags = 0; - m_pNext = NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: The base console invoked command/cvar interface -// Input : *pName - name of variable/command -// *pHelpString - help text -// flags - flags -//----------------------------------------------------------------------------- -ConCommandBase::ConCommandBase( const char *pName, const char *pHelpString /*=0*/, int flags /*= 0*/ ) -{ - Create( pName, pHelpString, flags ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -ConCommandBase::~ConCommandBase( void ) -{ -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsCommand( void ) const -{ -// Assert( 0 ); This can't assert. . causes a recursive assert in Sys_Printf, etc. - return true; -} - - -//----------------------------------------------------------------------------- -// Returns the DLL identifier -//----------------------------------------------------------------------------- -CVarDLLIdentifier_t ConCommandBase::GetDLLIdentifier() const -{ - return s_nDLLIdentifier; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pName - -// callback - -// *pHelpString - -// flags - -//----------------------------------------------------------------------------- -void ConCommandBase::Create( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ ) -{ - static char *empty_string = ""; - - m_bRegistered = false; - - // Name should be static data - Assert( pName ); - m_pszName = pName; - m_pszHelpString = pHelpString ? pHelpString : empty_string; - - m_nFlags = flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - m_nFlags &= ~FCVAR_DEVELOPMENTONLY; -#endif - - if ( !( m_nFlags & FCVAR_UNREGISTERED ) ) - { - m_pNext = s_pConCommandBases; - s_pConCommandBases = this; - } - else - { - // It's unregistered - m_pNext = NULL; - } - - // If s_pAccessor is already set (this ConVar is not a global variable), - // register it. - if ( s_pAccessor ) - { - Init(); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Used internally by OneTimeInit to initialize. -//----------------------------------------------------------------------------- -void ConCommandBase::Init() -{ - if ( s_pAccessor ) - { - s_pAccessor->RegisterConCommandBase( this ); - } -} - -void ConCommandBase::Shutdown() -{ - if ( g_pCVar ) - { - g_pCVar->UnregisterConCommand( this ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Return name of the command/var -// Output : const char -//----------------------------------------------------------------------------- -const char *ConCommandBase::GetName( void ) const -{ - return m_pszName; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flag - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsFlagSet( int flag ) const -{ - return ( flag & m_nFlags ) ? true : false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flags - -//----------------------------------------------------------------------------- -void ConCommandBase::AddFlags( int flags ) -{ - m_nFlags |= flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - m_nFlags &= ~FCVAR_DEVELOPMENTONLY; -#endif -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const ConCommandBase -//----------------------------------------------------------------------------- -const ConCommandBase *ConCommandBase::GetNext( void ) const -{ - return m_pNext; -} - -ConCommandBase *ConCommandBase::GetNext( void ) -{ - return m_pNext; -} - - -//----------------------------------------------------------------------------- -// Purpose: Copies string using local new/delete operators -// Input : *from - -// Output : char -//----------------------------------------------------------------------------- -char *ConCommandBase::CopyString( const char *from ) -{ - int len; - char *to; - - len = strlen( from ); - if ( len <= 0 ) - { - to = new char[1]; - to[0] = 0; - } - else - { - to = new char[len+1]; - Q_strncpy( to, from, len+1 ); - } - return to; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const char -//----------------------------------------------------------------------------- -const char *ConCommandBase::GetHelpText( void ) const -{ - return m_pszHelpString; -} - -//----------------------------------------------------------------------------- -// Purpose: Has this cvar been registered -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConCommandBase::IsRegistered( void ) const -{ - return m_bRegistered; -} - - -//----------------------------------------------------------------------------- -// -// Con Commands start here -// -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// Global methods -//----------------------------------------------------------------------------- -static characterset_t s_BreakSet; -static bool s_bBuiltBreakSet = false; - - -//----------------------------------------------------------------------------- -// Tokenizer class -//----------------------------------------------------------------------------- -CCommand::CCommand() -{ - if ( !s_bBuiltBreakSet ) - { - s_bBuiltBreakSet = true; - CharacterSetBuild( &s_BreakSet, "{}()':" ); - } - - Reset(); -} - -CCommand::CCommand( int nArgC, const char **ppArgV ) -{ - Assert( nArgC > 0 ); - - if ( !s_bBuiltBreakSet ) - { - s_bBuiltBreakSet = true; - CharacterSetBuild( &s_BreakSet, "{}()':" ); - } - - Reset(); - - char *pBuf = m_pArgvBuffer; - char *pSBuf = m_pArgSBuffer; - m_nArgc = nArgC; - for ( int i = 0; i < nArgC; ++i ) - { - m_ppArgv[i] = pBuf; - int nLen = Q_strlen( ppArgV[i] ); - memcpy( pBuf, ppArgV[i], nLen+1 ); - if ( i == 0 ) - { - m_nArgv0Size = nLen; - } - pBuf += nLen+1; - - bool bContainsSpace = strchr( ppArgV[i], ' ' ) != NULL; - if ( bContainsSpace ) - { - *pSBuf++ = '\"'; - } - memcpy( pSBuf, ppArgV[i], nLen ); - pSBuf += nLen; - if ( bContainsSpace ) - { - *pSBuf++ = '\"'; - } - - if ( i != nArgC - 1 ) - { - *pSBuf++ = ' '; - } - } -} - -void CCommand::Reset() -{ - m_nArgc = 0; - m_nArgv0Size = 0; - m_pArgSBuffer[0] = 0; -} - -characterset_t* CCommand::DefaultBreakSet() -{ - return &s_BreakSet; -} - -bool CCommand::Tokenize( const char *pCommand, characterset_t *pBreakSet ) -{ - Reset(); - if ( !pCommand ) - return false; - - // Use default break set - if ( !pBreakSet ) - { - pBreakSet = &s_BreakSet; - } - - // Copy the current command into a temp buffer - // NOTE: This is here to avoid the pointers returned by DequeueNextCommand - // to become invalid by calling AddText. Is there a way we can avoid the memcpy? - int nLen = Q_strlen( pCommand ); - if ( nLen >= COMMAND_MAX_LENGTH - 1 ) - { - Warning( "CCommand::Tokenize: Encountered command which overflows the tokenizer buffer.. Skipping!\n" ); - return false; - } - - memcpy( m_pArgSBuffer, pCommand, nLen + 1 ); - - // Parse the current command into the current command buffer - CUtlBuffer bufParse( m_pArgSBuffer, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY ); - int nArgvBufferSize = 0; - while ( bufParse.IsValid() && ( m_nArgc < COMMAND_MAX_ARGC ) ) - { - char *pArgvBuf = &m_pArgvBuffer[nArgvBufferSize]; - int nMaxLen = COMMAND_MAX_LENGTH - nArgvBufferSize; - int nStartGet = bufParse.TellGet(); - int nSize = bufParse.ParseToken( pBreakSet, pArgvBuf, nMaxLen ); - if ( nSize < 0 ) - break; - - // Check for overflow condition - if ( nMaxLen == nSize ) - { - Reset(); - return false; - } - - if ( m_nArgc == 1 ) - { - // Deal with the case where the arguments were quoted - m_nArgv0Size = bufParse.TellGet(); - bool bFoundEndQuote = m_pArgSBuffer[m_nArgv0Size-1] == '\"'; - if ( bFoundEndQuote ) - { - --m_nArgv0Size; - } - m_nArgv0Size -= nSize; - Assert( m_nArgv0Size != 0 ); - - // The StartGet check is to handle this case: "foo"bar - // which will parse into 2 different args. ArgS should point to bar. - bool bFoundStartQuote = ( m_nArgv0Size > nStartGet ) && ( m_pArgSBuffer[m_nArgv0Size-1] == '\"' ); - Assert( bFoundEndQuote == bFoundStartQuote ); - if ( bFoundStartQuote ) - { - --m_nArgv0Size; - } - } - - m_ppArgv[ m_nArgc++ ] = pArgvBuf; - if( m_nArgc >= COMMAND_MAX_ARGC ) - { - Warning( "CCommand::Tokenize: Encountered command which overflows the argument buffer.. Clamped!\n" ); - } - - nArgvBufferSize += nSize + 1; - Assert( nArgvBufferSize <= COMMAND_MAX_LENGTH ); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Helper function to parse arguments to commands. -//----------------------------------------------------------------------------- -const char* CCommand::FindArg( const char *pName ) const -{ - int nArgC = ArgC(); - for ( int i = 1; i < nArgC; i++ ) - { - if ( !Q_stricmp( Arg(i), pName ) ) - return (i+1) < nArgC ? Arg( i+1 ) : ""; - } - return 0; -} - -int CCommand::FindArgInt( const char *pName, int nDefaultVal ) const -{ - const char *pVal = FindArg( pName ); - if ( pVal ) - return atoi( pVal ); - else - return nDefaultVal; -} - - -//----------------------------------------------------------------------------- -// Default console command autocompletion function -//----------------------------------------------------------------------------- -int DefaultCompletionFunc( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ) -{ - return 0; -} - - -//----------------------------------------------------------------------------- -// Purpose: Constructs a console command -//----------------------------------------------------------------------------- -//ConCommand::ConCommand() -//{ -// m_bIsNewConCommand = true; -//} - -ConCommand::ConCommand( const char *pName, FnCommandCallbackV1_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) -{ - // Set the callback - m_fnCommandCallbackV1 = callback; - m_bUsingNewCommandCallback = false; - m_bUsingCommandCallbackInterface = false; - m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - m_bHasCompletionCallback = completionFunc != 0 ? true : false; - - // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); -} - -ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ ) -{ - // Set the callback - m_fnCommandCallback = callback; - m_bUsingNewCommandCallback = true; - m_fnCompletionCallback = completionFunc ? completionFunc : DefaultCompletionFunc; - m_bHasCompletionCallback = completionFunc != 0 ? true : false; - m_bUsingCommandCallbackInterface = false; - - // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); -} - -ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ ) -{ - // Set the callback - m_pCommandCallback = pCallback; - m_bUsingNewCommandCallback = false; - m_pCommandCompletionCallback = pCompletionCallback; - m_bHasCompletionCallback = ( pCompletionCallback != 0 ); - m_bUsingCommandCallbackInterface = true; - - // Setup the rest - BaseClass::Create( pName, pHelpString, flags ); -} - -//----------------------------------------------------------------------------- -// Destructor -//----------------------------------------------------------------------------- -ConCommand::~ConCommand( void ) -{ -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns true if this is a command -//----------------------------------------------------------------------------- -bool ConCommand::IsCommand( void ) const -{ - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: Invoke the function if there is one -//----------------------------------------------------------------------------- -void ConCommand::Dispatch( const CCommand &command ) -{ - if ( m_bUsingNewCommandCallback ) - { - if ( m_fnCommandCallback ) - { - ( *m_fnCommandCallback )( command ); - return; - } - } - else if ( m_bUsingCommandCallbackInterface ) - { - if ( m_pCommandCallback ) - { - m_pCommandCallback->CommandCallback( command ); - return; - } - } - else - { - if ( m_fnCommandCallbackV1 ) - { - ( *m_fnCommandCallbackV1 )(); - return; - } - } - - // Command without callback!!! - AssertMsg( 0, ( "Encountered ConCommand '%s' without a callback!\n", GetName() ) ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Calls the autocompletion method to get autocompletion suggestions -//----------------------------------------------------------------------------- -int ConCommand::AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands ) -{ - if ( m_bUsingCommandCallbackInterface ) - { - if ( !m_pCommandCompletionCallback ) - return 0; - return m_pCommandCompletionCallback->CommandCompletionCallback( partial, commands ); - } - - Assert( m_fnCompletionCallback ); - if ( !m_fnCompletionCallback ) - return 0; - - char rgpchCommands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ]; - int iret = ( m_fnCompletionCallback )( partial, rgpchCommands ); - for ( int i = 0 ; i < iret; ++i ) - { - CUtlString str = rgpchCommands[ i ]; - commands.AddToTail( str ); - } - return iret; -} - - -//----------------------------------------------------------------------------- -// Returns true if the console command can autocomplete -//----------------------------------------------------------------------------- -bool ConCommand::CanAutoComplete( void ) -{ - return m_bHasCompletionCallback; -} - - - -//----------------------------------------------------------------------------- -// -// Console Variables -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Various constructors -//----------------------------------------------------------------------------- -ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags /* = 0 */ ) -{ - Create( pName, pDefaultValue, flags ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags, const char *pHelpString ) -{ - Create( pName, pDefaultValue, flags, pHelpString ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags, const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) -{ - Create( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags, const char *pHelpString, FnChangeCallback_t callback ) -{ - Create( pName, pDefaultValue, flags, pHelpString, false, 0.0, false, 0.0, callback ); -} - -ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags, const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax, FnChangeCallback_t callback ) -{ - Create( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax, callback ); -} - - -//----------------------------------------------------------------------------- -// Destructor -//----------------------------------------------------------------------------- -ConVar::~ConVar( void ) -{ - if ( m_pszString ) - { - delete[] m_pszString; - m_pszString = NULL; - } -} - - -//----------------------------------------------------------------------------- -// Install a change callback (there shouldn't already be one....) -//----------------------------------------------------------------------------- -void ConVar::InstallChangeCallback( FnChangeCallback_t callback ) -{ - Assert( !m_pParent->m_fnChangeCallback || !callback ); - m_pParent->m_fnChangeCallback = callback; - - if ( m_pParent->m_fnChangeCallback ) - { - // Call it immediately to set the initial value... - m_pParent->m_fnChangeCallback( this, m_pszString, m_fValue ); - } -} - -bool ConVar::IsFlagSet( int flag ) const -{ - return ( flag & m_pParent->m_nFlags ) ? true : false; -} - -const char *ConVar::GetHelpText( void ) const -{ - return m_pParent->m_pszHelpString; -} - -void ConVar::AddFlags( int flags ) -{ - m_pParent->m_nFlags |= flags; - -#ifdef ALLOW_DEVELOPMENT_CVARS - m_pParent->m_nFlags &= ~FCVAR_DEVELOPMENTONLY; -#endif -} - -bool ConVar::IsRegistered( void ) const -{ - return m_pParent->m_bRegistered; -} - -const char *ConVar::GetName( void ) const -{ - return m_pParent->m_pszName; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool ConVar::IsCommand( void ) const -{ - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -//----------------------------------------------------------------------------- -void ConVar::Init() -{ - BaseClass::Init(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetValue( const char *value ) -{ - float fNewValue; - char tempVal[ 32 ]; - char *val; - - Assert(m_pParent == this); // Only valid for root convars. - - float flOldValue = m_fValue; - - val = (char *)value; - fNewValue = ( float )atof( value ); - - if ( ClampValue( fNewValue ) ) - { - Q_snprintf( tempVal,sizeof(tempVal), "%f", fNewValue ); - val = tempVal; - } - - // Redetermine value - m_fValue = fNewValue; - m_nValue = ( int )( m_fValue ); - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - ChangeStringValue( val, flOldValue ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *tempVal - -//----------------------------------------------------------------------------- -void ConVar::ChangeStringValue( const char *tempVal, float flOldValue ) -{ - Assert( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ); - - char* pszOldValue = (char*)stackalloc( m_StringLength ); - memcpy( pszOldValue, m_pszString, m_StringLength ); - - int len = Q_strlen(tempVal) + 1; - - if ( len > m_StringLength) - { - if (m_pszString) - { - delete[] m_pszString; - } - - m_pszString = new char[len]; - m_StringLength = len; - } - - memcpy( m_pszString, tempVal, len ); - - // Invoke any necessary callback function - if ( m_fnChangeCallback ) - { - m_fnChangeCallback( this, pszOldValue, flOldValue ); - } - - g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue ); - - stackfree( pszOldValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: Check whether to clamp and then perform clamp -// Input : value - -// Output : Returns true if value changed -//----------------------------------------------------------------------------- -bool ConVar::ClampValue( float& value ) -{ - if ( m_bHasMin && ( value < m_fMinVal ) ) - { - value = m_fMinVal; - return true; - } - - if ( m_bHasMax && ( value > m_fMaxVal ) ) - { - value = m_fMaxVal; - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetFloatValue( float fNewValue ) -{ - if ( fNewValue == m_fValue ) - return; - - Assert( m_pParent == this ); // Only valid for root convars. - - // Check bounds - ClampValue( fNewValue ); - - // Redetermine value - float flOldValue = m_fValue; - m_fValue = fNewValue; - m_nValue = ( int )m_fValue; - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - char tempVal[ 32 ]; - Q_snprintf( tempVal, sizeof( tempVal), "%f", m_fValue ); - ChangeStringValue( tempVal, flOldValue ); - } - else - { - Assert( !m_fnChangeCallback ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::InternalSetIntValue( int nValue ) -{ - if ( nValue == m_nValue ) - return; - - Assert( m_pParent == this ); // Only valid for root convars. - - float fValue = (float)nValue; - if ( ClampValue( fValue ) ) - { - nValue = ( int )( fValue ); - } - - // Redetermine value - float flOldValue = m_fValue; - m_fValue = fValue; - m_nValue = nValue; - - if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) ) - { - char tempVal[ 32 ]; - Q_snprintf( tempVal, sizeof( tempVal ), "%d", m_nValue ); - ChangeStringValue( tempVal, flOldValue ); - } - else - { - Assert( !m_fnChangeCallback ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Private creation -//----------------------------------------------------------------------------- -void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*= 0*/, - const char *pHelpString /*= NULL*/, bool bMin /*= false*/, float fMin /*= 0.0*/, - bool bMax /*= false*/, float fMax /*= false*/, FnChangeCallback_t callback /*= NULL*/ ) -{ - static char *empty_string = ""; - - m_pParent = this; - - // Name should be static data - m_pszDefaultValue = pDefaultValue ? pDefaultValue : empty_string; - Assert( m_pszDefaultValue ); - - m_StringLength = strlen( m_pszDefaultValue ) + 1; - m_pszString = new char[m_StringLength]; - memcpy( m_pszString, m_pszDefaultValue, m_StringLength ); - - m_bHasMin = bMin; - m_fMinVal = fMin; - m_bHasMax = bMax; - m_fMaxVal = fMax; - - m_fnChangeCallback = callback; - - m_fValue = ( float )atof( m_pszString ); - - // Bounds Check, should never happen, if it does, no big deal - if ( m_bHasMin && ( m_fValue < m_fMinVal ) ) - { - Assert( 0 ); - } - - if ( m_bHasMax && ( m_fValue > m_fMaxVal ) ) - { - Assert( 0 ); - } - - m_nValue = ( int )m_fValue; - - BaseClass::Create( pName, pHelpString, flags ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *value - -//----------------------------------------------------------------------------- -void ConVar::SetValue(const char *value) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : value - -//----------------------------------------------------------------------------- -void ConVar::SetValue( float value ) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetFloatValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : value - -//----------------------------------------------------------------------------- -void ConVar::SetValue( int value ) -{ - ConVar *var = ( ConVar * )m_pParent; - var->InternalSetIntValue( value ); -} - -//----------------------------------------------------------------------------- -// Purpose: Reset to default value -//----------------------------------------------------------------------------- -void ConVar::Revert( void ) -{ - // Force default value again - ConVar *var = ( ConVar * )m_pParent; - var->SetValue( var->m_pszDefaultValue ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : minVal - -// Output : true if there is a min set -//----------------------------------------------------------------------------- -bool ConVar::GetMin( float& minVal ) const -{ - minVal = m_pParent->m_fMinVal; - return m_pParent->m_bHasMin; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : maxVal - -//----------------------------------------------------------------------------- -bool ConVar::GetMax( float& maxVal ) const -{ - maxVal = m_pParent->m_fMaxVal; - return m_pParent->m_bHasMax; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const char -//----------------------------------------------------------------------------- -const char *ConVar::GetDefault( void ) const -{ - return m_pParent->m_pszDefaultValue; -} - - -//----------------------------------------------------------------------------- -// This version is simply used to make reading convars simpler. -// Writing convars isn't allowed in this mode -//----------------------------------------------------------------------------- -class CEmptyConVar : public ConVar -{ -public: - CEmptyConVar() : ConVar( "", "0" ) {} - // Used for optimal read access - virtual void SetValue( const char *pValue ) {} - virtual void SetValue( float flValue ) {} - virtual void SetValue( int nValue ) {} - virtual const char *GetName( void ) const { return ""; } - virtual bool IsFlagSet( int nFlags ) const { return false; } -}; - -static CEmptyConVar s_EmptyConVar; - -ConVarRef::ConVarRef( const char *pName ) -{ - Init( pName, false ); -} - -ConVarRef::ConVarRef( const char *pName, bool bIgnoreMissing ) -{ - Init( pName, bIgnoreMissing ); -} - -void ConVarRef::Init( const char *pName, bool bIgnoreMissing ) -{ - m_pConVar = g_pCVar ? g_pCVar->FindVar( pName ) : &s_EmptyConVar; - if ( !m_pConVar ) - { - m_pConVar = &s_EmptyConVar; - } - m_pConVarState = static_cast< ConVar * >( m_pConVar ); - if( !IsValid() ) - { - static bool bFirst = true; - if ( g_pCVar || bFirst ) - { - if ( !bIgnoreMissing ) - { - Warning( "ConVarRef %s doesn't point to an existing ConVar\n", pName ); - } - bFirst = false; - } - } -} - -ConVarRef::ConVarRef( IConVar *pConVar ) -{ - m_pConVar = pConVar ? pConVar : &s_EmptyConVar; - m_pConVarState = static_cast< ConVar * >( m_pConVar ); -} - -bool ConVarRef::IsValid() const -{ - return m_pConVar != &s_EmptyConVar; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void ConVar_PrintFlags( const ConCommandBase *var ) -{ - bool any = false; - if ( var->IsFlagSet( FCVAR_GAMEDLL ) ) - { - ConMsg( " game" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_CLIENTDLL ) ) - { - ConMsg( " client" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_ARCHIVE ) ) - { - ConMsg( " archive" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_NOTIFY ) ) - { - ConMsg( " notify" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_SPONLY ) ) - { - ConMsg( " singleplayer" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_NOT_CONNECTED ) ) - { - ConMsg( " notconnected" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_CHEAT ) ) - { - ConMsg( " cheat" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_REPLICATED ) ) - { - ConMsg( " replicated" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_SERVER_CAN_EXECUTE ) ) - { - ConMsg( " server_can_execute" ); - any = true; - } - - if ( var->IsFlagSet( FCVAR_CLIENTCMD_CAN_EXECUTE ) ) - { - ConMsg( " clientcmd_can_execute" ); - any = true; - } - - if ( any ) - { - ConMsg( "\n" ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void ConVar_PrintDescription( const ConCommandBase *pVar ) -{ - bool bMin, bMax; - float fMin, fMax; - const char *pStr; - - assert( pVar ); - - Color clr; - clr.SetColor( 255, 100, 100, 255 ); - - if ( !pVar->IsCommand() ) - { - ConVar *var = ( ConVar * )pVar; - const ConVar_ServerBounded *pBounded = dynamic_cast( var ); - - bMin = var->GetMin( fMin ); - bMax = var->GetMax( fMax ); - - const char *value = NULL; - char tempVal[ 32 ]; - - if ( pBounded || var->IsFlagSet( FCVAR_NEVER_AS_STRING ) ) - { - value = tempVal; - - int intVal = pBounded ? pBounded->GetInt() : var->GetInt(); - float floatVal = pBounded ? pBounded->GetFloat() : var->GetFloat(); - - if ( fabs( (float)intVal - floatVal ) < 0.000001 ) - { - Q_snprintf( tempVal, sizeof( tempVal ), "%d", intVal ); - } - else - { - Q_snprintf( tempVal, sizeof( tempVal ), "%f", floatVal ); - } - } - else - { - value = var->GetString(); - } - - if ( value ) - { - ConColorMsg( clr, "\"%s\" = \"%s\"", var->GetName(), value ); - - if ( stricmp( value, var->GetDefault() ) ) - { - ConMsg( " ( def. \"%s\" )", var->GetDefault() ); - } - } - - if ( bMin ) - { - ConMsg( " min. %f", fMin ); - } - if ( bMax ) - { - ConMsg( " max. %f", fMax ); - } - - ConMsg( "\n" ); - - // Handled virtualized cvars. - if ( pBounded && fabs( pBounded->GetFloat() - var->GetFloat() ) > 0.0001f ) - { - ConColorMsg( clr, "** NOTE: The real value is %.3f but the server has temporarily restricted it to %.3f **\n", - var->GetFloat(), pBounded->GetFloat() ); - } - } - else - { - ConCommand *var = ( ConCommand * )pVar; - - ConColorMsg( clr, "\"%s\"\n", var->GetName() ); - } - - ConVar_PrintFlags( pVar ); - - pStr = pVar->GetHelpText(); - if ( pStr && pStr[0] ) - { - ConMsg( " - %s\n", pStr ); - } -} diff --git a/Resources/NetHook/tier1/convar.h b/Resources/NetHook/tier1/convar.h deleted file mode 100644 index 126aa78a..00000000 --- a/Resources/NetHook/tier1/convar.h +++ /dev/null @@ -1,671 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $NoKeywords: $ -//===========================================================================// - -#ifndef CONVAR_H -#define CONVAR_H - -#if _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "tier1/iconvar.h" -#include "tier1/utlvector.h" -#include "tier1/utlstring.h" -#include "icvar.h" - -#ifdef _WIN32 -#define FORCEINLINE_CVAR FORCEINLINE -#elif _LINUX -#define FORCEINLINE_CVAR inline -#else -#error "implement me" -#endif - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class ConVar; -class CCommand; -class ConCommand; -class ConCommandBase; -struct characterset_t; - - - -//----------------------------------------------------------------------------- -// Any executable that wants to use ConVars need to implement one of -// these to hook up access to console variables. -//----------------------------------------------------------------------------- -class IConCommandBaseAccessor -{ -public: - // Flags is a combination of FCVAR flags in cvar.h. - // hOut is filled in with a handle to the variable. - virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0; -}; - - -//----------------------------------------------------------------------------- -// Helper method for console development -//----------------------------------------------------------------------------- -#if defined( _X360 ) && !defined( _RETAIL ) -void ConVar_PublishToVXConsole(); -#endif - - -//----------------------------------------------------------------------------- -// Called when a ConCommand needs to execute -//----------------------------------------------------------------------------- -typedef void ( *FnCommandCallbackV1_t )( void ); -typedef void ( *FnCommandCallback_t )( const CCommand &command ); - -#define COMMAND_COMPLETION_MAXITEMS 64 -#define COMMAND_COMPLETION_ITEM_LENGTH 64 - -//----------------------------------------------------------------------------- -// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings -//----------------------------------------------------------------------------- -typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); - - -//----------------------------------------------------------------------------- -// Interface version -//----------------------------------------------------------------------------- -class ICommandCallback -{ -public: - virtual void CommandCallback( const CCommand &command ) = 0; -}; - -class ICommandCompletionCallback -{ -public: - virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0; -}; - -//----------------------------------------------------------------------------- -// Purpose: The base console invoked command/cvar interface -//----------------------------------------------------------------------------- -class ConCommandBase -{ - friend class CCvar; - friend class ConVar; - friend class ConCommand; - friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor ); - friend void ConVar_PublishToVXConsole(); - - // FIXME: Remove when ConVar changes are done - friend class CDefaultCvar; - -public: - ConCommandBase( void ); - ConCommandBase( const char *pName, const char *pHelpString = 0, - int flags = 0 ); - - virtual ~ConCommandBase( void ); - - virtual bool IsCommand( void ) const; - - // Check flag - virtual bool IsFlagSet( int flag ) const; - // Set flag - virtual void AddFlags( int flags ); - - // Return name of cvar - virtual const char *GetName( void ) const; - - // Return help text for cvar - virtual const char *GetHelpText( void ) const; - - // Deal with next pointer - const ConCommandBase *GetNext( void ) const; - ConCommandBase *GetNext( void ); - - virtual bool IsRegistered( void ) const; - - // Returns the DLL identifier - virtual CVarDLLIdentifier_t GetDLLIdentifier() const; - -protected: - virtual void Create( const char *pName, const char *pHelpString = 0, - int flags = 0 ); - - // Used internally by OneTimeInit to initialize/shutdown - virtual void Init(); - void Shutdown(); - - // Internal copy routine ( uses new operator from correct module ) - char *CopyString( const char *from ); - -private: - // Next ConVar in chain - // Prior to register, it points to the next convar in the DLL. - // Once registered, though, m_pNext is reset to point to the next - // convar in the global list - ConCommandBase *m_pNext; - - // Has the cvar been added to the global list? - bool m_bRegistered; - - // Static data - const char *m_pszName; - const char *m_pszHelpString; - - // ConVar flags - int m_nFlags; - -protected: - // ConVars add themselves to this list for the executable. - // Then ConVar_Register runs through all the console variables - // and registers them into a global list stored in vstdlib.dll - static ConCommandBase *s_pConCommandBases; - - // ConVars in this executable use this 'global' to access values. - static IConCommandBaseAccessor *s_pAccessor; -}; - - -//----------------------------------------------------------------------------- -// Command tokenizer -//----------------------------------------------------------------------------- -class CCommand -{ -public: - CCommand(); - CCommand( int nArgC, const char **ppArgV ); - bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL ); - void Reset(); - - int ArgC() const; - const char **ArgV() const; - const char *ArgS() const; // All args that occur after the 0th arg, in string form - const char *GetCommandString() const; // The entire command in string form, including the 0th arg - const char *operator[]( int nIndex ) const; // Gets at arguments - const char *Arg( int nIndex ) const; // Gets at arguments - - // Helper functions to parse arguments to commands. - const char* FindArg( const char *pName ) const; - int FindArgInt( const char *pName, int nDefaultVal ) const; - - static int MaxCommandLength(); - static characterset_t* DefaultBreakSet(); - -private: - enum - { - COMMAND_MAX_ARGC = 64, - COMMAND_MAX_LENGTH = 512, - }; - - int m_nArgc; - int m_nArgv0Size; - char m_pArgSBuffer[ COMMAND_MAX_LENGTH ]; - char m_pArgvBuffer[ COMMAND_MAX_LENGTH ]; - const char* m_ppArgv[ COMMAND_MAX_ARGC ]; -}; - -inline int CCommand::MaxCommandLength() -{ - return COMMAND_MAX_LENGTH - 1; -} - -inline int CCommand::ArgC() const -{ - return m_nArgc; -} - -inline const char **CCommand::ArgV() const -{ - return m_nArgc ? (const char**)m_ppArgv : NULL; -} - -inline const char *CCommand::ArgS() const -{ - return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : ""; -} - -inline const char *CCommand::GetCommandString() const -{ - return m_nArgc ? m_pArgSBuffer : ""; -} - -inline const char *CCommand::Arg( int nIndex ) const -{ - // FIXME: Many command handlers appear to not be particularly careful - // about checking for valid argc range. For now, we're going to - // do the extra check and return an empty string if it's out of range - if ( nIndex < 0 || nIndex >= m_nArgc ) - return ""; - return m_ppArgv[nIndex]; -} - -inline const char *CCommand::operator[]( int nIndex ) const -{ - return Arg( nIndex ); -} - - -//----------------------------------------------------------------------------- -// Purpose: The console invoked command -//----------------------------------------------------------------------------- -class ConCommand : public ConCommandBase -{ -friend class CCvar; - -public: - typedef ConCommandBase BaseClass; - - ConCommand( const char *pName, FnCommandCallbackV1_t callback, - const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( const char *pName, FnCommandCallback_t callback, - const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - ConCommand( const char *pName, ICommandCallback *pCallback, - const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 ); - - virtual ~ConCommand( void ); - - virtual bool IsCommand( void ) const; - - virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands ); - - virtual bool CanAutoComplete( void ); - - // Invoke the function - virtual void Dispatch( const CCommand &command ); - -private: - // NOTE: To maintain backward compat, we have to be very careful: - // All public virtual methods must appear in the same order always - // since engine code will be calling into this code, which *does not match* - // in the mod code; it's using slightly different, but compatible versions - // of this class. Also: Be very careful about adding new fields to this class. - // Those fields will not exist in the version of this class that is instanced - // in mod code. - - // Call this function when executing the command - union - { - FnCommandCallbackV1_t m_fnCommandCallbackV1; - FnCommandCallback_t m_fnCommandCallback; - ICommandCallback *m_pCommandCallback; - }; - - union - { - FnCommandCompletionCallback m_fnCompletionCallback; - ICommandCompletionCallback *m_pCommandCompletionCallback; - }; - - bool m_bHasCompletionCallback : 1; - bool m_bUsingNewCommandCallback : 1; - bool m_bUsingCommandCallbackInterface : 1; -}; - - -//----------------------------------------------------------------------------- -// Purpose: A console variable -//----------------------------------------------------------------------------- -class ConVar : public ConCommandBase, public IConVar -{ -friend class CCvar; -friend class ConVarRef; - -public: - typedef ConCommandBase BaseClass; - - ConVar( const char *pName, const char *pDefaultValue, int flags = 0); - - ConVar( const char *pName, const char *pDefaultValue, int flags, - const char *pHelpString ); - ConVar( const char *pName, const char *pDefaultValue, int flags, - const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax ); - ConVar( const char *pName, const char *pDefaultValue, int flags, - const char *pHelpString, FnChangeCallback_t callback ); - ConVar( const char *pName, const char *pDefaultValue, int flags, - const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax, - FnChangeCallback_t callback ); - - virtual ~ConVar( void ); - - virtual bool IsFlagSet( int flag ) const; - virtual const char* GetHelpText( void ) const; - virtual bool IsRegistered( void ) const; - virtual const char *GetName( void ) const; - virtual void AddFlags( int flags ); - virtual bool IsCommand( void ) const; - - // Install a change callback (there shouldn't already be one....) - void InstallChangeCallback( FnChangeCallback_t callback ); - - // Retrieve value - FORCEINLINE_CVAR float GetFloat( void ) const; - FORCEINLINE_CVAR int GetInt( void ) const; - FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } - FORCEINLINE_CVAR char const *GetString( void ) const; - - // Any function that allocates/frees memory needs to be virtual or else you'll have crashes - // from alloc/free across dll/exe boundaries. - - // These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue). - virtual void SetValue( const char *value ); - virtual void SetValue( float value ); - virtual void SetValue( int value ); - - // Reset to default value - void Revert( void ); - - // True if it has a min/max setting - bool GetMin( float& minVal ) const; - bool GetMax( float& maxVal ) const; - const char *GetDefault( void ) const; - -private: - // Called by CCvar when the value of a var is changing. - virtual void InternalSetValue(const char *value); - // For CVARs marked FCVAR_NEVER_AS_STRING - virtual void InternalSetFloatValue( float fNewValue ); - virtual void InternalSetIntValue( int nValue ); - - virtual bool ClampValue( float& value ); - virtual void ChangeStringValue( const char *tempVal, float flOldValue ); - - virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0, - const char *pHelpString = 0, bool bMin = false, float fMin = 0.0, - bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 ); - - // Used internally by OneTimeInit to initialize. - virtual void Init(); - -private: - - // This either points to "this" or it points to the original declaration of a ConVar. - // This allows ConVars to exist in separate modules, and they all use the first one to be declared. - // m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). - ConVar *m_pParent; - - // Static data - const char *m_pszDefaultValue; - - // Value - // Dynamically allocated - char *m_pszString; - int m_StringLength; - - // Values - float m_fValue; - int m_nValue; - - // Min/Max values - bool m_bHasMin; - float m_fMinVal; - bool m_bHasMax; - float m_fMaxVal; - - // Call this function when ConVar changes - FnChangeCallback_t m_fnChangeCallback; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float -// Output : float -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR float ConVar::GetFloat( void ) const -{ - return m_pParent->m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an int -// Output : int -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR int ConVar::GetInt( void ) const -{ - return m_pParent->m_nValue; -} - - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. -// Output : const char * -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR const char *ConVar::GetString( void ) const -{ - if ( m_nFlags & FCVAR_NEVER_AS_STRING ) - return "FCVAR_NEVER_AS_STRING"; - - return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : ""; -} - - -//----------------------------------------------------------------------------- -// Used to read/write convars that already exist (replaces the FindVar method) -//----------------------------------------------------------------------------- -class ConVarRef -{ -public: - ConVarRef( const char *pName ); - ConVarRef( const char *pName, bool bIgnoreMissing ); - ConVarRef( IConVar *pConVar ); - - void Init( const char *pName, bool bIgnoreMissing ); - bool IsValid() const; - bool IsFlagSet( int nFlags ) const; - IConVar *GetLinkedConVar(); - - // Get/Set value - float GetFloat( void ) const; - int GetInt( void ) const; - bool GetBool() const { return !!GetInt(); } - const char *GetString( void ) const; - - void SetValue( const char *pValue ); - void SetValue( float flValue ); - void SetValue( int nValue ); - void SetValue( bool bValue ); - - const char *GetName() const; - - const char *GetDefault() const; - -private: - // High-speed method to read convar data - IConVar *m_pConVar; - ConVar *m_pConVarState; -}; - - -//----------------------------------------------------------------------------- -// Did we find an existing convar of that name? -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const -{ - return ( m_pConVar->IsFlagSet( nFlags ) != 0 ); -} - -FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar() -{ - return m_pConVar; -} - -FORCEINLINE_CVAR const char *ConVarRef::GetName() const -{ - return m_pConVar->GetName(); -} - - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const -{ - return m_pConVarState->m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an int -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const -{ - return m_pConVarState->m_nValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const -{ - Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) ); - return m_pConVarState->m_pszString; -} - - -FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue ) -{ - m_pConVar->SetValue( pValue ); -} - -FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue ) -{ - m_pConVar->SetValue( flValue ); -} - -FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue ) -{ - m_pConVar->SetValue( nValue ); -} - -FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue ) -{ - m_pConVar->SetValue( bValue ? 1 : 0 ); -} - -FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const -{ - return m_pConVarState->m_pszDefaultValue; -} - - -//----------------------------------------------------------------------------- -// Called by the framework to register ConCommands with the ICVar -//----------------------------------------------------------------------------- -void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL ); -void ConVar_Unregister( ); - - -//----------------------------------------------------------------------------- -// Utility methods -//----------------------------------------------------------------------------- -void ConVar_PrintFlags( const ConCommandBase *var ); -void ConVar_PrintDescription( const ConCommandBase *pVar ); - - -//----------------------------------------------------------------------------- -// Purpose: Utility class to quickly allow ConCommands to call member methods -//----------------------------------------------------------------------------- -#pragma warning (disable : 4355 ) - -template< class T > -class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback -{ - typedef ConCommand BaseClass; - typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command ); - typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands ); - -public: - CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0, - int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) : - BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL ) - { - m_pOwner = pOwner; - m_Func = callback; - m_CompletionFunc = completionFunc; - } - - ~CConCommandMemberAccessor() - { - Shutdown(); - } - - void SetOwner( T* pOwner ) - { - m_pOwner = pOwner; - } - - virtual void CommandCallback( const CCommand &command ) - { - Assert( m_pOwner && m_Func ); - (m_pOwner->*m_Func)( command ); - } - - virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) - { - Assert( m_pOwner && m_CompletionFunc ); - return (m_pOwner->*m_CompletionFunc)( pPartial, commands ); - } - -private: - T* m_pOwner; - FnMemberCommandCallback_t m_Func; - FnMemberCommandCompletionCallback_t m_CompletionFunc; -}; - -#pragma warning ( default : 4355 ) - - -//----------------------------------------------------------------------------- -// Purpose: Utility macros to quicky generate a simple console command -//----------------------------------------------------------------------------- -#define CON_COMMAND( name, description ) \ - static void name( const CCommand &args ); \ - static ConCommand name##_command( #name, name, description ); \ - static void name( const CCommand &args ) - -#define CON_COMMAND_F( name, description, flags ) \ - static void name( const CCommand &args ); \ - static ConCommand name##_command( #name, name, description, flags ); \ - static void name( const CCommand &args ) - -#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \ - static void name( const CCommand &args ); \ - static ConCommand name##_command( #name, name, description, flags, completion ); \ - static void name( const CCommand &args ) - -#define CON_COMMAND_EXTERN( name, _funcname, description ) \ - void _funcname( const CCommand &args ); \ - static ConCommand name##_command( #name, _funcname, description ); \ - void _funcname( const CCommand &args ) - -#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \ - void _funcname( const CCommand &args ); \ - static ConCommand name##_command( #name, _funcname, description, flags ); \ - void _funcname( const CCommand &args ) - -#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \ - void _funcname( const CCommand &args ); \ - friend class CCommandMemberInitializer_##_funcname; \ - class CCommandMemberInitializer_##_funcname \ - { \ - public: \ - CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \ - { \ - m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \ - } \ - private: \ - CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \ - }; \ - \ - CCommandMemberInitializer_##_funcname m_##_funcname##_register; \ - - -#endif // CONVAR_H diff --git a/Resources/NetHook/tier1/convar_serverbounded.h b/Resources/NetHook/tier1/convar_serverbounded.h deleted file mode 100644 index 26d74dc6..00000000 --- a/Resources/NetHook/tier1/convar_serverbounded.h +++ /dev/null @@ -1,53 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Helper class for cvars that have restrictions on their value. -// -//=============================================================================// - -#ifndef CONVAR_SERVERBOUNDED_H -#define CONVAR_SERVERBOUNDED_H -#ifdef _WIN32 -#pragma once -#endif - - -// This class is used to virtualize a ConVar's value, so the client can restrict its -// value while connected to a server. When using this across modules, it's important -// to dynamic_cast it to a ConVar_ServerBounded or you won't get the restricted value. -// -// NOTE: FCVAR_USERINFO vars are not virtualized before they are sent to the server -// (we have no way to detect if the virtualized value would change), so -// if you want to use a bounded cvar's value on the server, you must rebound it -// the same way the client does. -class ConVar_ServerBounded : public ConVar -{ -public: - ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) - : ConVar( pName, pDefaultValue, flags, pHelpString ) - { - } - - ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, FnChangeCallback_t callback ) - : ConVar( pName, pDefaultValue, flags, pHelpString, callback ) - { - } - - ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) - : ConVar( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax ) {} - - // You must implement GetFloat. - virtual float GetFloat() const = 0; - - // You can optionally implement these. - virtual int GetInt() const { return (int)GetFloat(); } - virtual bool GetBool() const { return ( GetInt() != 0 ); } - - // Use this to get the underlying cvar's value. - float GetBaseFloatValue() const - { - return ConVar::GetFloat(); - } -}; - - -#endif // CONVAR_SERVERBOUNDED_H diff --git a/Resources/NetHook/tier1/datamanager.cpp b/Resources/NetHook/tier1/datamanager.cpp deleted file mode 100644 index 24935280..00000000 --- a/Resources/NetHook/tier1/datamanager.cpp +++ /dev/null @@ -1,410 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#include "basetypes.h" -#include "datamanager.h" - -DECLARE_POINTER_HANDLE( memhandle_t ); - -#define AUTO_LOCK_DM() AUTO_LOCK_( CDataManagerBase, *this ) - -CDataManagerBase::CDataManagerBase( unsigned int maxSize ) -{ - m_targetMemorySize = maxSize; - m_memUsed = 0; - m_lruList = m_memoryLists.CreateList(); - m_lockList = m_memoryLists.CreateList(); - m_freeList = m_memoryLists.CreateList(); - m_listsAreFreed = 0; -} - -CDataManagerBase::~CDataManagerBase() -{ - Assert( m_listsAreFreed ); -} - -void CDataManagerBase::NotifySizeChanged( memhandle_t handle, unsigned int oldSize, unsigned int newSize ) -{ - Lock(); - m_memUsed += (int)newSize - (int)oldSize; - Unlock(); -} - -void CDataManagerBase::SetTargetSize( unsigned int targetSize ) -{ - m_targetMemorySize = targetSize; -} - -unsigned int CDataManagerBase::FlushAllUnlocked() -{ - Lock(); - - int nFlush = m_memoryLists.Count( m_lruList ); - void **pScratch = (void **)_alloca( nFlush * sizeof(void *) ); - CUtlVector destroyList( pScratch, nFlush ); - - unsigned nBytesInitial = MemUsed_Inline(); - - int node = m_memoryLists.Head(m_lruList); - while ( node != m_memoryLists.InvalidIndex() ) - { - int next = m_memoryLists.Next(node); - m_memoryLists.Unlink( m_lruList, node ); - destroyList.AddToTail( GetForFreeByIndex( node ) ); - node = next; - } - - Unlock(); - - for ( int i = 0; i < nFlush; i++ ) - { - DestroyResourceStorage( destroyList[i] ); - } - - return ( nBytesInitial - MemUsed_Inline() ); -} - -unsigned int CDataManagerBase::FlushToTargetSize() -{ - return EnsureCapacity(0); -} - -// Frees everything! The LRU AND the LOCKED items. This is only used to forcibly free the resources, -// not to make space. - -unsigned int CDataManagerBase::FlushAll() -{ - Lock(); - - int nFlush = m_memoryLists.Count( m_lruList ) + m_memoryLists.Count( m_lockList ); - void **pScratch = (void **)_alloca( nFlush * sizeof(void *) ); - CUtlVector destroyList( pScratch, nFlush ); - - unsigned result = MemUsed_Inline(); - int node; - int nextNode; - - node = m_memoryLists.Head(m_lruList); - while ( node != m_memoryLists.InvalidIndex() ) - { - nextNode = m_memoryLists.Next(node); - m_memoryLists.Unlink( m_lruList, node ); - destroyList.AddToTail( GetForFreeByIndex( node ) ); - node = nextNode; - } - - node = m_memoryLists.Head(m_lockList); - while ( node != m_memoryLists.InvalidIndex() ) - { - nextNode = m_memoryLists.Next(node); - m_memoryLists.Unlink( m_lockList, node ); - m_memoryLists[node].lockCount = 0; - destroyList.AddToTail( GetForFreeByIndex( node ) ); - node = nextNode; - } - - m_listsAreFreed = false; - Unlock(); - - for ( int i = 0; i < nFlush; i++ ) - { - DestroyResourceStorage( destroyList[i] ); - } - - return result; -} - -unsigned int CDataManagerBase::Purge( unsigned int nBytesToPurge ) -{ - unsigned int nTargetSize = MemUsed_Inline() - nBytesToPurge; - if ( nTargetSize < 0 ) - nTargetSize = 0; - unsigned int nImpliedCapacity = MemTotal_Inline() - nTargetSize; - return EnsureCapacity( nImpliedCapacity ); -} - - -void CDataManagerBase::DestroyResource( memhandle_t handle ) -{ - Lock(); - unsigned short index = FromHandle( handle ); - if ( !m_memoryLists.IsValidIndex(index) ) - { - Unlock(); - return; - } - - Assert( m_memoryLists[index].lockCount == 0 ); - if ( m_memoryLists[index].lockCount ) - BreakLock( handle ); - m_memoryLists.Unlink( m_lruList, index ); - void *p = GetForFreeByIndex( index ); - Unlock(); - - DestroyResourceStorage( p ); -} - - -void *CDataManagerBase::LockResource( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - if ( m_memoryLists[memoryIndex].lockCount == 0 ) - { - m_memoryLists.Unlink( m_lruList, memoryIndex ); - m_memoryLists.LinkToTail( m_lockList, memoryIndex ); - } - Assert(m_memoryLists[memoryIndex].lockCount != (unsigned short)-1); - m_memoryLists[memoryIndex].lockCount++; - return m_memoryLists[memoryIndex].pStore; - } - - return NULL; -} - -int CDataManagerBase::UnlockResource( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - Assert( m_memoryLists[memoryIndex].lockCount > 0 ); - if ( m_memoryLists[memoryIndex].lockCount > 0 ) - { - m_memoryLists[memoryIndex].lockCount--; - if ( m_memoryLists[memoryIndex].lockCount == 0 ) - { - m_memoryLists.Unlink( m_lockList, memoryIndex ); - m_memoryLists.LinkToTail( m_lruList, memoryIndex ); - } - } - return m_memoryLists[memoryIndex].lockCount; - } - - return 0; -} - -void *CDataManagerBase::GetResource_NoLockNoLRUTouch( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - return m_memoryLists[memoryIndex].pStore; - } - return NULL; -} - - -void *CDataManagerBase::GetResource_NoLock( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - TouchByIndex( memoryIndex ); - return m_memoryLists[memoryIndex].pStore; - } - return NULL; -} - -void CDataManagerBase::TouchResource( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - TouchByIndex( FromHandle(handle) ); -} - -void CDataManagerBase::MarkAsStale( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - if ( m_memoryLists[memoryIndex].lockCount == 0 ) - { - m_memoryLists.Unlink( m_lruList, memoryIndex ); - m_memoryLists.LinkToHead( m_lruList, memoryIndex ); - } - } -} - -int CDataManagerBase::BreakLock( memhandle_t handle ) -{ - AUTO_LOCK_DM(); - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() && m_memoryLists[memoryIndex].lockCount ) - { - int nBroken = m_memoryLists[memoryIndex].lockCount; - m_memoryLists[memoryIndex].lockCount = 0; - m_memoryLists.Unlink( m_lockList, memoryIndex ); - m_memoryLists.LinkToTail( m_lruList, memoryIndex ); - - return nBroken; - } - return 0; -} - -int CDataManagerBase::BreakAllLocks() -{ - AUTO_LOCK_DM(); - int nBroken = 0; - int node; - int nextNode; - - node = m_memoryLists.Head(m_lockList); - while ( node != m_memoryLists.InvalidIndex() ) - { - nBroken++; - nextNode = m_memoryLists.Next(node); - m_memoryLists[node].lockCount = 0; - m_memoryLists.Unlink( m_lockList, node ); - m_memoryLists.LinkToTail( m_lruList, node ); - node = nextNode; - } - - return nBroken; - -} - -unsigned short CDataManagerBase::CreateHandle( bool bCreateLocked ) -{ - AUTO_LOCK_DM(); - int memoryIndex = m_memoryLists.Head(m_freeList); - unsigned short list = ( bCreateLocked ) ? m_lockList : m_lruList; - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - m_memoryLists.Unlink( m_freeList, memoryIndex ); - m_memoryLists.LinkToTail( list, memoryIndex ); - } - else - { - memoryIndex = m_memoryLists.AddToTail( list ); - } - - if ( bCreateLocked ) - { - m_memoryLists[memoryIndex].lockCount++; - } - - return memoryIndex; -} - -memhandle_t CDataManagerBase::StoreResourceInHandle( unsigned short memoryIndex, void *pStore, unsigned int realSize ) -{ - AUTO_LOCK_DM(); - resource_lru_element_t &mem = m_memoryLists[memoryIndex]; - mem.pStore = pStore; - m_memUsed += realSize; - return ToHandle(memoryIndex); -} - -void CDataManagerBase::TouchByIndex( unsigned short memoryIndex ) -{ - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - if ( m_memoryLists[memoryIndex].lockCount == 0 ) - { - m_memoryLists.Unlink( m_lruList, memoryIndex ); - m_memoryLists.LinkToTail( m_lruList, memoryIndex ); - } - } -} - -memhandle_t CDataManagerBase::ToHandle( unsigned short index ) -{ - unsigned int hiword = m_memoryLists.Element(index).serial; - hiword <<= 16; - index++; - return (memhandle_t)( hiword|index ); -} - -unsigned int CDataManagerBase::TargetSize() -{ - return MemTotal_Inline(); -} - -unsigned int CDataManagerBase::AvailableSize() -{ - return MemAvailable_Inline(); -} - - -unsigned int CDataManagerBase::UsedSize() -{ - return MemUsed_Inline(); -} - -// free resources until there is enough space to hold "size" -unsigned int CDataManagerBase::EnsureCapacity( unsigned int size ) -{ - unsigned nBytesInitial = MemUsed_Inline(); - while ( MemUsed_Inline() > MemTotal_Inline() || MemAvailable_Inline() < size ) - { - Lock(); - int lruIndex = m_memoryLists.Head( m_lruList ); - if ( lruIndex == m_memoryLists.InvalidIndex() ) - { - Unlock(); - break; - } - m_memoryLists.Unlink( m_lruList, lruIndex ); - void *p = GetForFreeByIndex( lruIndex ); - Unlock(); - DestroyResourceStorage( p ); - } - return ( nBytesInitial - MemUsed_Inline() ); -} - -// free this resource and move the handle to the free list -void *CDataManagerBase::GetForFreeByIndex( unsigned short memoryIndex ) -{ - void *p = NULL; - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - Assert( m_memoryLists[memoryIndex].lockCount == 0 ); - - resource_lru_element_t &mem = m_memoryLists[memoryIndex]; - unsigned size = GetRealSize( mem.pStore ); - if ( size > m_memUsed ) - { - ExecuteOnce( Warning( "Data manager 'used' memory incorrect\n" ) ); - size = m_memUsed; - } - m_memUsed -= size; - p = mem.pStore; - mem.pStore = NULL; - mem.serial++; - m_memoryLists.LinkToTail( m_freeList, memoryIndex ); - } - return p; -} - -// get a list of everything in the LRU -void CDataManagerBase::GetLRUHandleList( CUtlVector< memhandle_t >& list ) -{ - for ( int node = m_memoryLists.Tail(m_lruList); - node != m_memoryLists.InvalidIndex(); - node = m_memoryLists.Previous(node) ) - { - list.AddToTail( ToHandle( node ) ); - } -} - -// get a list of everything locked -void CDataManagerBase::GetLockHandleList( CUtlVector< memhandle_t >& list ) -{ - for ( int node = m_memoryLists.Head(m_lockList); - node != m_memoryLists.InvalidIndex(); - node = m_memoryLists.Next(node) ) - { - list.AddToTail( ToHandle( node ) ); - } -} - diff --git a/Resources/NetHook/tier1/datamanager.h b/Resources/NetHook/tier1/datamanager.h deleted file mode 100644 index 02181541..00000000 --- a/Resources/NetHook/tier1/datamanager.h +++ /dev/null @@ -1,277 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef RESOURCEMANAGER_H -#define RESOURCEMANAGER_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/threadtools.h" -#include "utlmultilist.h" -#include "utlvector.h" - -FORWARD_DECLARE_HANDLE( memhandle_t ); - -#define INVALID_MEMHANDLE ((memhandle_t)0xffffffff) - -class CDataManagerBase -{ -public: - - // public API - // ----------------------------------------------------------------------------- - // memhandle_t CreateResource( params ) // implemented by derived class - void DestroyResource( memhandle_t handle ); - - // type-safe implementation in derived class - //void *LockResource( memhandle_t handle ); - int UnlockResource( memhandle_t handle ); - void TouchResource( memhandle_t handle ); - void MarkAsStale( memhandle_t handle ); // move to head of LRU - - int LockCount( memhandle_t handle ); - int BreakLock( memhandle_t handle ); - int BreakAllLocks(); - - // HACKHACK: For convenience - offers no lock protection - // type-safe implementation in derived class - //void *GetResource_NoLock( memhandle_t handle ); - - unsigned int TargetSize(); - unsigned int AvailableSize(); - unsigned int UsedSize(); - - void NotifySizeChanged( memhandle_t handle, unsigned int oldSize, unsigned int newSize ); - - void SetTargetSize( unsigned int targetSize ); - - // NOTE: flush is equivalent to Destroy - unsigned int FlushAllUnlocked(); - unsigned int FlushToTargetSize(); - unsigned int FlushAll(); - unsigned int Purge( unsigned int nBytesToPurge ); - unsigned int EnsureCapacity( unsigned int size ); - - // Thread lock - virtual void Lock() {} - virtual bool TryLock() { return true; } - virtual void Unlock() {} - - // Iteration - - // ----------------------------------------------------------------------------- - - // Debugging only!!!! - void GetLRUHandleList( CUtlVector< memhandle_t >& list ); - void GetLockHandleList( CUtlVector< memhandle_t >& list ); - - -protected: - // derived class must call these to implement public API - unsigned short CreateHandle( bool bCreateLocked ); - memhandle_t StoreResourceInHandle( unsigned short memoryIndex, void *pStore, unsigned int realSize ); - void *GetResource_NoLock( memhandle_t handle ); - void *GetResource_NoLockNoLRUTouch( memhandle_t handle ); - void *LockResource( memhandle_t handle ); - - // NOTE: you must call this from the destructor of the derived class! (will assert otherwise) - void FreeAllLists() { FlushAll(); m_listsAreFreed = true; } - - CDataManagerBase( unsigned int maxSize ); - virtual ~CDataManagerBase(); - - - inline unsigned int MemTotal_Inline() const { return m_targetMemorySize; } - inline unsigned int MemAvailable_Inline() const { return m_targetMemorySize - m_memUsed; } - inline unsigned int MemUsed_Inline() const { return m_memUsed; } - -// Implemented by derived class: - virtual void DestroyResourceStorage( void * ) = 0; - virtual unsigned int GetRealSize( void * ) = 0; - - memhandle_t ToHandle( unsigned short index ); - unsigned short FromHandle( memhandle_t handle ); - - void TouchByIndex( unsigned short memoryIndex ); - void * GetForFreeByIndex( unsigned short memoryIndex ); - - // One of these is stored per active allocation - struct resource_lru_element_t - { - resource_lru_element_t() - { - lockCount = 0; - serial = 1; - pStore = 0; - } - - unsigned short lockCount; - unsigned short serial; - void *pStore; - }; - - unsigned int m_targetMemorySize; - unsigned int m_memUsed; - - CUtlMultiList< resource_lru_element_t, unsigned short > m_memoryLists; - - unsigned short m_lruList; - unsigned short m_lockList; - unsigned short m_freeList; - unsigned short m_listsAreFreed : 1; - unsigned short m_unused : 15; - -}; - -template< class STORAGE_TYPE, class CREATE_PARAMS, class LOCK_TYPE = STORAGE_TYPE *, class MUTEX_TYPE = CThreadNullMutex> -class CDataManager : public CDataManagerBase -{ - typedef CDataManagerBase BaseClass; -public: - - CDataManager( unsigned int size = (unsigned)-1 ) : BaseClass(size) {} - - - ~CDataManager() - { - // NOTE: This must be called in all implementations of CDataManager - FreeAllLists(); - } - - // Use GetData() to translate pointer to LOCK_TYPE - LOCK_TYPE LockResource( memhandle_t hMem ) - { - void *pLock = BaseClass::LockResource( hMem ); - if ( pLock ) - { - return StoragePointer(pLock)->GetData(); - } - - return NULL; - } - - // Use GetData() to translate pointer to LOCK_TYPE - LOCK_TYPE GetResource_NoLock( memhandle_t hMem ) - { - void *pLock = const_cast(BaseClass::GetResource_NoLock( hMem )); - if ( pLock ) - { - return StoragePointer(pLock)->GetData(); - } - return NULL; - } - - // Use GetData() to translate pointer to LOCK_TYPE - // Doesn't touch the memory LRU - LOCK_TYPE GetResource_NoLockNoLRUTouch( memhandle_t hMem ) - { - void *pLock = const_cast(BaseClass::GetResource_NoLockNoLRUTouch( hMem )); - if ( pLock ) - { - return StoragePointer(pLock)->GetData(); - } - return NULL; - } - - // Wrapper to match implementation of allocation with typed storage & alloc params. - memhandle_t CreateResource( const CREATE_PARAMS &createParams, bool bCreateLocked = false ) - { - BaseClass::EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams)); - unsigned short memoryIndex = BaseClass::CreateHandle( bCreateLocked ); - STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams ); - return BaseClass::StoreResourceInHandle( memoryIndex, pStore, pStore->Size() ); - } - - // Iteration. Must lock first - memhandle_t GetFirstUnlocked() - { - unsigned node = m_memoryLists.Head(m_lruList); - if ( node == m_memoryLists.InvalidIndex() ) - { - return INVALID_MEMHANDLE; - } - return ToHandle( node ); - } - - memhandle_t GetFirstLocked() - { - unsigned node = m_memoryLists.Head(m_lockList); - if ( node == m_memoryLists.InvalidIndex() ) - { - return INVALID_MEMHANDLE; - } - return ToHandle( node ); - } - - memhandle_t GetNext( memhandle_t hPrev ) - { - if ( hPrev == INVALID_MEMHANDLE ) - { - return INVALID_MEMHANDLE; - } - - unsigned short iNext = m_memoryLists.Next( FromHandle( hPrev ) ); - if ( iNext == m_memoryLists.InvalidIndex() ) - { - return INVALID_MEMHANDLE; - } - - return ToHandle( iNext ); - } - - MUTEX_TYPE &AccessMutex() { return m_mutex; } - virtual void Lock() { m_mutex.Lock(); } - virtual bool TryLock() { return m_mutex.TryLock(); } - virtual void Unlock() { m_mutex.Unlock(); } - -private: - STORAGE_TYPE *StoragePointer( void *pMem ) - { - return static_cast(pMem); - } - - virtual void DestroyResourceStorage( void *pStore ) - { - StoragePointer(pStore)->DestroyResource(); - } - - virtual unsigned int GetRealSize( void *pStore ) - { - return StoragePointer(pStore)->Size(); - } - - MUTEX_TYPE m_mutex; -}; - -//----------------------------------------------------------------------------- - -inline unsigned short CDataManagerBase::FromHandle( memhandle_t handle ) -{ - unsigned int fullWord = (unsigned int)handle; - unsigned short serial = fullWord>>16; - unsigned short index = fullWord & 0xFFFF; - index--; - if ( m_memoryLists.IsValidIndex(index) && m_memoryLists[index].serial == serial ) - return index; - return m_memoryLists.InvalidIndex(); -} - -inline int CDataManagerBase::LockCount( memhandle_t handle ) -{ - Lock(); - int result = 0; - unsigned short memoryIndex = FromHandle(handle); - if ( memoryIndex != m_memoryLists.InvalidIndex() ) - { - result = m_memoryLists[memoryIndex].lockCount; - } - Unlock(); - return result; -} - - -#endif // RESOURCEMANAGER_H diff --git a/Resources/NetHook/tier1/delegates.h b/Resources/NetHook/tier1/delegates.h deleted file mode 100644 index aa357c28..00000000 --- a/Resources/NetHook/tier1/delegates.h +++ /dev/null @@ -1,99 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: Simple macros to generate delegation code -// -//============================================================================= - -#ifndef DELEGATES_H -#define DELEGATES_H - -#if defined( _WIN32 ) -#pragma once -#endif - -#define DELEGATE_TO_OBJECT_0( RetType, FuncName, pDelegated ) RetType FuncName() { return (pDelegated)->FuncName(); } -#define DELEGATE_TO_OBJECT_0V( FuncName, pDelegated ) void FuncName() { (pDelegated)->FuncName(); } -#define DELEGATE_TO_OBJECT_1( RetType, FuncName, ArgType1, pDelegated ) RetType FuncName( ArgType1 a1 ) { return (pDelegated)->FuncName( a1 ); } -#define DELEGATE_TO_OBJECT_1V( FuncName, ArgType1, pDelegated ) void FuncName( ArgType1 a1 ) { (pDelegated)->FuncName( a1 ); } -#define DELEGATE_TO_OBJECT_2( RetType, FuncName, ArgType1, ArgType2, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2 ) { return (pDelegated)->FuncName( a1, a2 ); } -#define DELEGATE_TO_OBJECT_2V( FuncName, ArgType1, ArgType2, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2 ) { (pDelegated)->FuncName( a1, a2 ); } -#define DELEGATE_TO_OBJECT_3( RetType, FuncName, ArgType1, ArgType2, ArgType3, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) { return (pDelegated)->FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_OBJECT_3V( FuncName, ArgType1, ArgType2, ArgType3, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) { (pDelegated)->FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_OBJECT_4( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) { return (pDelegated)->FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_OBJECT_4V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) { (pDelegated)->FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_OBJECT_5( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) { return (pDelegated)->FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_OBJECT_5V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_OBJECT_6( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_OBJECT_6V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_OBJECT_7( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_OBJECT_7V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_OBJECT_8( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_OBJECT_8V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_OBJECT_9( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } -#define DELEGATE_TO_OBJECT_9V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } -#define DELEGATE_TO_OBJECT_11V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, ArgType10, ArgType11, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9, ArgType10 a10, ArgType11 a11 ) { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 ); } - -#define DELEGATE_TO_OBJECT_0C( RetType, FuncName, pDelegated ) RetType FuncName() const { return (pDelegated)->FuncName(); } -#define DELEGATE_TO_OBJECT_0VC( FuncName, pDelegated ) void FuncName() const { (pDelegated)->FuncName(); } -#define DELEGATE_TO_OBJECT_1C( RetType, FuncName, ArgType1, pDelegated ) RetType FuncName( ArgType1 a1 ) const { return (pDelegated)->FuncName( a1 ); } -#define DELEGATE_TO_OBJECT_1VC( FuncName, ArgType1, pDelegated ) void FuncName( ArgType1 a1 ) const { (pDelegated)->FuncName( a1 ); } -#define DELEGATE_TO_OBJECT_2C( RetType, FuncName, ArgType1, ArgType2, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2 ) const { return (pDelegated)->FuncName( a1, a2 ); } -#define DELEGATE_TO_OBJECT_2VC( FuncName, ArgType1, ArgType2, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2 ) const { (pDelegated)->FuncName( a1, a2 ); } -#define DELEGATE_TO_OBJECT_3C( RetType, FuncName, ArgType1, ArgType2, ArgType3, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) const { return (pDelegated)->FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_OBJECT_3VC( FuncName, ArgType1, ArgType2, ArgType3, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) const { (pDelegated)->FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_OBJECT_4C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_OBJECT_4VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) const { (pDelegated)->FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_OBJECT_5C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_OBJECT_5VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) const { (pDelegated)->FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_OBJECT_6C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_OBJECT_6VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) const { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_OBJECT_7C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_OBJECT_7VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) const { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_OBJECT_8C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_OBJECT_8VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) const { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_OBJECT_9C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, pDelegated ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) const { return (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } -#define DELEGATE_TO_OBJECT_9VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, pDelegated ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) const { (pDelegated)->FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } - -#define DELEGATE_TO_BASE_0( RetType, FuncName, BaseClass ) RetType FuncName() { return BaseClass::FuncName(); } -#define DELEGATE_TO_BASE_0V( FuncName, BaseClass ) void FuncName() { BaseClass::FuncName(); } -#define DELEGATE_TO_BASE_1( RetType, FuncName, ArgType1, BaseClass ) RetType FuncName( ArgType1 a1 ) { return BaseClass::FuncName( a1 ); } -#define DELEGATE_TO_BASE_1V( FuncName, ArgType1, BaseClass ) void FuncName( ArgType1 a1 ) { BaseClass::FuncName( a1 ); } -#define DELEGATE_TO_BASE_2( RetType, FuncName, ArgType1, ArgType2, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2 ) { return BaseClass::FuncName( a1, a2 ); } -#define DELEGATE_TO_BASE_2V( FuncName, ArgType1, ArgType2, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2 ) { BaseClass::FuncName( a1, a2 ); } -#define DELEGATE_TO_BASE_3( RetType, FuncName, ArgType1, ArgType2, ArgType3, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) { return BaseClass::FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_BASE_3V( FuncName, ArgType1, ArgType2, ArgType3, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) { BaseClass::FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_BASE_4( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) { return BaseClass::FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_BASE_4V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) { BaseClass::FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_BASE_5( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) { return BaseClass::FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_BASE_5V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) { BaseClass::FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_BASE_6( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_BASE_6V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) { BaseClass::FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_BASE_7( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_BASE_7V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_BASE_8( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_BASE_8V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_BASE_9( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } -#define DELEGATE_TO_BASE_9V( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } - -#define DELEGATE_TO_BASE_0C( RetType, FuncName, BaseClass ) RetType FuncName() const { return BaseClass::FuncName(); } -#define DELEGATE_TO_BASE_0VC( FuncName, BaseClass ) void FuncName() const { BaseClass::FuncName(); } -#define DELEGATE_TO_BASE_1C( RetType, FuncName, ArgType1, BaseClass ) RetType FuncName( ArgType1 a1 ) const { return BaseClass::FuncName( a1 ); } -#define DELEGATE_TO_BASE_1VC( FuncName, ArgType1, BaseClass ) void FuncName( ArgType1 a1 ) const { BaseClass::FuncName( a1 ); } -#define DELEGATE_TO_BASE_2C( RetType, FuncName, ArgType1, ArgType2, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2 ) const { return BaseClass::FuncName( a1, a2 ); } -#define DELEGATE_TO_BASE_2VC( FuncName, ArgType1, ArgType2, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2 ) const { BaseClass::FuncName( a1, a2 ); } -#define DELEGATE_TO_BASE_3C( RetType, FuncName, ArgType1, ArgType2, ArgType3, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) const { return BaseClass::FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_BASE_3VC( FuncName, ArgType1, ArgType2, ArgType3, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3 ) const { BaseClass::FuncName( a1, a2, a3 ); } -#define DELEGATE_TO_BASE_4C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) const { return BaseClass::FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_BASE_4VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4 ) const { BaseClass::FuncName( a1, a2, a3, a4 ); } -#define DELEGATE_TO_BASE_5C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) const { return BaseClass::FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_BASE_5VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5 ) const { BaseClass::FuncName( a1, a2, a3, a4, a5 ); } -#define DELEGATE_TO_BASE_6C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) const { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_BASE_6VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6 ) const { BaseClass::FuncName( a1, a2, a3, a4, a5, a6 ); } -#define DELEGATE_TO_BASE_7C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) const { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_BASE_7VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 ) const { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7 ); } -#define DELEGATE_TO_BASE_8C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) const { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_BASE_8VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8 ) const { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8 ); } -#define DELEGATE_TO_BASE_9C( RetType, FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, BaseClass ) RetType FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) const { return BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } -#define DELEGATE_TO_BASE_9VC( FuncName, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8, ArgType9, BaseClass ) void FuncName( ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7, ArgType8 a8, ArgType9 a9 ) const { BaseClass::FuncName( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); } - -#endif // DELEGATES_H diff --git a/Resources/NetHook/tier1/diff.cpp b/Resources/NetHook/tier1/diff.cpp deleted file mode 100644 index 8951193c..00000000 --- a/Resources/NetHook/tier1/diff.cpp +++ /dev/null @@ -1,547 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier1/diff.h" -#include "mathlib/mathlib.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -// format of diff output: -// 0NN (N=1..127) copy next N literaly -// -// 1NN (N=1..127) ofs (-128..127) copy next N bytes from original, changin offset by N bytes from -// last copy end -// 100 N ofs(-32768..32767) copy next N, with larger delta offset -// 00 NNNN(1..65535) ofs(-32768..32767) big copy from old -// 80 00 NN NN NN big raw copy -// -// available codes (could be used for additonal compression ops) -// long offset form whose offset could have fit in short offset - -// note - this algorithm uses storage equal to 8* the old buffer size. 64k=.5mb - - -#define MIN_MATCH_LEN 8 -#define ACCEPTABLE_MATCH_LEN 4096 - -struct BlockPtr -{ - BlockPtr *Next; - uint8 const *dataptr; -}; - -template static inline void AddToHead(T * & head, V * node) -{ - node->Next=head; - head=node; -} - -void Fail(char const *msg) -{ - Assert(0); -} - -void ApplyDiffs(uint8 const *OldBlock, uint8 const *DiffList, - int OldSize, int DiffListSize, int &ResultListSize,uint8 *Output,uint32 OutSize) -{ - uint8 const *copy_src=OldBlock; - uint8 const *end_of_diff_list=DiffList+DiffListSize; - uint8 const *obuf=Output; - while(DiffList32767) - copy_ofs|=0xffff0000; - // printf("long cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList+=4; - } - else - { - if (op & 0x80) - { - int copy_sz=op & 0x7f; - int copy_ofs; - if (copy_sz==0) - { - copy_sz=DiffList[0]; - if (copy_sz==0) - { - // big raw copy - copy_sz=DiffList[1]+256*DiffList[2]+65536*DiffList[3]; - memcpy(Output,DiffList+4,copy_sz); - // printf("big rawcopy to %x len=%d\n", Output-obuf,copy_sz); - - DiffList+=copy_sz+4; - Output+=copy_sz; - } - else - { - copy_ofs=DiffList[1]+(DiffList[2]*256); - if (copy_ofs>32767) - copy_ofs|=0xffff0000; - // printf("long ofs cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList+=3; - } - } - else - { - copy_ofs=DiffList[0]; - if (copy_ofs>127) - copy_ofs|=0xffffff80; - // printf("cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList++; - } - } - else - { - // printf("raw copy %d to %x\n",op & 127,Output-obuf); - memcpy(Output,DiffList,op & 127); - Output+=op & 127; - DiffList+=(op & 127); - } - } - } - ResultListSize=Output-obuf; - -} - -static void CopyPending(int len, uint8 const *rawbytes,uint8 * &outbuf, uint8 const *limit) -{ -// printf("copy raw len=%d\n",len); - if (len<128) - { - if (limit-outbuf < len+1) - Fail("diff buffer overrun"); - *(outbuf++)=len; - memcpy(outbuf,rawbytes,len); - outbuf+=len; - } - else - { - if (limit-outbuf < len+5) - Fail("diff buffer overrun"); - *(outbuf++)=0x80; - *(outbuf++)=0x00; - *(outbuf++)=(len & 255); - *(outbuf++)=((len>>8) & 255); - *(outbuf++)=((len>>16) & 255); - memcpy(outbuf,rawbytes,len); - outbuf+=len; - } -} - -static uint32 hasher(uint8 const *mdata) -{ - // attempt to scramble the bits of h1 and h2 together - uint32 ret=0; - for(int i=0;idataptr=walk; - AddToHead(HashedMatches[hash1],newnode); - walk++; - } - else - ret=1; - // now, we have the hash table which may be used to search. begin the output step - int pending_raw_len=0; - walk=NewBlock; - uint8 *outbuf=Output; - uint8 const *lastmatchend=OldBlock; - while(walkMIN_MATCH_LEN, take it - for(BlockPtr *b=HashedMatches[hash1];b;b=b->Next) - { - // find the match length - int match_of=b->dataptr-lastmatchend; - if ((match_of>-32768) && (match_of<32767)) - { - int max_mlength=min(65535,OldBlock+OldSize-b->dataptr); - max_mlength=min(max_mlength,NewBlock+NewSize-walk); - int i; - for(i=0;idataptr[i]) - break; - if ((i>MIN_MATCH_LEN) && (i>longest)) - { - longest=i; - longest_block=b; - if (longest>ACCEPTABLE_MATCH_LEN) - break; - } - } - } - } - // now, we have a match maybe - if (longest_block) - { - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - // now, output copy block - int match_of=longest_block->dataptr-lastmatchend; - int nremaining=OutSize-(outbuf-Output); - - if (match_of) - ret=1; -// printf("copy from %x to %x len=%d\n", match_of,outbuf-Output,longest); - if (longest>127) - { - // use really long encoding - if (nremaining<5) - Fail("diff buff needs increase"); - *(outbuf++)=00; - *(outbuf++)=(longest & 255); - *(outbuf++)=((longest>>8) & 255); - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - - } - else - { - if ((match_of>=-128) && (match_of<128)) - { - if (nremaining<2) - Fail("diff buff needs increase"); - *(outbuf++)=128+longest; - *(outbuf++)=(match_of&255); - } - else - { - // use long encoding - if (nremaining<4) - Fail("diff buff needs increase"); - *(outbuf++)=0x80; - *(outbuf++)=longest; - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - } - } - lastmatchend=longest_block->dataptr+longest; - walk+=longest; - } - else - { - walk++; - pending_raw_len++; - } - } - // now, flush pending raw copy - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - delete[] HashedMatches; - if (Blocks) - delete[] Blocks; - DiffListSize=outbuf-Output; - return ret; -} - - -int FindDiffs(uint8 const *NewBlock, uint8 const *OldBlock, - int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize) -{ - - int ret=0; - if (OldSize!=NewSize) - ret=1; - // first, build the hash table - BlockPtr *HashedMatches[65536]; - memset(HashedMatches,0,sizeof(HashedMatches)); - BlockPtr *Blocks=0; - if (OldSize) - Blocks=new BlockPtr[OldSize]; - BlockPtr *FreeList=Blocks; - // now, build the hash table - uint8 const *walk=OldBlock; - if (OldBlock && OldSize) - while(walkdataptr=walk; - AddToHead(HashedMatches[hash1],newnode); - walk++; - } - else - ret=1; - // now, we have the hash table which may be used to search. begin the output step - int pending_raw_len=0; - walk=NewBlock; - uint8 *outbuf=Output; - uint8 const *lastmatchend=OldBlock; - while(walkMIN_MATCH_LEN, take it - for(BlockPtr *b=HashedMatches[hash1];b;b=b->Next) - { - // find the match length - int match_of=b->dataptr-lastmatchend; - if ((match_of>-32768) && (match_of<32767)) - { - int max_mlength=min(65535,OldBlock+OldSize-b->dataptr); - max_mlength=min(max_mlength,NewBlock+NewSize-walk); - int i; - for(i=0;idataptr[i]) - break; - if ((i>MIN_MATCH_LEN) && (i>longest)) - { - longest=i; - longest_block=b; - } - } - } - } - // now, we have a match maybe - if (longest_block) - { - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - // now, output copy block - int match_of=longest_block->dataptr-lastmatchend; - int nremaining=OutSize-(outbuf-Output); - if (match_of) - ret=1; - if (longest>127) - { - // use really long encoding - if (nremaining<5) - Fail("diff buff needs increase"); - *(outbuf++)=00; - *(outbuf++)=(longest & 255); - *(outbuf++)=((longest>>8) & 255); - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - } - else - { - if ((match_of>=-128) && (match_of<128)) - { - if (nremaining<2) - Fail("diff buff needs increase"); - *(outbuf++)=128+longest; - *(outbuf++)=(match_of&255); - } - else - { - // use long encoding - if (nremaining<4) - Fail("diff buff needs increase"); - *(outbuf++)=0x80; - *(outbuf++)=longest; - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - } - } - lastmatchend=longest_block->dataptr+longest; - walk+=longest; - } - else - { - walk++; - pending_raw_len++; - } - } - // now, flush pending raw copy - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - if (Blocks) - delete[] Blocks; - DiffListSize=outbuf-Output; - return ret; -} - - -int FindDiffsLowMemory(uint8 const *NewBlock, uint8 const *OldBlock, - int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize) -{ - - int ret=0; - if (OldSize!=NewSize) - ret=1; - uint8 const *old_data_hash[256]; - memset(old_data_hash,0,sizeof(old_data_hash)); - int pending_raw_len=0; - uint8 const *walk=NewBlock; - uint8 const *oldptr=OldBlock; - uint8 *outbuf=Output; - uint8 const *lastmatchend=OldBlock; - while(walkMIN_MATCH_LEN) - { - longest_block=old_data_hash[hash1]; - longest=nmatches; - } - } - } - // now, we have a match maybe - if (longest_block) - { - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - // now, output copy block - int match_of=longest_block-lastmatchend; - int nremaining=OutSize-(outbuf-Output); - if (match_of) - ret=1; - if (longest>127) - { - // use really long encoding - if (nremaining<5) - Fail("diff buff needs increase"); - *(outbuf++)=00; - *(outbuf++)=(longest & 255); - *(outbuf++)=((longest>>8) & 255); - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - } - else - { - if ((match_of>=-128) && (match_of<128)) - { - if (nremaining<2) - Fail("diff buff needs increase"); - *(outbuf++)=128+longest; - *(outbuf++)=(match_of&255); - } - else - { - // use long encoding - if (nremaining<4) - Fail("diff buff needs increase"); - *(outbuf++)=0x80; - *(outbuf++)=longest; - *(outbuf++)=(match_of & 255); - *(outbuf++)=((match_of>>8) & 255); - } - } - lastmatchend=longest_block+longest; - walk+=longest; - } - else - { - walk++; - pending_raw_len++; - } - } - // now, flush pending raw copy - if (pending_raw_len) // must output - { - ret=1; - CopyPending(pending_raw_len,walk-pending_raw_len,outbuf,Output+OutSize); - pending_raw_len=0; - } - DiffListSize=outbuf-Output; - return ret; -} - - diff --git a/Resources/NetHook/tier1/diff.h b/Resources/NetHook/tier1/diff.h deleted file mode 100644 index 3828d1be..00000000 --- a/Resources/NetHook/tier1/diff.h +++ /dev/null @@ -1,29 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -// Serialization/unserialization buffer -//=============================================================================// - -#ifndef DIFF_H -#define DIFF_H -#pragma once - -int FindDiffs(uint8 const *NewBlock, uint8 const *OldBlock, - int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize); - -int FindDiffsForLargeFiles(uint8 const *NewBlock, uint8 const *OldBlock, - int NewSize, int OldSize, int &DiffListSize,uint8 *Output, - uint32 OutSize, - int hashsize=65536); - -void ApplyDiffs(uint8 const *OldBlock, uint8 const *DiffList, - int OldSize, int DiffListSize, int &ResultListSize,uint8 *Output,uint32 OutSize); - -int FindDiffsLowMemory(uint8 const *NewBlock, uint8 const *OldBlock, - int NewSize, int OldSize, int &DiffListSize,uint8 *Output,uint32 OutSize); - -#endif - diff --git a/Resources/NetHook/tier1/fmtstr.h b/Resources/NetHook/tier1/fmtstr.h deleted file mode 100644 index 50d9f9f2..00000000 --- a/Resources/NetHook/tier1/fmtstr.h +++ /dev/null @@ -1,82 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: A simple class for performing safe and in-expression sprintf-style -// string formatting -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef FMTSTR_H -#define FMTSTR_H - -#include -#include -#include "tier0/platform.h" -#include "tier1/strtools.h" - -#if defined( _WIN32 ) -#pragma once -#endif - -//============================================================================= - -// using macro to be compatable with GCC -#define FmtStrVSNPrintf( szBuf, nBufSize, ppszFormat ) \ - do \ - { \ - int result; \ - va_list arg_ptr; \ - \ - va_start(arg_ptr, (*(ppszFormat))); \ - result = Q_vsnprintf((szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr); \ - va_end(arg_ptr); \ - \ - (szBuf)[(nBufSize)-1] = 0; \ - } \ - while (0) - -//----------------------------------------------------------------------------- -// -// Purpose: String formatter with specified size -// - -template -class CFmtStrN -{ -public: - CFmtStrN() { m_szBuf[0] = 0; } - - // Standard C formatting - CFmtStrN(const char *pszFormat, ...) { FmtStrVSNPrintf(m_szBuf, SIZE_BUF, &pszFormat); } - - // Use this for pass-through formatting - CFmtStrN(const char ** ppszFormat, ...) { FmtStrVSNPrintf(m_szBuf, SIZE_BUF, ppszFormat); } - - // Explicit reformat - const char *sprintf(const char *pszFormat, ...) { FmtStrVSNPrintf(m_szBuf, SIZE_BUF, &pszFormat); return m_szBuf; } - - // Use this for pass-through formatting - void VSprintf(const char **ppszFormat, ...) { FmtStrVSNPrintf(m_szBuf, SIZE_BUF, ppszFormat); } - - // Use for access - operator const char *() const { return m_szBuf; } - char *Access() { return m_szBuf; } - - void Clear() { m_szBuf[0] = 0; } - -private: - char m_szBuf[SIZE_BUF]; -}; - -//----------------------------------------------------------------------------- -// -// Purpose: Default-sized string formatter -// - -#define FMTSTR_STD_LEN 256 - -typedef CFmtStrN CFmtStr; - -//============================================================================= - -#endif // FMTSTR_H diff --git a/Resources/NetHook/tier1/functors.h b/Resources/NetHook/tier1/functors.h deleted file mode 100644 index 3619310a..00000000 --- a/Resources/NetHook/tier1/functors.h +++ /dev/null @@ -1,617 +0,0 @@ -//========== Copyright © 2006, Valve Corporation, All rights reserved. ======== -// -// Purpose: Implements a generic infrastucture for functors combining -// a number of techniques to provide transparent parameter type -// deduction and packaging. Supports both member and non-member functions. -// -// See also: http://en.wikipedia.org/wiki/Function_object -// -// Note that getting into the guts of this file is not for the -// feint of heart. The core concept here is that the compiler can -// figure out all the parameter types. -// -// E.g.: -// -// struct CMyClass -// { -// void foo( int i) {} -// }; -// -// int bar(int i) { return i; } -// -// CMyClass myInstance; -// -// CFunctor *pFunctor = CreateFunctor( &myInstance, CMyClass::foo, 8675 ); -// CFunctor *pFunctor2 = CreateFunctor( &bar, 309 ); -// -// void CallEm() -// { -// (*pFunctor)(); -// (*pFunctor2)(); -// } -// -//============================================================================= - -#ifndef FUNCTORS_H -#define FUNCTORS_H - -#include "tier0/platform.h" -#include "tier1/refcount.h" -#include "tier1/utlenvelope.h" - -#if defined( _WIN32 ) -#pragma once -#endif - -//----------------------------------------------------------------------------- -// -// Macros used as basis for template generation. Just ignore the man behind the -// curtain -// -//----------------------------------------------------------------------------- - -#define FUNC_TEMPLATE_ARG_PARAMS_0 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_0 -#define FUNC_ARG_MEMBERS_0 -#define FUNC_ARG_FORMAL_PARAMS_0 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_0 -#define FUNC_CALL_ARGS_INIT_0 -#define FUNC_CALL_MEMBER_ARGS_0 -#define FUNC_CALL_ARGS_0 -#define FUNC_FUNCTOR_CALL_ARGS_0 -#define FUNC_TEMPLATE_FUNC_PARAMS_0 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_0 - -#define FUNC_TEMPLATE_ARG_PARAMS_1 , typename ARG_TYPE_1 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_1 , ARG_TYPE_1 -#define FUNC_ARG_MEMBERS_1 ARG_TYPE_1 m_arg1 -#define FUNC_ARG_FORMAL_PARAMS_1 , const ARG_TYPE_1 &arg1 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_1 const ARG_TYPE_1 &arg1 -#define FUNC_CALL_ARGS_INIT_1 , m_arg1( arg1 ) -#define FUNC_CALL_MEMBER_ARGS_1 m_arg1 -#define FUNC_CALL_ARGS_1 arg1 -#define FUNC_FUNCTOR_CALL_ARGS_1 , arg1 -#define FUNC_TEMPLATE_FUNC_PARAMS_1 , typename FUNC_ARG_TYPE_1 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_1 FUNC_ARG_TYPE_1 - -#define FUNC_TEMPLATE_ARG_PARAMS_2 , typename ARG_TYPE_1, typename ARG_TYPE_2 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_2 , ARG_TYPE_1, ARG_TYPE_2 -#define FUNC_ARG_MEMBERS_2 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2 -#define FUNC_ARG_FORMAL_PARAMS_2 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_2 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2 -#define FUNC_CALL_ARGS_INIT_2 , m_arg1( arg1 ), m_arg2( arg2 ) -#define FUNC_CALL_MEMBER_ARGS_2 m_arg1, m_arg2 -#define FUNC_CALL_ARGS_2 arg1, arg2 -#define FUNC_FUNCTOR_CALL_ARGS_2 , arg1, arg2 -#define FUNC_TEMPLATE_FUNC_PARAMS_2 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_2 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2 - -#define FUNC_TEMPLATE_ARG_PARAMS_3 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_3 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3 -#define FUNC_ARG_MEMBERS_3 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3 -#define FUNC_ARG_FORMAL_PARAMS_3 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_3 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3 -#define FUNC_CALL_ARGS_INIT_3 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ) -#define FUNC_CALL_MEMBER_ARGS_3 m_arg1, m_arg2, m_arg3 -#define FUNC_CALL_ARGS_3 arg1, arg2, arg3 -#define FUNC_FUNCTOR_CALL_ARGS_3 , arg1, arg2, arg3 -#define FUNC_TEMPLATE_FUNC_PARAMS_3 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_3 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3 - -#define FUNC_TEMPLATE_ARG_PARAMS_4 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_4 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4 -#define FUNC_ARG_MEMBERS_4 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4 -#define FUNC_ARG_FORMAL_PARAMS_4 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_4 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4 -#define FUNC_CALL_ARGS_INIT_4 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ) -#define FUNC_CALL_MEMBER_ARGS_4 m_arg1, m_arg2, m_arg3, m_arg4 -#define FUNC_CALL_ARGS_4 arg1, arg2, arg3, arg4 -#define FUNC_FUNCTOR_CALL_ARGS_4 , arg1, arg2, arg3, arg4 -#define FUNC_TEMPLATE_FUNC_PARAMS_4 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_4 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4 - -#define FUNC_TEMPLATE_ARG_PARAMS_5 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_5 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5 -#define FUNC_ARG_MEMBERS_5 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5 -#define FUNC_ARG_FORMAL_PARAMS_5 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_5 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5 -#define FUNC_CALL_ARGS_INIT_5 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ) -#define FUNC_CALL_MEMBER_ARGS_5 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5 -#define FUNC_CALL_ARGS_5 arg1, arg2, arg3, arg4, arg5 -#define FUNC_FUNCTOR_CALL_ARGS_5 , arg1, arg2, arg3, arg4, arg5 -#define FUNC_TEMPLATE_FUNC_PARAMS_5 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_5 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5 - -#define FUNC_TEMPLATE_ARG_PARAMS_6 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_6 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6 -#define FUNC_ARG_MEMBERS_6 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6 -#define FUNC_ARG_FORMAL_PARAMS_6 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_6 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6 -#define FUNC_CALL_ARGS_INIT_6 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ) -#define FUNC_CALL_MEMBER_ARGS_6 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6 -#define FUNC_CALL_ARGS_6 arg1, arg2, arg3, arg4, arg5, arg6 -#define FUNC_FUNCTOR_CALL_ARGS_6 , arg1, arg2, arg3, arg4, arg5, arg6 -#define FUNC_TEMPLATE_FUNC_PARAMS_6 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_6 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6 - -#define FUNC_TEMPLATE_ARG_PARAMS_7 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_7 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7 -#define FUNC_ARG_MEMBERS_7 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; -#define FUNC_ARG_FORMAL_PARAMS_7 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_7 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7 -#define FUNC_CALL_ARGS_INIT_7 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ) -#define FUNC_CALL_MEMBER_ARGS_7 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7 -#define FUNC_CALL_ARGS_7 arg1, arg2, arg3, arg4, arg5, arg6, arg7 -#define FUNC_FUNCTOR_CALL_ARGS_7 , arg1, arg2, arg3, arg4, arg5, arg6, arg7 -#define FUNC_TEMPLATE_FUNC_PARAMS_7 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_7 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7 - -#define FUNC_TEMPLATE_ARG_PARAMS_8 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_8 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8 -#define FUNC_ARG_MEMBERS_8 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; -#define FUNC_ARG_FORMAL_PARAMS_8 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_8 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8 -#define FUNC_CALL_ARGS_INIT_8 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ) -#define FUNC_CALL_MEMBER_ARGS_8 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8 -#define FUNC_CALL_ARGS_8 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 -#define FUNC_FUNCTOR_CALL_ARGS_8 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 -#define FUNC_TEMPLATE_FUNC_PARAMS_8 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_8 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8 - -#define FUNC_TEMPLATE_ARG_PARAMS_9 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_9 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9 -#define FUNC_ARG_MEMBERS_9 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; -#define FUNC_ARG_FORMAL_PARAMS_9 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_9 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9 -#define FUNC_CALL_ARGS_INIT_9 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ) -#define FUNC_CALL_MEMBER_ARGS_9 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9 -#define FUNC_CALL_ARGS_9 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 -#define FUNC_FUNCTOR_CALL_ARGS_9 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 -#define FUNC_TEMPLATE_FUNC_PARAMS_9 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_9 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9 - -#define FUNC_TEMPLATE_ARG_PARAMS_10 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_10 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10 -#define FUNC_ARG_MEMBERS_10 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; -#define FUNC_ARG_FORMAL_PARAMS_10 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_10 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10 -#define FUNC_CALL_ARGS_INIT_10 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ) -#define FUNC_CALL_MEMBER_ARGS_10 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10 -#define FUNC_CALL_ARGS_10 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 -#define FUNC_FUNCTOR_CALL_ARGS_10 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 -#define FUNC_TEMPLATE_FUNC_PARAMS_10 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_10 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10 - -#define FUNC_TEMPLATE_ARG_PARAMS_11 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_11 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11 -#define FUNC_ARG_MEMBERS_11 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11 -#define FUNC_ARG_FORMAL_PARAMS_11 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_11 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11 -#define FUNC_CALL_ARGS_INIT_11 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ) -#define FUNC_CALL_MEMBER_ARGS_11 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11 -#define FUNC_CALL_ARGS_11 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 -#define FUNC_FUNCTOR_CALL_ARGS_11 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 -#define FUNC_TEMPLATE_FUNC_PARAMS_11 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_11 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11 - -#define FUNC_TEMPLATE_ARG_PARAMS_12 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_12 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12 -#define FUNC_ARG_MEMBERS_12 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12 -#define FUNC_ARG_FORMAL_PARAMS_12 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_12 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12 -#define FUNC_CALL_ARGS_INIT_12 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ) -#define FUNC_CALL_MEMBER_ARGS_12 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12 -#define FUNC_CALL_ARGS_12 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 -#define FUNC_FUNCTOR_CALL_ARGS_12 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 -#define FUNC_TEMPLATE_FUNC_PARAMS_12 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_12 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12 - -#define FUNC_TEMPLATE_ARG_PARAMS_13 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_13 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13 -#define FUNC_ARG_MEMBERS_13 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12; ARG_TYPE_13 m_arg13 -#define FUNC_ARG_FORMAL_PARAMS_13 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_13 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13 -#define FUNC_CALL_ARGS_INIT_13 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 ) -#define FUNC_CALL_MEMBER_ARGS_13 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13 -#define FUNC_CALL_ARGS_13 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13 -#define FUNC_FUNCTOR_CALL_ARGS_13 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13 -#define FUNC_TEMPLATE_FUNC_PARAMS_13 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12, typename FUNC_ARG_TYPE_13 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_13 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12, FUNC_ARG_TYPE_13 - -#define FUNC_TEMPLATE_ARG_PARAMS_14 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13, typename ARG_TYPE_14 -#define FUNC_BASE_TEMPLATE_ARG_PARAMS_14 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13, ARG_TYPE_14 -#define FUNC_ARG_MEMBERS_14 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12; ARG_TYPE_13 m_arg13; ARG_TYPE_14 m_arg14 -#define FUNC_ARG_FORMAL_PARAMS_14 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13, const ARG_TYPE_14 &arg14 -#define FUNC_PROXY_ARG_FORMAL_PARAMS_14 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13, const ARG_TYPE_14 &arg14 -#define FUNC_CALL_ARGS_INIT_14 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 ), m_arg14( arg14 ) -#define FUNC_CALL_MEMBER_ARGS_14 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14 -#define FUNC_CALL_ARGS_14 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 -#define FUNC_FUNCTOR_CALL_ARGS_14 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 -#define FUNC_TEMPLATE_FUNC_PARAMS_14 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12, typename FUNC_ARG_TYPE_13, typename FUNC_ARG_TYPE_14 -#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_14 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12, FUNC_ARG_TYPE_13, FUNC_ARG_TYPE_14 - -#define FUNC_GENERATE_ALL( INNERMACRONAME ) \ - INNERMACRONAME(0); \ - INNERMACRONAME(1); \ - INNERMACRONAME(2); \ - INNERMACRONAME(3); \ - INNERMACRONAME(4); \ - INNERMACRONAME(5); \ - INNERMACRONAME(6); \ - INNERMACRONAME(7); \ - INNERMACRONAME(8); \ - INNERMACRONAME(9); \ - INNERMACRONAME(10);\ - INNERMACRONAME(11);\ - INNERMACRONAME(12);\ - INNERMACRONAME(13);\ - INNERMACRONAME(14) - -//----------------------------------------------------------------------------- -// -// Purpose: Base class of all function objects -// -//----------------------------------------------------------------------------- - -abstract_class CFunctor : public IRefCounted -{ -public: - CFunctor() - { -#ifdef DEBUG - m_nUserID = 0; -#endif - } - virtual void operator()() = 0; - - unsigned m_nUserID; // For debugging -}; - - -//----------------------------------------------------------------------------- -// When calling through a functor, care needs to be taken to not pass objects that might go away. -// Since this code determines the type to store in the functor based on the actual arguments, -// this is achieved by changing the point of call. -// -// See also CUtlEnvelope -//----------------------------------------------------------------------------- - -// convert a reference to a passable value -template -inline T RefToVal(const T &item) -{ - return item; -} - -//----------------------------------------------------------------------------- -// This class can be used to pass into a functor a proxy object for a pointer -// to be resolved later. For example, you can execute a "call" on a resource -// whose actual value is not known until a later time -//----------------------------------------------------------------------------- - -template -class CLateBoundPtr -{ -public: - CLateBoundPtr( T **ppObject ) - : m_ppObject( ppObject ) - { - } - - T *operator->() { return *m_ppObject; } - T &operator *() { return **m_ppObject; } - operator T *() const { return (T*)(*m_ppObject); } - operator void *() { return *m_ppObject; } - -private: - T **m_ppObject; -}; - -//----------------------------------------------------------------------------- -// -// Purpose: Classes to define memory management policies when operating -// on pointers to members -// -//----------------------------------------------------------------------------- - -class CFuncMemPolicyNone -{ -public: - static void OnAcquire(void *pObject) {} - static void OnRelease(void *pObject) {} -}; - -template -class CFuncMemPolicyRefCount -{ -public: - static void OnAcquire(OBJECT_TYPE_PTR pObject) { pObject->AddRef(); } - static void OnRelease(OBJECT_TYPE_PTR pObject) { pObject->Release(); } -}; - -//----------------------------------------------------------------------------- -// -// Purpose: Function proxy is a generic facility for holding a function -// pointer. Can be used on own, though primarily for use -// by this file -// -//----------------------------------------------------------------------------- - -template -class CMemberFuncProxyBase -{ -protected: - CMemberFuncProxyBase( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied ) - : m_pObject( pObject ), - m_pfnProxied( pfnProxied ) - { - MEM_POLICY::OnAcquire(m_pObject); - } - - ~CMemberFuncProxyBase() - { - MEM_POLICY::OnRelease(m_pObject); - } - - void Set( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied ) - { - m_pfnProxied = pfnProxied; - m_pObject = pObject; - } - - void OnCall() - { - Assert( (void *)m_pObject != NULL ); - } - - FUNCTION_TYPE m_pfnProxied; - OBJECT_TYPE_PTR m_pObject; -}; - - -#define DEFINE_MEMBER_FUNC_PROXY( N ) \ - template \ - class CMemberFuncProxy##N : public CMemberFuncProxyBase \ - { \ - public: \ - CMemberFuncProxy##N( OBJECT_TYPE_PTR pObject = NULL, FUNCTION_TYPE pfnProxied = NULL ) \ - : CMemberFuncProxyBase( pObject, pfnProxied ) \ - { \ - } \ - \ - void operator()( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \ - { \ - this->OnCall(); \ - ((*this->m_pObject).*this->m_pfnProxied)( FUNC_CALL_ARGS_##N ); \ - } \ - } - -FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_PROXY ); - - -//----------------------------------------------------------------------------- -// -// The actual functor implementation -// -//----------------------------------------------------------------------------- - -#include "tier0/memdbgon.h" - -typedef CRefCounted1 CFunctorBase; - -#define DEFINE_FUNCTOR_TEMPLATE(N) \ - template \ - class CFunctor##N : public CFunctorBase \ - { \ - public: \ - CFunctor##N( FUNC_TYPE pfnProxied FUNC_ARG_FORMAL_PARAMS_##N ) : m_pfnProxied( pfnProxied ) FUNC_CALL_ARGS_INIT_##N {} \ - void operator()() { m_pfnProxied(FUNC_CALL_MEMBER_ARGS_##N); } \ - \ - private: \ - FUNC_TYPE m_pfnProxied; \ - FUNC_ARG_MEMBERS_##N; \ - } - -FUNC_GENERATE_ALL( DEFINE_FUNCTOR_TEMPLATE ); - -#define DEFINE_MEMBER_FUNCTOR( N ) \ - template \ - class CMemberFunctor##N : public FUNCTOR_BASE \ - { \ - public: \ - CMemberFunctor##N( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied FUNC_ARG_FORMAL_PARAMS_##N ) : m_Proxy( pObject, pfnProxied ) FUNC_CALL_ARGS_INIT_##N {} \ - void operator()() { m_Proxy(FUNC_CALL_MEMBER_ARGS_##N); } \ - \ - private: \ - CMemberFuncProxy##N m_Proxy; \ - FUNC_ARG_MEMBERS_##N; \ - }; - - -FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR ); - -//----------------------------------------------------------------------------- -// -// The real magic, letting the compiler figure out all the right template parameters -// -//----------------------------------------------------------------------------- - -#define DEFINE_NONMEMBER_FUNCTOR_FACTORY(N) \ - template \ - inline CFunctor *CreateFunctor(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ - return new CFunctor##N( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ); \ - } - -FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY ); - -//------------------------------------- - -#define DEFINE_MEMBER_FUNCTOR_FACTORY(N) \ -template \ -inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ -{ \ - return new CMemberFunctor##N(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ -} - -FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY ); - -//------------------------------------- - -#define DEFINE_CONST_MEMBER_FUNCTOR_FACTORY(N) \ - template \ - inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new CMemberFunctor##N(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - -FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY ); - -//------------------------------------- - -#define DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY(N) \ - template \ - inline CFunctor *CreateRefCountingFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new CMemberFunctor##N >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - -FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY ); - -//------------------------------------- - -#define DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY(N) \ - template \ - inline CFunctor *CreateRefCountingFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new CMemberFunctor##N >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - -FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY ); - -//----------------------------------------------------------------------------- -// -// Templates to assist early-out direct call code -// -//----------------------------------------------------------------------------- - -#define DEFINE_NONMEMBER_FUNCTOR_DIRECT(N) \ - template \ - inline void FunctorDirectCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ -{ \ - (*pfnProxied)( FUNC_CALL_ARGS_##N ); \ -} - -FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_DIRECT ); - - -//------------------------------------- - -#define DEFINE_MEMBER_FUNCTOR_DIRECT(N) \ - template \ - inline void FunctorDirectCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ -{ \ - ((*pObject).*pfnProxied)(FUNC_CALL_ARGS_##N); \ -} - -FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_DIRECT ); - -//------------------------------------- - -#define DEFINE_CONST_MEMBER_FUNCTOR_DIRECT(N) \ - template \ - inline void FunctorDirectCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ -{ \ - ((*pObject).*pfnProxied)(FUNC_CALL_ARGS_##N); \ -} - -FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_DIRECT ); - -#include "tier0/memdbgoff.h" - -//----------------------------------------------------------------------------- -// Factory class useable as templated traits -//----------------------------------------------------------------------------- - -class CDefaultFunctorFactory -{ -public: - FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY ); - FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY ); - FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY ); - FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY ); - FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY ); -}; - -template -class CCustomizedFunctorFactory -{ -public: - void SetAllocator( CAllocator *pAllocator ) - { - m_pAllocator = pAllocator; - } - - #define DEFINE_NONMEMBER_FUNCTOR_FACTORY_CUSTOM(N) \ - template \ - inline CFunctor *CreateFunctor( FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \ - return new (m_pAllocator->Alloc( sizeof(CFunctor##N) )) CFunctor##N( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ); \ - } - - FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY_CUSTOM ); - - //------------------------------------- - - #define DEFINE_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \ - template \ - inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N) )) CMemberFunctor##N(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - - FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY_CUSTOM ); - - //------------------------------------- - - #define DEFINE_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \ - template \ - inline CFunctor *CreateFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N) )) CMemberFunctor##N(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - - FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM ); - - //------------------------------------- - - #define DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \ - template \ - inline CFunctor *CreateRefCountingFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N >) )) CMemberFunctor##N >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - - FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY_CUSTOM ); - - //------------------------------------- - - #define DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \ - template \ - inline CFunctor *CreateRefCountingFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \ - { \ - return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N >) )) CMemberFunctor##N >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \ - } - - FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM ); - -private: - CAllocator *m_pAllocator; - -}; - -//----------------------------------------------------------------------------- - -#endif // FUNCTORS_H diff --git a/Resources/NetHook/tier1/generichash.cpp b/Resources/NetHook/tier1/generichash.cpp deleted file mode 100644 index af784fc4..00000000 --- a/Resources/NetHook/tier1/generichash.cpp +++ /dev/null @@ -1,303 +0,0 @@ -//======= Copyright © 2005, , Valve Corporation, All rights reserved. ========= -// -// Purpose: Variant Pearson Hash general purpose hashing algorithm described -// by Cargill in C++ Report 1994. Generates a 16-bit result. -// -//============================================================================= - -#include -#include "tier0/basetypes.h" -#include "tier0/platform.h" -#include "generichash.h" -#include - -//----------------------------------------------------------------------------- -// -// Table of randomly shuffled values from 0-255 generated by: -// -//----------------------------------------------------------------------------- -/* -void MakeRandomValues() -{ - int i, j, r; - unsigned t; - srand( 0xdeadbeef ); - - for ( i = 0; i < 256; i++ ) - { - g_nRandomValues[i] = (unsigned )i; - } - - for (j = 0; j < 8; j++) - { - for (i = 0; i < 256; i++) - { - r = rand() & 0xff; - t = g_nRandomValues[i]; - g_nRandomValues[i] = g_nRandomValues[r]; - g_nRandomValues[r] = t; - } - } - - printf("static unsigned g_nRandomValues[256] =\n{\n"); - - for (i = 0; i < 256; i += 16) - { - printf("\t"); - for (j = 0; j < 16; j++) - printf(" %3d,", g_nRandomValues[i+j]); - printf("\n"); - } - printf("};\n"); -} -*/ - -static unsigned g_nRandomValues[256] = -{ - 238, 164, 191, 168, 115, 16, 142, 11, 213, 214, 57, 151, 248, 252, 26, 198, - 13, 105, 102, 25, 43, 42, 227, 107, 210, 251, 86, 66, 83, 193, 126, 108, - 131, 3, 64, 186, 192, 81, 37, 158, 39, 244, 14, 254, 75, 30, 2, 88, - 172, 176, 255, 69, 0, 45, 116, 139, 23, 65, 183, 148, 33, 46, 203, 20, - 143, 205, 60, 197, 118, 9, 171, 51, 233, 135, 220, 49, 71, 184, 82, 109, - 36, 161, 169, 150, 63, 96, 173, 125, 113, 67, 224, 78, 232, 215, 35, 219, - 79, 181, 41, 229, 149, 153, 111, 217, 21, 72, 120, 163, 133, 40, 122, 140, - 208, 231, 211, 200, 160, 182, 104, 110, 178, 237, 15, 101, 27, 50, 24, 189, - 177, 130, 187, 92, 253, 136, 100, 212, 19, 174, 70, 22, 170, 206, 162, 74, - 247, 5, 47, 32, 179, 117, 132, 195, 124, 123, 245, 128, 236, 223, 12, 84, - 54, 218, 146, 228, 157, 94, 106, 31, 17, 29, 194, 34, 56, 134, 239, 246, - 241, 216, 127, 98, 7, 204, 154, 152, 209, 188, 48, 61, 87, 97, 225, 85, - 90, 167, 155, 112, 145, 114, 141, 93, 250, 4, 201, 156, 38, 89, 226, 196, - 1, 235, 44, 180, 159, 121, 119, 166, 190, 144, 10, 91, 76, 230, 221, 80, - 207, 55, 58, 53, 175, 8, 6, 52, 68, 242, 18, 222, 103, 249, 147, 129, - 138, 243, 28, 185, 62, 59, 240, 202, 234, 99, 77, 73, 199, 137, 95, 165, -}; - -//----------------------------------------------------------------------------- -// String -//----------------------------------------------------------------------------- -unsigned FASTCALL HashString( const char *pszKey ) -{ - const uint8 *k = (const uint8 *)pszKey; - unsigned even = 0, - odd = 0, - n; - - while ((n = *k++) != 0) - { - even = g_nRandomValues[odd ^ n]; - if ((n = *k++) != 0) - odd = g_nRandomValues[even ^ n]; - else - break; - } - - return (even << 8) | odd ; -} - - -//----------------------------------------------------------------------------- -// Case-insensitive string -//----------------------------------------------------------------------------- -unsigned FASTCALL HashStringCaseless( const char *pszKey ) -{ - const uint8 *k = (const uint8 *) pszKey; - unsigned even = 0, - odd = 0, - n; - - while ((n = toupper(*k++)) != 0) - { - even = g_nRandomValues[odd ^ n]; - if ((n = toupper(*k++)) != 0) - odd = g_nRandomValues[even ^ n]; - else - break; - } - - return (even << 8) | odd; -} - -//----------------------------------------------------------------------------- -// 32 bit conventional case-insensitive string -//----------------------------------------------------------------------------- -unsigned FASTCALL HashStringCaselessConventional( const char *pszKey ) -{ - unsigned hash = 0xAAAAAAAA; // Alternating 1's and 0's to maximize the effect of the later multiply and add - - for( ; *pszKey ; pszKey++ ) - { - hash = ( ( hash << 5 ) + hash ) + (uint8)tolower(*pszKey); - } - - return hash; -} - -//----------------------------------------------------------------------------- -// int hash -//----------------------------------------------------------------------------- -unsigned FASTCALL HashInt( const int n ) -{ - register unsigned even, odd; - even = g_nRandomValues[n & 0xff]; - odd = g_nRandomValues[((n >> 8) & 0xff)]; - - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - return (even << 8) | odd; -} - -//----------------------------------------------------------------------------- -// 4-byte hash -//----------------------------------------------------------------------------- -unsigned FASTCALL Hash4( const void *pKey ) -{ - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; - n = *p; - even = g_nRandomValues[n & 0xff]; - odd = g_nRandomValues[((n >> 8) & 0xff)]; - - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - return (even << 8) | odd; -} - - -//----------------------------------------------------------------------------- -// 8-byte hash -//----------------------------------------------------------------------------- -unsigned FASTCALL Hash8( const void *pKey ) -{ - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; - n = *p; - even = g_nRandomValues[n & 0xff]; - odd = g_nRandomValues[((n >> 8) & 0xff)]; - - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+1); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - return (even << 8) | odd; -} - - -//----------------------------------------------------------------------------- -// 12-byte hash -//----------------------------------------------------------------------------- -unsigned FASTCALL Hash12( const void *pKey ) -{ - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; - n = *p; - even = g_nRandomValues[n & 0xff]; - odd = g_nRandomValues[((n >> 8) & 0xff)]; - - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+1); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+2); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - return (even << 8) | odd; -} - - -//----------------------------------------------------------------------------- -// 16-byte hash -//----------------------------------------------------------------------------- -unsigned FASTCALL Hash16( const void *pKey ) -{ - register const uint32 * p = (const uint32 *) pKey; - register unsigned even, - odd, - n; - n = *p; - even = g_nRandomValues[n & 0xff]; - odd = g_nRandomValues[((n >> 8) & 0xff)]; - - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ (n >> 16) & 0xff]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+1); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+2); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - n = *(p+3); - even = g_nRandomValues[odd ^ (n >> 24)]; - odd = g_nRandomValues[even ^ ((n >> 16) & 0xff)]; - even = g_nRandomValues[odd ^ ((n >> 8) & 0xff)]; - odd = g_nRandomValues[even ^ (n & 0xff)]; - - return (even << 8) | odd; -} - - -//----------------------------------------------------------------------------- -// Arbitrary fixed length hash -//----------------------------------------------------------------------------- -unsigned FASTCALL HashBlock( const void *pKey, unsigned size ) -{ - const uint8 * k = (const uint8 *) pKey; - unsigned even = 0, - odd = 0, - n; - - while (size) - { - --size; - n = *k++; - even = g_nRandomValues[odd ^ n]; - if (size) - { - --size; - n = *k++; - odd = g_nRandomValues[even ^ n]; - } - else - break; - } - - return (even << 8) | odd; -} - diff --git a/Resources/NetHook/tier1/generichash.h b/Resources/NetHook/tier1/generichash.h deleted file mode 100644 index 057ca971..00000000 --- a/Resources/NetHook/tier1/generichash.h +++ /dev/null @@ -1,92 +0,0 @@ -//======= Copyright © 2005, , Valve Corporation, All rights reserved. ========= -// -// Purpose: Variant Pearson Hash general purpose hashing algorithm described -// by Cargill in C++ Report 1994. Generates a 16-bit result. -// -//============================================================================= - -#ifndef GENERICHASH_H -#define GENERICHASH_H - -#if defined(_WIN32) -#pragma once -#endif - -//----------------------------------------------------------------------------- - -unsigned FASTCALL HashString( const char *pszKey ); -unsigned FASTCALL HashStringCaseless( const char *pszKey ); -unsigned FASTCALL HashStringCaselessConventional( const char *pszKey ); -unsigned FASTCALL Hash4( const void *pKey ); -unsigned FASTCALL Hash8( const void *pKey ); -unsigned FASTCALL Hash12( const void *pKey ); -unsigned FASTCALL Hash16( const void *pKey ); -unsigned FASTCALL HashBlock( const void *pKey, unsigned size ); - -unsigned FASTCALL HashInt( const int key ); - -inline unsigned HashIntConventional( const int n ) // faster but less effective -{ - // first byte - unsigned hash = 0xAAAAAAAA + (n & 0xFF); - // second byte - hash = ( hash << 5 ) + hash + ( (n >> 8) & 0xFF ); - // third byte - hash = ( hash << 5 ) + hash + ( (n >> 16) & 0xFF ); - // fourth byte - hash = ( hash << 5 ) + hash + ( (n >> 24) & 0xFF ); - - return hash; - - /* this is the old version, which would cause a load-hit-store on every - line on a PowerPC, and therefore took hundreds of clocks to execute! - - byte *p = (byte *)&n; - unsigned hash = 0xAAAAAAAA + *p++; - hash = ( ( hash << 5 ) + hash ) + *p++; - hash = ( ( hash << 5 ) + hash ) + *p++; - return ( ( hash << 5 ) + hash ) + *p; - */ -} - -//----------------------------------------------------------------------------- - -template -inline unsigned HashItem( const T &item ) -{ - // TODO: Confirm comiler optimizes out unused paths - if ( sizeof(item) == 4 ) - return Hash4( &item ); - else if ( sizeof(item) == 8 ) - return Hash8( &item ); - else if ( sizeof(item) == 12 ) - return Hash12( &item ); - else if ( sizeof(item) == 16 ) - return Hash16( &item ); - else - return HashBlock( &item, sizeof(item) ); -} - -template <> inline unsigned HashItem(const int &key ) -{ - return HashInt( key ); -} - -template <> inline unsigned HashItem(const unsigned &key ) -{ - return HashInt( (int)key ); -} - -template<> inline unsigned HashItem(const char * const &pszKey ) -{ - return HashString( pszKey ); -} - -template<> inline unsigned HashItem(char * const &pszKey ) -{ - return HashString( pszKey ); -} - -//----------------------------------------------------------------------------- - -#endif /* !GENERICHASH_H */ diff --git a/Resources/NetHook/tier1/iconvar.h b/Resources/NetHook/tier1/iconvar.h deleted file mode 100644 index 53a7e126..00000000 --- a/Resources/NetHook/tier1/iconvar.h +++ /dev/null @@ -1,114 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $NoKeywords: $ -//===========================================================================// - -#ifndef ICONVAR_H -#define ICONVAR_H - -#if _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "tier0/platform.h" -#include "tier1/strtools.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class IConVar; -class CCommand; - - -//----------------------------------------------------------------------------- -// ConVar flags -//----------------------------------------------------------------------------- -// The default, no flags at all -#define FCVAR_NONE 0 - -// Command to ConVars and ConCommands -// ConVar Systems -#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc. -#define FCVAR_DEVELOPMENTONLY (1<<1) // Hidden in released products. Flag is removed automatically if ALLOW_DEVELOPMENT_CVARS is defined. -#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL -#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL -#define FCVAR_HIDDEN (1<<4) // Hidden. Doesn't appear in find or autocomplete. Like DEVELOPMENTONLY, but can't be compiled out. - -// ConVar only -#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value -#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server. -#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc -#define FCVAR_NOTIFY (1<<8) // notifies players when changed -#define FCVAR_USERINFO (1<<9) // changes the client's info string -#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats - -#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). -#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log -#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar - -// It's a ConVar that's shared between the client and the server. -// At signon, the values of all such ConVars are sent from the server to the client (skipped for local -// client, of course ) -// If a change is requested it must come from the console (i.e., no remote client changes) -// If a value is changed while a server is active, it's replicated to all connected clients -#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time -#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file -#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles - -#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server - -#define FCVAR_ARCHIVE_XBOX (1<<24) // cvar written to config.cfg on the Xbox - -#define FCVAR_SERVER_CAN_EXECUTE (1<<28)// the server is allowed to execute this command on clients via ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd. -#define FCVAR_SERVER_CANNOT_QUERY (1<<29)// If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue). -#define FCVAR_CLIENTCMD_CAN_EXECUTE (1<<30) // IVEngineClient::ClientCmd is allowed to execute this command. - // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command. - -// #define FCVAR_AVAILABLE (1<<15) -// #define FCVAR_AVAILABLE (1<<18) -// #define FCVAR_AVAILABLE (1<<19) -// #define FCVAR_AVAILABLE (1<<20) -// #define FCVAR_AVAILABLE (1<<21) -// #define FCVAR_AVAILABLE (1<<23) -// #define FCVAR_AVAILABLE (1<<25) -// #define FCVAR_AVAILABLE (1<<26) -// #define FCVAR_AVAILABLE (1<<27) -// #define FCVAR_AVAILABLE (1<<31) - - -//----------------------------------------------------------------------------- -// Called when a ConVar changes value -// NOTE: For FCVAR_NEVER_AS_STRING ConVars, pOldValue == NULL -//----------------------------------------------------------------------------- -typedef void ( *FnChangeCallback_t )( IConVar *var, const char *pOldValue, float flOldValue ); - - -//----------------------------------------------------------------------------- -// Abstract interface for ConVars -//----------------------------------------------------------------------------- -abstract_class IConVar -{ -public: - // Value set - virtual void SetValue( const char *pValue ) = 0; - virtual void SetValue( float flValue ) = 0; - virtual void SetValue( int nValue ) = 0; - - // Return name of command - virtual const char *GetName( void ) const = 0; - - // Accessors.. not as efficient as using GetState()/GetInfo() - // if you call these methods multiple times on the same IConVar - virtual bool IsFlagSet( int nFlag ) const = 0; -}; - - -#endif // ICONVAR_H diff --git a/Resources/NetHook/tier1/interface.cpp b/Resources/NetHook/tier1/interface.cpp deleted file mode 100644 index 0e87b614..00000000 --- a/Resources/NetHook/tier1/interface.cpp +++ /dev/null @@ -1,462 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// -#if defined( _WIN32 ) && !defined( _X360 ) -#include -#endif - -#if !defined( DONT_PROTECT_FILEIO_FUNCTIONS ) -#define DONT_PROTECT_FILEIO_FUNCTIONS // for protected_things.h -#endif - -#if defined( PROTECTED_THINGS_ENABLE ) -#undef PROTECTED_THINGS_ENABLE // from protected_things.h -#endif - -#include -#include "interface.h" -#include "basetypes.h" -#include "tier0/dbg.h" -#include -#include -#include "tier1/strtools.h" -#include "tier0/icommandline.h" -#include "tier0/dbg.h" -#include "tier0/threadtools.h" -#ifdef _WIN32 -#include // getcwd -#elif _LINUX -#define _getcwd getcwd -#endif -#if defined( _X360 ) -#include "xbox/xbox_win32stubs.h" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// ------------------------------------------------------------------------------------ // -// InterfaceReg. -// ------------------------------------------------------------------------------------ // -InterfaceReg *InterfaceReg::s_pInterfaceRegs = NULL; - -InterfaceReg::InterfaceReg( InstantiateInterfaceFn fn, const char *pName ) : - m_pName(pName) -{ - m_CreateFn = fn; - m_pNext = s_pInterfaceRegs; - s_pInterfaceRegs = this; -} - -// ------------------------------------------------------------------------------------ // -// CreateInterface. -// This is the primary exported function by a dll, referenced by name via dynamic binding -// that exposes an opqaue function pointer to the interface. -// ------------------------------------------------------------------------------------ // -void* CreateInterface( const char *pName, int *pReturnCode ) -{ - InterfaceReg *pCur; - - for (pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext) - { - if (strcmp(pCur->m_pName, pName) == 0) - { - if (pReturnCode) - { - *pReturnCode = IFACE_OK; - } - return pCur->m_CreateFn(); - } - } - - if (pReturnCode) - { - *pReturnCode = IFACE_FAILED; - } - return NULL; -} - - -#ifdef _LINUX -// Linux doesn't have this function so this emulates its functionality -void *GetModuleHandle(const char *name) -{ - void *handle; - - if( name == NULL ) - { - // hmm, how can this be handled under linux.... - // is it even needed? - return NULL; - } - - if( (handle=dlopen(name, RTLD_NOW))==NULL) - { - printf("DLOPEN Error:%s\n",dlerror()); - // couldn't open this file - return NULL; - } - - // read "man dlopen" for details - // in short dlopen() inc a ref count - // so dec the ref count by performing the close - dlclose(handle); - return handle; -} -#endif - -#if defined( _WIN32 ) && !defined( _X360 ) -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#endif - -//----------------------------------------------------------------------------- -// Purpose: returns a pointer to a function, given a module -// Input : pModuleName - module name -// *pName - proc name -//----------------------------------------------------------------------------- -static void *Sys_GetProcAddress( const char *pModuleName, const char *pName ) -{ - HMODULE hModule = GetModuleHandle( pModuleName ); - return GetProcAddress( hModule, pName ); -} - -static void *Sys_GetProcAddress( HMODULE hModule, const char *pName ) -{ - return GetProcAddress( hModule, pName ); -} - -bool Sys_IsDebuggerPresent() -{ - return Plat_IsInDebugSession(); -} - -struct ThreadedLoadLibaryContext_t -{ - const char *m_pLibraryName; - HMODULE m_hLibrary; -}; - -#ifdef _WIN32 - -// wraps LoadLibraryEx() since 360 doesn't support that -static HMODULE InternalLoadLibrary( const char *pName ) -{ -#if defined(_X360) - return LoadLibrary( pName ); -#else - return LoadLibraryEx( pName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); -#endif -} -unsigned ThreadedLoadLibraryFunc( void *pParam ) -{ - ThreadedLoadLibaryContext_t *pContext = (ThreadedLoadLibaryContext_t*)pParam; - pContext->m_hLibrary = InternalLoadLibrary(pContext->m_pLibraryName); - return 0; -} -#endif - -HMODULE Sys_LoadLibrary( const char *pLibraryName ) -{ - char str[1024]; -#if defined( _WIN32 ) && !defined( _X360 ) - const char *pModuleExtension = ".dll"; - const char *pModuleAddition = pModuleExtension; -#elif defined( _X360 ) - const char *pModuleExtension = "_360.dll"; - const char *pModuleAddition = pModuleExtension; -#elif defined( _LINUX ) - const char *pModuleExtension = ".so"; - const char *pModuleAddition = "_i486.so"; // if an extension is on the filename assume the i486 binary set -#endif - Q_strncpy( str, pLibraryName, sizeof(str) ); - if ( !Q_stristr( str, pModuleExtension ) ) - { - if ( IsX360() ) - { - Q_StripExtension( str, str, sizeof(str) ); - } - Q_strncat( str, pModuleAddition, sizeof(str) ); - } - Q_FixSlashes( str ); - -#ifdef _WIN32 - ThreadedLoadLibraryFunc_t threadFunc = GetThreadedLoadLibraryFunc(); - if ( !threadFunc ) - return InternalLoadLibrary( str ); - - ThreadedLoadLibaryContext_t context; - context.m_pLibraryName = str; - context.m_hLibrary = 0; - - ThreadHandle_t h = CreateSimpleThread( ThreadedLoadLibraryFunc, &context ); - -#ifdef _X360 - ThreadSetAffinity( h, XBOX_PROCESSOR_3 ); -#endif - - unsigned int nTimeout = 0; - while( ThreadWaitForObject( h, true, nTimeout ) == TW_TIMEOUT ) - { - nTimeout = threadFunc(); - } - - ReleaseThreadHandle( h ); - return context.m_hLibrary; - -#elif _LINUX - HMODULE ret = dlopen( str, RTLD_NOW ); - if ( ! ret ) - { - const char *pError = dlerror(); - if ( pError && ( strstr( pError, "No such file" ) == 0 ) ) - { - Msg( " failed to dlopen %s error=%s\n", str, pError ); - - } - } - - return ret; -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Loads a DLL/component from disk and returns a handle to it -// Input : *pModuleName - filename of the component -// Output : opaque handle to the module (hides system dependency) -//----------------------------------------------------------------------------- -CSysModule *Sys_LoadModule( const char *pModuleName ) -{ - // If using the Steam filesystem, either the DLL must be a minimum footprint - // file in the depot (MFP) or a filesystem GetLocalCopy() call must be made - // prior to the call to this routine. - char szCwd[1024]; - HMODULE hDLL = NULL; - - if ( !Q_IsAbsolutePath( pModuleName ) ) - { - // full path wasn't passed in, using the current working dir - _getcwd( szCwd, sizeof( szCwd ) ); - if ( IsX360() ) - { - int i = CommandLine()->FindParm( "-basedir" ); - if ( i ) - { - strcpy( szCwd, CommandLine()->GetParm( i+1 ) ); - } - } - if (szCwd[strlen(szCwd) - 1] == '/' || szCwd[strlen(szCwd) - 1] == '\\' ) - { - szCwd[strlen(szCwd) - 1] = 0; - } - - char szAbsoluteModuleName[1024]; - if ( strstr( pModuleName, "bin/") == pModuleName ) - { - // don't make bin/bin path - Q_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName ); - } - else - { - Q_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/bin/%s", szCwd, pModuleName ); - } - hDLL = Sys_LoadLibrary( szAbsoluteModuleName ); - } - - if ( !hDLL ) - { - // full path failed, let LoadLibrary() try to search the PATH now - hDLL = Sys_LoadLibrary( pModuleName ); -#if defined( _DEBUG ) - if ( !hDLL ) - { -// So you can see what the error is in the debugger... -#if defined( _WIN32 ) && !defined( _X360 ) - char *lpMsgBuf; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - - LocalFree( (HLOCAL)lpMsgBuf ); -#elif defined( _X360 ) - Msg( "Failed to load %s:\n", pModuleName ); -#else - Error( "Failed to load %s: %s\n", pModuleName, dlerror() ); -#endif // _WIN32 - } -#endif // DEBUG - } - - // If running in the debugger, assume debug binaries are okay, otherwise they must run with -allowdebug - if ( !IsX360() && hDLL && - !CommandLine()->FindParm( "-allowdebug" ) && - !Sys_IsDebuggerPresent() ) - { - if ( Sys_GetProcAddress( hDLL, "BuiltDebug" ) ) - { - Error( "Module %s is a debug build\n", pModuleName ); - } - } - - return reinterpret_cast(hDLL); -} - - -//----------------------------------------------------------------------------- -// Purpose: Unloads a DLL/component from -// Input : *pModuleName - filename of the component -// Output : opaque handle to the module (hides system dependency) -//----------------------------------------------------------------------------- -void Sys_UnloadModule( CSysModule *pModule ) -{ - if ( !pModule ) - return; - - HMODULE hDLL = reinterpret_cast(pModule); - -#ifdef _WIN32 - FreeLibrary( hDLL ); -#elif defined(_LINUX) - dlclose((void *)hDLL); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: returns a pointer to a function, given a module -// Input : module - windows HMODULE from Sys_LoadModule() -// *pName - proc name -// Output : factory for this module -//----------------------------------------------------------------------------- -CreateInterfaceFn Sys_GetFactory( CSysModule *pModule ) -{ - if ( !pModule ) - return NULL; - - HMODULE hDLL = reinterpret_cast(pModule); -#ifdef _WIN32 - return reinterpret_cast(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME )); -#elif defined(_LINUX) - // Linux gives this error: - //../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory - //(CSysModule *)) (const char *, int *)': - //../public/interface.cpp:154: ISO C++ forbids casting between - //pointer-to-function and pointer-to-object - // - // so lets get around it :) - return (CreateInterfaceFn)(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME )); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: returns the instance of this module -// Output : interface_instance_t -//----------------------------------------------------------------------------- -CreateInterfaceFn Sys_GetFactoryThis( void ) -{ - return CreateInterface; -} - -//----------------------------------------------------------------------------- -// Purpose: returns the instance of the named module -// Input : *pModuleName - name of the module -// Output : interface_instance_t - instance of that module -//----------------------------------------------------------------------------- -CreateInterfaceFn Sys_GetFactory( const char *pModuleName ) -{ -#ifdef _WIN32 - return static_cast( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) ); -#elif defined(_LINUX) - // see Sys_GetFactory( CSysModule *pModule ) for an explanation - return (CreateInterfaceFn)( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) ); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: get the interface for the specified module and version -// Input : -// Output : -//----------------------------------------------------------------------------- -bool Sys_LoadInterface( - const char *pModuleName, - const char *pInterfaceVersionName, - CSysModule **pOutModule, - void **pOutInterface ) -{ - CSysModule *pMod = Sys_LoadModule( pModuleName ); - if ( !pMod ) - return false; - - CreateInterfaceFn fn = Sys_GetFactory( pMod ); - if ( !fn ) - { - Sys_UnloadModule( pMod ); - return false; - } - - *pOutInterface = fn( pInterfaceVersionName, NULL ); - if ( !( *pOutInterface ) ) - { - Sys_UnloadModule( pMod ); - return false; - } - - if ( pOutModule ) - *pOutModule = pMod; - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Place this as a singleton at module scope (e.g.) and use it to get the factory from the specified module name. -// -// When the singleton goes out of scope (.dll unload if at module scope), -// then it'll call Sys_UnloadModule on the module so that the refcount is decremented -// and the .dll actually can unload from memory. -//----------------------------------------------------------------------------- -CDllDemandLoader::CDllDemandLoader( char const *pchModuleName ) : - m_pchModuleName( pchModuleName ), - m_hModule( 0 ), - m_bLoadAttempted( false ) -{ -} - -CDllDemandLoader::~CDllDemandLoader() -{ - Unload(); -} - -CreateInterfaceFn CDllDemandLoader::GetFactory() -{ - if ( !m_hModule && !m_bLoadAttempted ) - { - m_bLoadAttempted = true; - m_hModule = Sys_LoadModule( m_pchModuleName ); - } - - if ( !m_hModule ) - { - return NULL; - } - - return Sys_GetFactory( m_hModule ); -} - -void CDllDemandLoader::Unload() -{ - if ( m_hModule ) - { - Sys_UnloadModule( m_hModule ); - m_hModule = 0; - } -} diff --git a/Resources/NetHook/tier1/interface.h b/Resources/NetHook/tier1/interface.h deleted file mode 100644 index 73ed499a..00000000 --- a/Resources/NetHook/tier1/interface.h +++ /dev/null @@ -1,219 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -// This header defines the interface convention used in the valve engine. -// To make an interface and expose it: -// 1. The interface must be ALL pure virtuals, and have no data members. -// 2. Define a name for it. -// 3. In its implementation file, use EXPOSE_INTERFACE or EXPOSE_SINGLE_INTERFACE. - -// Versioning -// There are two versioning cases that are handled by this: -// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case, -// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface. -// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface -// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and -// expose it for the old interface. - -// Static Linking: -// Must mimic unique seperate class 'InterfaceReg' constructors per subsystem. -// Each subsystem can then import and export interfaces as expected. -// This is achieved through unique namespacing 'InterfaceReg' via symbol _SUBSYSTEM. -// Static Linking also needs to generate unique symbols per interface so as to -// provide a 'stitching' method whereby these interface symbols can be referenced -// via the lib's primary module (usually the lib's interface exposure) -// therby stitching all of that lib's code/data together for eventual final exe link inclusion. - -#ifndef INTERFACE_H -#define INTERFACE_H - -#ifdef _WIN32 -#pragma once -#endif - -#ifdef _LINUX -#include // dlopen,dlclose, et al -#include - -#define HMODULE void * -#define GetProcAddress dlsym - -#define _snprintf snprintf -#endif - -// TODO: move interface.cpp into tier0 library. -#include "tier0/platform.h" - -// All interfaces derive from this. -class IBaseInterface -{ -public: - virtual ~IBaseInterface() {} -}; - -#if !defined( _X360 ) -#define CREATEINTERFACE_PROCNAME "CreateInterface" -#else -// x360 only allows ordinal exports, .def files export "CreateInterface" at 1 -#define CREATEINTERFACE_PROCNAME ((const char*)1) -#endif - -typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode); -typedef void* (*InstantiateInterfaceFn)(); - -// Used internally to register classes. -class InterfaceReg -{ -public: - InterfaceReg(InstantiateInterfaceFn fn, const char *pName); - -public: - InstantiateInterfaceFn m_CreateFn; - const char *m_pName; - - InterfaceReg *m_pNext; // For the global list. - static InterfaceReg *s_pInterfaceRegs; -}; - -// Use this to expose an interface that can have multiple instances. -// e.g.: -// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" ) -// This will expose a class called CInterfaceImp that implements IInterface (a pure class) -// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" ) -// -// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001") -// so that each component can use these names/vtables to communicate -// -// A single class can support multiple interfaces through multiple inheritance -// -// Use this if you want to write the factory function. -#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM) -#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \ - static InterfaceReg __g_Create##interfaceName##_reg(functionName, versionName); -#else -#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \ - namespace _SUBSYSTEM \ - { \ - static InterfaceReg __g_Create##interfaceName##_reg(functionName, versionName); \ - } -#endif - -#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM) -#define EXPOSE_INTERFACE(className, interfaceName, versionName) \ - static void* __Create##className##_interface() {return static_cast( new className );} \ - static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName ); -#else -#define EXPOSE_INTERFACE(className, interfaceName, versionName) \ - namespace _SUBSYSTEM \ - { \ - static void* __Create##className##_interface() {return static_cast( new className );} \ - static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName ); \ - } -#endif - -// Use this to expose a singleton interface with a global variable you've created. -#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM) -#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \ - static void* __Create##className##interfaceName##_interface() {return static_cast( &globalVarName );} \ - static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName); -#else -#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \ - namespace _SUBSYSTEM \ - { \ - static void* __Create##className##interfaceName##_interface() {return static_cast( &globalVarName );} \ - static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName); \ - } -#endif - -// Use this to expose a singleton interface. This creates the global variable for you automatically. -#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM) -#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \ - static className __g_##className##_singleton; \ - EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton) -#else -#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \ - namespace _SUBSYSTEM \ - { \ - static className __g_##className##_singleton; \ - } \ - EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton) -#endif - -// load/unload components -class CSysModule; - -// interface return status -enum -{ - IFACE_OK = 0, - IFACE_FAILED -}; - -//----------------------------------------------------------------------------- -// This function is automatically exported and allows you to access any interfaces exposed with the above macros. -// if pReturnCode is set, it will return one of the following values (IFACE_OK, IFACE_FAILED) -// extend this for other error conditions/code -//----------------------------------------------------------------------------- -DLL_EXPORT void* CreateInterface(const char *pName, int *pReturnCode); - -#if defined( _X360 ) -DLL_EXPORT void *CreateInterfaceThunk( const char *pName, int *pReturnCode ); -#endif - -//----------------------------------------------------------------------------- -// UNDONE: This is obsolete, use the module load/unload/get instead!!! -//----------------------------------------------------------------------------- -extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule ); -extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName ); -extern CreateInterfaceFn Sys_GetFactoryThis( void ); - -//----------------------------------------------------------------------------- -// Load & Unload should be called in exactly one place for each module -// The factory for that module should be passed on to dependent components for -// proper versioning. -//----------------------------------------------------------------------------- -extern CSysModule *Sys_LoadModule( const char *pModuleName ); -extern void Sys_UnloadModule( CSysModule *pModule ); - -// This is a helper function to load a module, get its factory, and get a specific interface. -// You are expected to free all of these things. -// Returns false and cleans up if any of the steps fail. -bool Sys_LoadInterface( - const char *pModuleName, - const char *pInterfaceVersionName, - CSysModule **pOutModule, - void **pOutInterface ); - -bool Sys_IsDebuggerPresent(); - -//----------------------------------------------------------------------------- -// Purpose: Place this as a singleton at module scope (e.g.) and use it to get the factory from the specified module name. -// -// When the singleton goes out of scope (.dll unload if at module scope), -// then it'll call Sys_UnloadModule on the module so that the refcount is decremented -// and the .dll actually can unload from memory. -//----------------------------------------------------------------------------- -class CDllDemandLoader -{ -public: - CDllDemandLoader( char const *pchModuleName ); - virtual ~CDllDemandLoader(); - CreateInterfaceFn GetFactory(); - void Unload(); - -private: - - char const *m_pchModuleName; - CSysModule *m_hModule; - bool m_bLoadAttempted; -}; - -#endif - - - diff --git a/Resources/NetHook/tier1/lzmaDecoder.h b/Resources/NetHook/tier1/lzmaDecoder.h deleted file mode 100644 index 197fd6bf..00000000 --- a/Resources/NetHook/tier1/lzmaDecoder.h +++ /dev/null @@ -1,42 +0,0 @@ -//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// -// -// LZMA Decoder. Designed for run time decoding. -// -// LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) -// http://www.7-zip.org/ -// -//=====================================================================================// - -#ifndef _LZMADECODER_H -#define _LZMADECODER_H -#pragma once - -#if !defined( _X360 ) -#define LZMA_ID (('A'<<24)|('M'<<16)|('Z'<<8)|('L')) -#else -#define LZMA_ID (('L'<<24)|('Z'<<16)|('M'<<8)|('A')) -#endif - -// bind the buffer for correct identification -#pragma pack(1) -struct lzma_header_t -{ - unsigned int id; - unsigned int actualSize; // always little endian - unsigned int lzmaSize; // always little endian - unsigned char properties[5]; -}; -#pragma pack() - -class CLZMA -{ -public: - unsigned int Uncompress( unsigned char *pInput, unsigned char *pOutput ); - bool IsCompressed( unsigned char *pInput ); - unsigned int GetActualSize( unsigned char *pInput ); - -private: -}; - -#endif - diff --git a/Resources/NetHook/tier1/lzss.h b/Resources/NetHook/tier1/lzss.h deleted file mode 100644 index 5c923176..00000000 --- a/Resources/NetHook/tier1/lzss.h +++ /dev/null @@ -1,71 +0,0 @@ -//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// -// -// LZSS Codec. Designed for fast cheap gametime encoding/decoding. Compression results -// are not aggresive as other alogrithms, but gets 2:1 on most arbitrary uncompressed data. -// -//=====================================================================================// - -#ifndef _LZSS_H -#define _LZSS_H -#pragma once - -#if !defined( _X360 ) -#define LZSS_ID (('S'<<24)|('S'<<16)|('Z'<<8)|('L')) -#else -#define LZSS_ID (('L'<<24)|('Z'<<16)|('S'<<8)|('S')) -#endif - -// bind the buffer for correct identification -struct lzss_header_t -{ - unsigned int id; - unsigned int actualSize; // always little endian -}; - -class CUtlBuffer; - -#define DEFAULT_LZSS_WINDOW_SIZE 4096 - -class CLZSS -{ -public: - unsigned char* Compress( unsigned char *pInput, int inputlen, unsigned int *pOutputSize ); - unsigned char* CompressNoAlloc( unsigned char *pInput, int inputlen, unsigned char *pOutput, unsigned int *pOutputSize ); - unsigned int Uncompress( unsigned char *pInput, unsigned char *pOutput ); - //unsigned int Uncompress( unsigned char *pInput, CUtlBuffer &buf ); - unsigned int SafeUncompress( unsigned char *pInput, unsigned char *pOutput, unsigned int unBufSize ); - bool IsCompressed( unsigned char *pInput ); - unsigned int GetActualSize( unsigned char *pInput ); - - // windowsize must be a power of two. - FORCEINLINE CLZSS( int nWindowSize = DEFAULT_LZSS_WINDOW_SIZE ); - -private: - // expected to be sixteen bytes - struct lzss_node_t - { - unsigned char *pData; - lzss_node_t *pPrev; - lzss_node_t *pNext; - char empty[4]; - }; - - struct lzss_list_t - { - lzss_node_t *pStart; - lzss_node_t *pEnd; - }; - - void BuildHash( unsigned char *pData ); - lzss_list_t *m_pHashTable; - lzss_node_t *m_pHashTarget; - int m_nWindowSize; - -}; - -FORCEINLINE CLZSS::CLZSS( int nWindowSize ) -{ - m_nWindowSize = nWindowSize; -} -#endif - diff --git a/Resources/NetHook/tier1/mempool.cpp b/Resources/NetHook/tier1/mempool.cpp deleted file mode 100644 index 5c770036..00000000 --- a/Resources/NetHook/tier1/mempool.cpp +++ /dev/null @@ -1,312 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -//===========================================================================// - -#include "mempool.h" -#include -#include -#include -#include "tier0/dbg.h" -#include -#include "tier1/strtools.h" - -// Should be last include -#include "tier0/memdbgon.h" - -MemoryPoolReportFunc_t CMemoryPool::g_ReportFunc = 0; - -//----------------------------------------------------------------------------- -// Error reporting... (debug only) -//----------------------------------------------------------------------------- - -void CMemoryPool::SetErrorReportFunc( MemoryPoolReportFunc_t func ) -{ - g_ReportFunc = func; -} - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -CMemoryPool::CMemoryPool( int blockSize, int numElements, int growMode, const char *pszAllocOwner, int nAlignment ) -{ -#ifdef _X360 - if( numElements > 0 && growMode != GROW_NONE ) - { - numElements = 1; - } -#endif - - m_nAlignment = ( nAlignment != 0 ) ? nAlignment : 1; - Assert( IsPowerOfTwo( m_nAlignment ) ); - m_BlockSize = blockSize < sizeof(void*) ? sizeof(void*) : blockSize; - m_BlockSize = AlignValue( m_BlockSize, m_nAlignment ); - m_BlocksPerBlob = numElements; - m_PeakAlloc = 0; - m_GrowMode = growMode; - if ( !pszAllocOwner ) - { - pszAllocOwner = __FILE__; - } - m_pszAllocOwner = pszAllocOwner; - Init(); - AddNewBlob(); -} - -//----------------------------------------------------------------------------- -// Purpose: Frees the memory contained in the mempool, and invalidates it for -// any further use. -// Input : *memPool - the mempool to shutdown -//----------------------------------------------------------------------------- -CMemoryPool::~CMemoryPool() -{ - if (m_BlocksAllocated > 0) - { - ReportLeaks(); - } - Clear(); -} - - -//----------------------------------------------------------------------------- -// Resets the pool -//----------------------------------------------------------------------------- -void CMemoryPool::Init() -{ - m_NumBlobs = 0; - m_BlocksAllocated = 0; - m_pHeadOfFreeList = 0; - m_BlobHead.m_pNext = m_BlobHead.m_pPrev = &m_BlobHead; -} - - -//----------------------------------------------------------------------------- -// Frees everything -//----------------------------------------------------------------------------- -void CMemoryPool::Clear() -{ - // Free everything.. - CBlob *pNext; - for( CBlob *pCur = m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur = pNext ) - { - pNext = pCur->m_pNext; - free( pCur ); - } - Init(); -} - -//----------------------------------------------------------------------------- -// Purpose: Reports memory leaks -//----------------------------------------------------------------------------- - -void CMemoryPool::ReportLeaks() -{ - if (!g_ReportFunc) - return; - - g_ReportFunc("Memory leak: mempool blocks left in memory: %d\n", m_BlocksAllocated); - -#ifdef _DEBUG - // walk and destroy the free list so it doesn't intefere in the scan - while (m_pHeadOfFreeList != NULL) - { - void *next = *((void**)m_pHeadOfFreeList); - memset(m_pHeadOfFreeList, 0, m_BlockSize); - m_pHeadOfFreeList = next; - } - - g_ReportFunc("Dumping memory: \'"); - - for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext ) - { - // scan the memory block and dump the leaks - char *scanPoint = (char *)pCur->m_Data; - char *scanEnd = pCur->m_Data + pCur->m_NumBytes; - bool needSpace = false; - - while (scanPoint < scanEnd) - { - // search for and dump any strings - if ((unsigned)(*scanPoint + 1) <= 256 && isprint(*scanPoint)) - { - g_ReportFunc("%c", *scanPoint); - needSpace = true; - } - else if (needSpace) - { - needSpace = false; - g_ReportFunc(" "); - } - - scanPoint++; - } - } - - g_ReportFunc("\'\n"); -#endif // _DEBUG -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CMemoryPool::AddNewBlob() -{ - MEM_ALLOC_CREDIT_(m_pszAllocOwner); - - int sizeMultiplier; - - if( m_GrowMode == GROW_SLOW ) - { - sizeMultiplier = 1; - } - else - { - if ( m_GrowMode == GROW_NONE ) - { - // Can only have one allocation when we're in this mode - if( m_NumBlobs != 0 ) - { - Assert( !"CMemoryPool::AddNewBlob: mode == GROW_NONE" ); - return; - } - } - - // GROW_FAST and GROW_NONE use this. - sizeMultiplier = m_NumBlobs + 1; - } - - // maybe use something other than malloc? - int nElements = m_BlocksPerBlob * sizeMultiplier; - int blobSize = m_BlockSize * nElements; - CBlob *pBlob = (CBlob*)malloc( sizeof(CBlob) - 1 + blobSize + ( m_nAlignment - 1 ) ); - Assert( pBlob ); - - // Link it in at the end of the blob list. - pBlob->m_NumBytes = blobSize; - pBlob->m_pNext = &m_BlobHead; - pBlob->m_pPrev = pBlob->m_pNext->m_pPrev; - pBlob->m_pNext->m_pPrev = pBlob->m_pPrev->m_pNext = pBlob; - - // setup the free list - m_pHeadOfFreeList = AlignValue( pBlob->m_Data, m_nAlignment ); - Assert (m_pHeadOfFreeList); - - void **newBlob = (void**)m_pHeadOfFreeList; - for (int j = 0; j < nElements-1; j++) - { - newBlob[0] = (char*)newBlob + m_BlockSize; - newBlob = (void**)newBlob[0]; - } - - // null terminate list - newBlob[0] = NULL; - m_NumBlobs++; -} - - -void* CMemoryPool::Alloc() -{ - return Alloc( m_BlockSize ); -} - - -void* CMemoryPool::AllocZero() -{ - return AllocZero( m_BlockSize ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Allocs a single block of memory from the pool. -// Input : amount - -//----------------------------------------------------------------------------- -void *CMemoryPool::Alloc( unsigned int amount ) -{ - void *returnBlock; - - if ( amount > (unsigned int)m_BlockSize ) - return NULL; - - if( !m_pHeadOfFreeList ) - { - // returning NULL is fine in GROW_NONE - if( m_GrowMode == GROW_NONE ) - { - //Assert( !"CMemoryPool::Alloc: tried to make new blob with GROW_NONE" ); - return NULL; - } - - // overflow - AddNewBlob(); - - // still failure, error out - if( !m_pHeadOfFreeList ) - { - Assert( !"CMemoryPool::Alloc: ran out of memory" ); - return NULL; - } - } - m_BlocksAllocated++; - m_PeakAlloc = max(m_PeakAlloc, m_BlocksAllocated); - - returnBlock = m_pHeadOfFreeList; - - // move the pointer the next block - m_pHeadOfFreeList = *((void**)m_pHeadOfFreeList); - - return returnBlock; -} - -//----------------------------------------------------------------------------- -// Purpose: Allocs a single block of memory from the pool, zeroes the memory before returning -// Input : amount - -//----------------------------------------------------------------------------- -void *CMemoryPool::AllocZero( unsigned int amount ) -{ - void *mem = Alloc( amount ); - if ( mem ) - { - V_memset( mem, 0x00, amount ); - } - return mem; -} - -//----------------------------------------------------------------------------- -// Purpose: Frees a block of memory -// Input : *memBlock - the memory to free -//----------------------------------------------------------------------------- -void CMemoryPool::Free( void *memBlock ) -{ - if ( !memBlock ) - return; // trying to delete NULL pointer, ignore - -#ifdef _DEBUG - // check to see if the memory is from the allocated range - bool bOK = false; - for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext ) - { - if (memBlock >= pCur->m_Data && (char*)memBlock < (pCur->m_Data + pCur->m_NumBytes)) - { - bOK = true; - } - } - Assert (bOK); -#endif // _DEBUG - -#ifdef _DEBUG - // invalidate the memory - memset( memBlock, 0xDD, m_BlockSize ); -#endif - - m_BlocksAllocated--; - - // make the block point to the first item in the list - *((void**)memBlock) = m_pHeadOfFreeList; - - // the list head is now the new block - m_pHeadOfFreeList = memBlock; -} - - diff --git a/Resources/NetHook/tier1/mempool.h b/Resources/NetHook/tier1/mempool.h deleted file mode 100644 index 3f334596..00000000 --- a/Resources/NetHook/tier1/mempool.h +++ /dev/null @@ -1,541 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//===========================================================================// - -#ifndef MEMPOOL_H -#define MEMPOOL_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/memalloc.h" -#include "tier0/tslist.h" -#include "tier0/platform.h" -#include "tier1/utlvector.h" -#include "tier1/utlrbtree.h" - -//----------------------------------------------------------------------------- -// Purpose: Optimized pool memory allocator -//----------------------------------------------------------------------------- - -typedef void (*MemoryPoolReportFunc_t)( char const* pMsg, ... ); - -class CMemoryPool -{ -public: - // Ways the memory pool can grow when it needs to make a new blob. - enum MemoryPoolGrowType_t - { - GROW_NONE=0, // Don't allow new blobs. - GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates - // get larger and larger each time it allocates one). - GROW_SLOW=2 // New blob size is numElements. - }; - - CMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 ); - ~CMemoryPool(); - - void* Alloc(); // Allocate the element size you specified in the constructor. - void* Alloc( size_t amount ); - void* AllocZero(); // Allocate the element size you specified in the constructor, zero the memory before construction - void* AllocZero( size_t amount ); - void Free(void *pMem); - - // Frees everything - void Clear(); - - // Error reporting... - static void SetErrorReportFunc( MemoryPoolReportFunc_t func ); - - // returns number of allocated blocks - int Count() { return m_BlocksAllocated; } - int PeakCount() { return m_PeakAlloc; } - -protected: - class CBlob - { - public: - CBlob *m_pPrev, *m_pNext; - int m_NumBytes; // Number of bytes in this blob. - char m_Data[1]; - }; - - // Resets the pool - void Init(); - void AddNewBlob(); - void ReportLeaks(); - - int m_BlockSize; - int m_BlocksPerBlob; - - int m_GrowMode; // GROW_ enum. - - // FIXME: Change m_ppMemBlob into a growable array? - CBlob m_BlobHead; - void *m_pHeadOfFreeList; - int m_BlocksAllocated; - int m_PeakAlloc; - unsigned short m_nAlignment; - unsigned short m_NumBlobs; - const char * m_pszAllocOwner; - - static MemoryPoolReportFunc_t g_ReportFunc; -}; - - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -class CMemoryPoolMT : public CMemoryPool -{ -public: - CMemoryPoolMT(int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL) : CMemoryPool( blockSize, numElements, growMode, pszAllocOwner) {} - - - void* Alloc() { AUTO_LOCK( m_mutex ); return CMemoryPool::Alloc(); } - void* Alloc( size_t amount ) { AUTO_LOCK( m_mutex ); return CMemoryPool::Alloc( amount ); } - void* AllocZero() { AUTO_LOCK( m_mutex ); return CMemoryPool::AllocZero(); } - void* AllocZero( size_t amount ) { AUTO_LOCK( m_mutex ); return CMemoryPool::AllocZero( amount ); } - void Free(void *pMem) { AUTO_LOCK( m_mutex ); CMemoryPool::Free( pMem ); } - - // Frees everything - void Clear() { AUTO_LOCK( m_mutex ); return CMemoryPool::Clear(); } -private: - CThreadFastMutex m_mutex; // @TODO: Rework to use tslist (toml 7/6/2007) -}; - - -//----------------------------------------------------------------------------- -// Wrapper macro to make an allocator that returns particular typed allocations -// and construction and destruction of objects. -//----------------------------------------------------------------------------- -template< class T > -class CClassMemoryPool : public CMemoryPool -{ -public: - CClassMemoryPool(int numElements, int growMode = GROW_FAST, int nAlignment = 0 ) : - CMemoryPool( sizeof(T), numElements, growMode, MEM_ALLOC_CLASSNAME(T), nAlignment ) {} - - T* Alloc(); - T* AllocZero(); - void Free( T *pMem ); - - void Clear(); -}; - - -//----------------------------------------------------------------------------- -// Specialized pool for aligned data management (e.g., Xbox cubemaps) -//----------------------------------------------------------------------------- -template -class CAlignedMemPool -{ - enum - { - BLOCK_SIZE = max( ALIGN_VALUE( ITEM_SIZE, ALIGNMENT ), 8 ), - }; - -public: - CAlignedMemPool(); - - void *Alloc(); - void Free( void *p ); - - static int __cdecl CompareChunk( void * const *ppLeft, void * const *ppRight ); - void Compact(); - - int NumTotal() { return m_Chunks.Count() * ( CHUNK_SIZE / BLOCK_SIZE ); } - int NumAllocated() { return NumTotal() - m_nFree; } - int NumFree() { return m_nFree; } - - int BytesTotal() { return NumTotal() * BLOCK_SIZE; } - int BytesAllocated() { return NumAllocated() * BLOCK_SIZE; } - int BytesFree() { return NumFree() * BLOCK_SIZE; } - - int ItemSize() { return ITEM_SIZE; } - int BlockSize() { return BLOCK_SIZE; } - int ChunkSize() { return CHUNK_SIZE; } - -private: - struct FreeBlock_t - { - FreeBlock_t *pNext; - byte reserved[ BLOCK_SIZE - sizeof( FreeBlock_t *) ]; - }; - - CUtlVector m_Chunks; // Chunks are tracked outside blocks (unlike CMemoryPool) to simplify alignment issues - FreeBlock_t * m_pFirstFree; - int m_nFree; - CAllocator m_Allocator; - float m_TimeLastCompact; -}; - -//----------------------------------------------------------------------------- -// Pool variant using standard allocation -//----------------------------------------------------------------------------- -template -class CObjectPool -{ -public: - CObjectPool() - { - int i = nInitialCount; - while ( i-- > 0 ) - { - m_AvailableObjects.PushItem( new T ); - } - } - - ~CObjectPool() - { - Purge(); - } - - int NumAvailable() - { - return m_AvailableObjects.Count(); - } - - void Purge() - { - T *p; - while ( m_AvailableObjects.PopItem( &p ) ) - { - delete p; - } - } - - T *GetObject( bool bCreateNewIfEmpty = bDefCreateNewIfEmpty ) - { - T *p; - if ( !m_AvailableObjects.PopItem( &p ) ) - { - p = ( bCreateNewIfEmpty ) ? new T : NULL; - } - return p; - } - - void PutObject( T *p ) - { - m_AvailableObjects.PushItem( p ); - } - -private: - CTSList m_AvailableObjects; -}; - -//----------------------------------------------------------------------------- - - -template< class T > -inline T* CClassMemoryPool::Alloc() -{ - T *pRet; - - { - MEM_ALLOC_CREDIT_(MEM_ALLOC_CLASSNAME(T)); - pRet = (T*)CMemoryPool::Alloc(); - } - - if ( pRet ) - { - Construct( pRet ); - } - return pRet; -} - -template< class T > -inline T* CClassMemoryPool::AllocZero() -{ - T *pRet; - - { - MEM_ALLOC_CREDIT_(MEM_ALLOC_CLASSNAME(T)); - pRet = (T*)CMemoryPool::AllocZero(); - } - - if ( pRet ) - { - Construct( pRet ); - } - return pRet; -} - -template< class T > -inline void CClassMemoryPool::Free(T *pMem) -{ - if ( pMem ) - { - Destruct( pMem ); - } - - CMemoryPool::Free( pMem ); -} - -template< class T > -inline void CClassMemoryPool::Clear() -{ - CUtlRBTree freeBlocks; - SetDefLessFunc( freeBlocks ); - - void *pCurFree = m_pHeadOfFreeList; - while ( pCurFree != NULL ) - { - freeBlocks.Insert( pCurFree ); - pCurFree = *((void**)pCurFree); - } - - for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext ) - { - T *p = (T *)pCur->m_Data; - T *pLimit = (T *)(pCur->m_Data + pCur->m_NumBytes); - while ( p < pLimit ) - { - if ( freeBlocks.Find( p ) == freeBlocks.InvalidIndex() ) - { - Destruct( p ); - } - p++; - } - } - - CMemoryPool::Clear(); -} - - -//----------------------------------------------------------------------------- -// Macros that make it simple to make a class use a fixed-size allocator -// Put DECLARE_FIXEDSIZE_ALLOCATOR in the private section of a class, -// Put DEFINE_FIXEDSIZE_ALLOCATOR in the CPP file -//----------------------------------------------------------------------------- -#define DECLARE_FIXEDSIZE_ALLOCATOR( _class ) \ - public: \ - inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ - inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ - inline void operator delete( void* p ) { s_Allocator.Free(p); } \ - inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \ - private: \ - static CMemoryPool s_Allocator - -#define DEFINE_FIXEDSIZE_ALLOCATOR( _class, _initsize, _grow ) \ - CMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool") - -#define DEFINE_FIXEDSIZE_ALLOCATOR_ALIGNED( _class, _initsize, _grow, _alignment ) \ - CMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", _alignment ) - -#define DECLARE_FIXEDSIZE_ALLOCATOR_MT( _class ) \ - public: \ - inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ - inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ - inline void operator delete( void* p ) { s_Allocator.Free(p); } \ - inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \ - private: \ - static CMemoryPoolMT s_Allocator - -#define DEFINE_FIXEDSIZE_ALLOCATOR_MT( _class, _initsize, _grow ) \ - CMemoryPoolMT _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool") - -//----------------------------------------------------------------------------- -// Macros that make it simple to make a class use a fixed-size allocator -// This version allows us to use a memory pool which is externally defined... -// Put DECLARE_FIXEDSIZE_ALLOCATOR_EXTERNAL in the private section of a class, -// Put DEFINE_FIXEDSIZE_ALLOCATOR_EXTERNAL in the CPP file -//----------------------------------------------------------------------------- - -#define DECLARE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class ) \ - public: \ - inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \ - inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \ - inline void operator delete( void* p ) { s_pAllocator->Free(p); } \ - private: \ - static CMemoryPool* s_pAllocator - -#define DEFINE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class, _allocator ) \ - CMemoryPool* _class::s_pAllocator = _allocator - - -template -inline CAlignedMemPool::CAlignedMemPool() - : m_pFirstFree( 0 ), - m_nFree( 0 ), - m_TimeLastCompact( 0 ) -{ - COMPILE_TIME_ASSERT( sizeof( FreeBlock_t ) >= BLOCK_SIZE ); - COMPILE_TIME_ASSERT( ALIGN_VALUE( sizeof( FreeBlock_t ), ALIGNMENT ) == sizeof( FreeBlock_t ) ); -} - -template -inline void *CAlignedMemPool::Alloc() -{ - if ( !m_pFirstFree ) - { - FreeBlock_t *pNew = (FreeBlock_t *)m_Allocator.Alloc( CHUNK_SIZE ); - Assert( (unsigned)pNew % ALIGNMENT == 0 ); - m_Chunks.AddToTail( pNew ); - m_nFree = CHUNK_SIZE / BLOCK_SIZE; - m_pFirstFree = pNew; - for ( int i = 0; i < m_nFree - 1; i++ ) - { - pNew->pNext = pNew + 1; - pNew++; - } - pNew->pNext = NULL; - } - - void *p = m_pFirstFree; - m_pFirstFree = m_pFirstFree->pNext; - m_nFree--; - - return p; -} - -template -inline void CAlignedMemPool::Free( void *p ) -{ - // Insertion sort to encourage allocation clusters in chunks - FreeBlock_t *pFree = ((FreeBlock_t *)p); - FreeBlock_t *pCur = m_pFirstFree; - FreeBlock_t *pPrev = NULL; - - while ( pCur && pFree > pCur ) - { - pPrev = pCur; - pCur = pCur->pNext; - } - - pFree->pNext = pCur; - - if ( pPrev ) - { - pPrev->pNext = pFree; - } - else - { - m_pFirstFree = pFree; - } - m_nFree++; - - if ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD ) - { - float time = Plat_FloatTime(); - float compactTime = ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD * 4 ) ? 15.0 : 30.0; - if ( m_TimeLastCompact > time || m_TimeLastCompact + compactTime < Plat_FloatTime() ) - { - Compact(); - m_TimeLastCompact = time; - } - } -} - -template -inline int __cdecl CAlignedMemPool::CompareChunk( void * const *ppLeft, void * const *ppRight ) -{ - return ((unsigned)*ppLeft) - ((unsigned)*ppRight); -} - -template -inline void CAlignedMemPool::Compact() -{ - FreeBlock_t *pCur = m_pFirstFree; - FreeBlock_t *pPrev = NULL; - - m_Chunks.Sort( CompareChunk ); - -#ifdef VALIDATE_ALIGNED_MEM_POOL - { - FreeBlock_t *p = m_pFirstFree; - while ( p ) - { - if ( p->pNext && p > p->pNext ) - { - __asm { int 3 } - } - p = p->pNext; - } - - for ( int i = 0; i < m_Chunks.Count(); i++ ) - { - if ( i + 1 < m_Chunks.Count() ) - { - if ( m_Chunks[i] > m_Chunks[i + 1] ) - { - __asm { int 3 } - } - } - } - } -#endif - - int i; - - for ( i = 0; i < m_Chunks.Count(); i++ ) - { - int nBlocksPerChunk = CHUNK_SIZE / BLOCK_SIZE; - FreeBlock_t *pChunkLimit = ((FreeBlock_t *)m_Chunks[i]) + nBlocksPerChunk; - int nFromChunk = 0; - if ( pCur == m_Chunks[i] ) - { - FreeBlock_t *pFirst = pCur; - while ( pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit ) - { - pCur = pCur->pNext; - nFromChunk++; - } - pCur = pFirst; - - } - - while ( pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit ) - { - if ( nFromChunk != nBlocksPerChunk ) - { - if ( pPrev ) - { - pPrev->pNext = pCur; - } - else - { - m_pFirstFree = pCur; - } - pPrev = pCur; - } - else if ( pPrev ) - { - pPrev->pNext = NULL; - } - else - { - m_pFirstFree = NULL; - } - - pCur = pCur->pNext; - } - - if ( nFromChunk == nBlocksPerChunk ) - { - m_Allocator.Free( m_Chunks[i] ); - m_nFree -= nBlocksPerChunk; - m_Chunks[i] = 0; - } - } - - for ( i = m_Chunks.Count() - 1; i >= 0 ; i-- ) - { - if ( !m_Chunks[i] ) - { - m_Chunks.FastRemove( i ); - } - } -} - -#endif // MEMPOOL_H diff --git a/Resources/NetHook/tier1/memstack.cpp b/Resources/NetHook/tier1/memstack.cpp deleted file mode 100644 index 5efe33f8..00000000 --- a/Resources/NetHook/tier1/memstack.cpp +++ /dev/null @@ -1,297 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#if defined( _WIN32 ) && !defined( _X360 ) -#define WIN_32_LEAN_AND_MEAN -#include -#define VA_COMMIT_FLAGS MEM_COMMIT -#define VA_RESERVE_FLAGS MEM_RESERVE -#elif defined( _X360 ) -#define VA_COMMIT_FLAGS (MEM_COMMIT|MEM_NOZERO|MEM_LARGE_PAGES) -#define VA_RESERVE_FLAGS (MEM_RESERVE|MEM_LARGE_PAGES) -#endif - -#include "tier0/dbg.h" -#include "memstack.h" -#include "utlmap.h" -#include "tier0/memdbgon.h" - -#ifdef _WIN32 -#pragma warning(disable:4073) -#pragma init_seg(lib) -#endif - -//----------------------------------------------------------------------------- - -MEMALLOC_DEFINE_EXTERNAL_TRACKING(CMemoryStack); - -//----------------------------------------------------------------------------- - -CMemoryStack::CMemoryStack() - : m_pBase( NULL ), - m_pNextAlloc( NULL ), - m_pAllocLimit( NULL ), - m_pCommitLimit( NULL ), - m_alignment( 16 ), -#if defined(_WIN32) - m_commitSize( 0 ), - m_minCommit( 0 ), -#endif - m_maxSize( 0 ) -{ -} - -//------------------------------------- - -CMemoryStack::~CMemoryStack() -{ - if ( m_pBase ) - Term(); -} - -//------------------------------------- - -bool CMemoryStack::Init( unsigned maxSize, unsigned commitSize, unsigned initialCommit, unsigned alignment ) -{ - Assert( !m_pBase ); - -#ifdef _X360 - m_bPhysical = false; -#endif - - m_maxSize = maxSize; - m_alignment = AlignValue( alignment, 4 ); - - Assert( m_alignment == alignment ); - Assert( m_maxSize > 0 ); - -#if defined(_WIN32) - if ( commitSize != 0 ) - { - m_commitSize = commitSize; - } - - unsigned pageSize; - -#ifndef _X360 - SYSTEM_INFO sysInfo; - GetSystemInfo( &sysInfo ); - Assert( !( sysInfo.dwPageSize & (sysInfo.dwPageSize-1)) ); - pageSize = sysInfo.dwPageSize; -#else - pageSize = 64*1024; -#endif - - if ( m_commitSize == 0 ) - { - m_commitSize = pageSize; - } - else - { - m_commitSize = AlignValue( m_commitSize, pageSize ); - } - - m_maxSize = AlignValue( m_maxSize, m_commitSize ); - - Assert( m_maxSize % pageSize == 0 && m_commitSize % pageSize == 0 && m_commitSize <= m_maxSize ); - - m_pBase = (unsigned char *)VirtualAlloc( NULL, m_maxSize, VA_RESERVE_FLAGS, PAGE_NOACCESS ); - Assert( m_pBase ); - m_pCommitLimit = m_pNextAlloc = m_pBase; - - if ( initialCommit ) - { - initialCommit = AlignValue( initialCommit, m_commitSize ); - Assert( initialCommit < m_maxSize ); - if ( !VirtualAlloc( m_pCommitLimit, initialCommit, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) - return false; - m_minCommit = initialCommit; - m_pCommitLimit += initialCommit; - MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); - } - -#else - m_pBase = MemAlloc_AllocAligned( m_maxSize, alignment ? alignment : 1 ); - m_pNextAlloc = m_pBase; - m_pCommitLimit = m_pBase + m_maxSize; -#endif - - m_pAllocLimit = m_pBase + m_maxSize; - - return ( m_pBase != NULL ); -} - -//------------------------------------- - -#ifdef _X360 -bool CMemoryStack::InitPhysical( unsigned size, unsigned alignment ) -{ - m_bPhysical = true; - - m_maxSize = m_commitSize = size; - m_alignment = AlignValue( alignment, 4 ); - - int flags = PAGE_READWRITE; - if ( size >= 16*1024*1024 ) - { - flags |= MEM_16MB_PAGES; - } - else - { - flags |= MEM_LARGE_PAGES; - } - m_pBase = (unsigned char *)XPhysicalAlloc( m_maxSize, MAXULONG_PTR, 4096, flags ); - Assert( m_pBase ); - m_pNextAlloc = m_pBase; - m_pCommitLimit = m_pBase + m_maxSize; - m_pAllocLimit = m_pBase + m_maxSize; - - MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); - return ( m_pBase != NULL ); -} -#endif - -//------------------------------------- - -void CMemoryStack::Term() -{ - FreeAll(); - if ( m_pBase ) - { -#if defined(_WIN32) - VirtualFree( m_pBase, 0, MEM_RELEASE ); -#else - MemAlloc_FreeAligned( m_pBase ); -#endif - m_pBase = NULL; - } -} - -//------------------------------------- - -int CMemoryStack::GetSize() -{ -#ifdef _WIN32 - return m_pCommitLimit - m_pBase; -#else - return m_maxSize; -#endif -} - - -//------------------------------------- - -bool CMemoryStack::CommitTo( byte *pNextAlloc ) RESTRICT -{ -#ifdef _X360 - if ( m_bPhysical ) - { - return NULL; - } -#endif -#if defined(_WIN32) - unsigned char * pNewCommitLimit = AlignValue( pNextAlloc, m_commitSize ); - unsigned commitSize = pNewCommitLimit - m_pCommitLimit; - - if ( GetSize() ) - MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() ); - - if( m_pCommitLimit + commitSize > m_pAllocLimit ) - { - return false; - } - - if ( !VirtualAlloc( m_pCommitLimit, commitSize, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) - { - Assert( 0 ); - return false; - } - m_pCommitLimit = pNewCommitLimit; - - if ( GetSize() ) - MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); - return true; -#else - Assert( 0 ); - return false; -#endif -} - -//------------------------------------- - -void CMemoryStack::FreeToAllocPoint( MemoryStackMark_t mark, bool bDecommit ) -{ - void *pAllocPoint = m_pBase + mark; - Assert( pAllocPoint >= m_pBase && pAllocPoint <= m_pNextAlloc ); - - if ( pAllocPoint >= m_pBase && pAllocPoint < m_pNextAlloc ) - { - if ( bDecommit ) - { -#if defined(_WIN32) - unsigned char *pDecommitPoint = AlignValue( (unsigned char *)pAllocPoint, m_commitSize ); - - if ( pDecommitPoint < m_pBase + m_minCommit ) - { - pDecommitPoint = m_pBase + m_minCommit; - } - - unsigned decommitSize = m_pCommitLimit - pDecommitPoint; - - if ( decommitSize > 0 ) - { - MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() ); - - VirtualFree( pDecommitPoint, decommitSize, MEM_DECOMMIT ); - m_pCommitLimit = pDecommitPoint; - - if ( mark > 0 ) - { - MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); - } - } -#endif - } - m_pNextAlloc = (unsigned char *)pAllocPoint; - } -} - -//------------------------------------- - -void CMemoryStack::FreeAll( bool bDecommit ) -{ - if ( m_pBase && m_pCommitLimit - m_pBase > 0 ) - { - if ( bDecommit ) - { -#if defined(_WIN32) - MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() ); - - VirtualFree( m_pBase, m_pCommitLimit - m_pBase, MEM_DECOMMIT ); - m_pCommitLimit = m_pBase; -#endif - } - m_pNextAlloc = m_pBase; - } -} - -//------------------------------------- - -void CMemoryStack::Access( void **ppRegion, unsigned *pBytes ) -{ - *ppRegion = m_pBase; - *pBytes = ( m_pNextAlloc - m_pBase); -} - -//------------------------------------- - -void CMemoryStack::PrintContents() -{ - Msg( "Total used memory: %d\n", GetUsed() ); - Msg( "Total committed memory: %d\n", GetSize() ); -} - -//----------------------------------------------------------------------------- diff --git a/Resources/NetHook/tier1/memstack.h b/Resources/NetHook/tier1/memstack.h deleted file mode 100644 index 8ebebb01..00000000 --- a/Resources/NetHook/tier1/memstack.h +++ /dev/null @@ -1,204 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: A fast stack memory allocator that uses virtual memory if available -// -//=============================================================================// - -#ifndef MEMSTACK_H -#define MEMSTACK_H - -#if defined( _WIN32 ) -#pragma once -#endif - -//----------------------------------------------------------------------------- - -typedef unsigned MemoryStackMark_t; - -class CMemoryStack -{ -public: - CMemoryStack(); - ~CMemoryStack(); - - bool Init( unsigned maxSize = 0, unsigned commitSize = 0, unsigned initialCommit = 0, unsigned alignment = 16 ); -#ifdef _X360 - bool InitPhysical( unsigned size = 0, unsigned alignment = 16 ); -#endif - void Term(); - - int GetSize(); - int GetMaxSize(); - int GetUsed(); - - void *Alloc( unsigned bytes, bool bClear = false ) RESTRICT; - - MemoryStackMark_t GetCurrentAllocPoint(); - void FreeToAllocPoint( MemoryStackMark_t mark, bool bDecommit = true ); - void FreeAll( bool bDecommit = true ); - - void Access( void **ppRegion, unsigned *pBytes ); - - void PrintContents(); - - void *GetBase(); - const void *GetBase() const { return const_cast(this)->GetBase(); } - -private: - bool CommitTo( byte * ) RESTRICT; - - byte *m_pNextAlloc; - byte *m_pCommitLimit; - byte *m_pAllocLimit; - - byte *m_pBase; - - unsigned m_maxSize; - unsigned m_alignment; -#ifdef _WIN32 - unsigned m_commitSize; - unsigned m_minCommit; -#endif -#ifdef _X360 - bool m_bPhysical; -#endif -}; - -//------------------------------------- - -FORCEINLINE void *CMemoryStack::Alloc( unsigned bytes, bool bClear ) RESTRICT -{ - Assert( m_pBase ); - - int alignment = m_alignment; - if ( bytes ) - { - bytes = AlignValue( bytes, alignment ); - } - else - { - bytes = alignment; - } - - - void *pResult = m_pNextAlloc; - byte *pNextAlloc = m_pNextAlloc + bytes; - - if ( pNextAlloc > m_pCommitLimit ) - { - if ( !CommitTo( pNextAlloc ) ) - { - return NULL; - } - } - - if ( bClear ) - { - memset( pResult, 0, bytes ); - } - - m_pNextAlloc = pNextAlloc; - - return pResult; -} - -//------------------------------------- - -inline int CMemoryStack::GetMaxSize() -{ - return m_maxSize; -} - -//------------------------------------- - -inline int CMemoryStack::GetUsed() -{ - return ( m_pNextAlloc - m_pBase ); -} - -//------------------------------------- - -inline void *CMemoryStack::GetBase() -{ - return m_pBase; -} - -//------------------------------------- - -inline MemoryStackMark_t CMemoryStack::GetCurrentAllocPoint() -{ - return ( m_pNextAlloc - m_pBase ); -} - -//----------------------------------------------------------------------------- -// The CUtlMemoryStack class: -// A fixed memory class -//----------------------------------------------------------------------------- -template< typename T, typename I, size_t MAX_SIZE, size_t COMMIT_SIZE = 0, size_t INITIAL_COMMIT = 0 > -class CUtlMemoryStack -{ -public: - // constructor, destructor - CUtlMemoryStack( int nGrowSize = 0, int nInitSize = 0 ) { m_MemoryStack.Init( MAX_SIZE * sizeof(T), COMMIT_SIZE * sizeof(T), INITIAL_COMMIT * sizeof(T), 4 ); COMPILE_TIME_ASSERT( sizeof(T) % 4 == 0 ); } - CUtlMemoryStack( T* pMemory, int numElements ) { Assert( 0 ); } - - // Can we use this index? - bool IsIdxValid( I i ) const { return (i >= 0) && (i < m_nAllocated); } - static int InvalidIndex() { return -1; } - - class Iterator_t - { - Iterator_t( I i ) : index( i ) {} - I index; - friend class CUtlMemoryStack; - public: - bool operator==( const Iterator_t it ) const { return index == it.index; } - bool operator!=( const Iterator_t it ) const { return index != it.index; } - }; - Iterator_t First() const { return Iterator_t( m_nAllocated ? 0 : InvalidIndex() ); } - Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.index < m_nAllocated ? it.index + 1 : InvalidIndex() ); } - I GetIndex( const Iterator_t &it ) const { return it.index; } - bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; } - bool IsValidIterator( const Iterator_t &it ) const { return it.index >= 0 && it.index < m_nAllocated; } - Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); } - - // Gets the base address - T* Base() { return (T*)m_MemoryStack.GetBase(); } - const T* Base() const { return (const T*)m_MemoryStack.GetBase(); } - - // element access - T& operator[]( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; } - const T& operator[]( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; } - T& Element( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; } - const T& Element( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; } - - // Attaches the buffer to external memory.... - void SetExternalBuffer( T* pMemory, int numElements ) { Assert( 0 ); } - - // Size - int NumAllocated() const { return m_nAllocated; } - int Count() const { return m_nAllocated; } - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow( int num = 1 ) { Assert( num > 0 ); m_nAllocated += num; m_MemoryStack.Alloc( num * sizeof(T) ); } - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ) { Assert( num <= MAX_SIZE ); if ( m_nAllocated < num ) Grow( num - m_nAllocated ); } - - // Memory deallocation - void Purge() { m_MemoryStack.FreeAll(); m_nAllocated = 0; } - - // is the memory externally allocated? - bool IsExternallyAllocated() const { return false; } - - // Set the size by which the memory grows - void SetGrowSize( int size ) {} - -private: - CMemoryStack m_MemoryStack; - int m_nAllocated; -}; - -//----------------------------------------------------------------------------- - -#endif // MEMSTACK_H diff --git a/Resources/NetHook/tier1/netadr.h b/Resources/NetHook/tier1/netadr.h deleted file mode 100644 index e03e7be9..00000000 --- a/Resources/NetHook/tier1/netadr.h +++ /dev/null @@ -1,70 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -// netadr.h -#ifndef NETADR_H -#define NETADR_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/platform.h" -#undef SetPort - -typedef enum -{ - NA_NULL = 0, - NA_LOOPBACK, - NA_BROADCAST, - NA_IP, -} netadrtype_t; - -typedef struct netadr_s -{ -public: - netadr_s() { SetIP( 0 ); SetPort( 0 ); SetType( NA_IP ); } - netadr_s( uint unIP, uint16 usPort ) { SetIP( unIP ); SetPort( usPort ); SetType( NA_IP ); } - netadr_s( const char *pch ) { SetFromString( pch ); } - void Clear(); // invalids Address - - void SetType( netadrtype_t type ); - void SetPort( unsigned short port ); - bool SetFromSockadr(const struct sockaddr *s); - void SetIP(uint8 b1, uint8 b2, uint8 b3, uint8 b4); - void SetIP(uint unIP); // Sets IP. unIP is in host order (little-endian) - void SetIPAndPort( uint unIP, unsigned short usPort ) { SetIP( unIP ); SetPort( usPort ); } - void SetFromString(const char *pch, bool bUseDNS = false ); // if bUseDNS is true then do a DNS lookup if needed - - bool CompareAdr (const netadr_s &a, bool onlyBase = false) const; - bool CompareClassBAdr (const netadr_s &a) const; - bool CompareClassCAdr (const netadr_s &a) const; - - netadrtype_t GetType() const; - unsigned short GetPort() const; - const char* ToString( bool onlyBase = false ) const; // returns xxx.xxx.xxx.xxx:ppppp - void ToSockadr(struct sockaddr *s) const; - unsigned int GetIP() const; - - bool IsLocalhost() const; // true, if this is the localhost IP - bool IsLoopback() const; // true if engine loopback buffers are used - bool IsReservedAdr() const; // true, if this is a private LAN IP - bool IsValid() const; // ip & port != 0 - void SetFromSocket( int hSocket ); - // These function names are decorated because the Xbox360 defines macros for ntohl and htonl - unsigned long addr_ntohl() const; - unsigned long addr_htonl() const; - bool operator==(const netadr_s &netadr) const {return ( CompareAdr( netadr ) );} - bool operator<(const netadr_s &netadr) const; - -public: // members are public to avoid to much changes - - netadrtype_t type; - unsigned char ip[4]; - unsigned short port; -} netadr_t; - -#endif // NETADR_H diff --git a/Resources/NetHook/tier1/newbitbuf.cpp b/Resources/NetHook/tier1/newbitbuf.cpp deleted file mode 100644 index 5fdfa986..00000000 --- a/Resources/NetHook/tier1/newbitbuf.cpp +++ /dev/null @@ -1,713 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - -#include "bitbuf.h" -#include "coordsize.h" -#include "mathlib/vector.h" -#include "mathlib/mathlib.h" -#include "tier1/strtools.h" -#include "bitvec.h" - -// FIXME: Can't use this until we get multithreaded allocations in tier0 working for tools -// This is used by VVIS and fails to link -// NOTE: This must be the last file included!!! -//#include "tier0/memdbgon.h" - -#ifdef _X360 -// mandatory ... wary of above comment and isolating, tier0 is built as MT though -#include "tier0/memdbgon.h" -#endif - -#include "stdio.h" - -void CBitWrite::StartWriting( void *pData, int nBytes, int iStartBit, int nBits ) -{ - // Make sure it's dword aligned and padded. - Assert( (nBytes % 4) == 0 ); - Assert(((unsigned long)pData & 3) == 0); - Assert( iStartBit == 0 ); - m_pData = (uint32 *) pData; - m_pDataOut = m_pData; - m_nDataBytes = nBytes; - - if ( nBits == -1 ) - { - m_nDataBits = nBytes << 3; - } - else - { - Assert( nBits <= nBytes*8 ); - m_nDataBits = nBits; - } - m_bOverflow = false; - m_nOutBufWord = 0; - m_nOutBitsAvail = 32; - m_pBufferEnd = m_pDataOut + ( nBytes >> 2 ); -} - -const uint32 CBitBuffer::s_nMaskTable[33] = { - 0, - ( 1 << 1 ) - 1, - ( 1 << 2 ) - 1, - ( 1 << 3 ) - 1, - ( 1 << 4 ) - 1, - ( 1 << 5 ) - 1, - ( 1 << 6 ) - 1, - ( 1 << 7 ) - 1, - ( 1 << 8 ) - 1, - ( 1 << 9 ) - 1, - ( 1 << 10 ) - 1, - ( 1 << 11 ) - 1, - ( 1 << 12 ) - 1, - ( 1 << 13 ) - 1, - ( 1 << 14 ) - 1, - ( 1 << 15 ) - 1, - ( 1 << 16 ) - 1, - ( 1 << 17 ) - 1, - ( 1 << 18 ) - 1, - ( 1 << 19 ) - 1, - ( 1 << 20 ) - 1, - ( 1 << 21 ) - 1, - ( 1 << 22 ) - 1, - ( 1 << 23 ) - 1, - ( 1 << 24 ) - 1, - ( 1 << 25 ) - 1, - ( 1 << 26 ) - 1, - ( 1 << 27 ) - 1, - ( 1 << 28 ) - 1, - ( 1 << 29 ) - 1, - ( 1 << 30 ) - 1, - 0x7fffffff, - 0xffffffff, -}; - -bool CBitWrite::WriteString( const char *pStr ) -{ - if(pStr) - { - while( *pStr ) - { - WriteChar( * ( pStr++ ) ); - } - } - WriteChar( 0 ); - return !IsOverflowed(); -} - - -void CBitWrite::WriteLongLong(int64 val) -{ - uint *pLongs = (uint*)&val; - - // Insert the two DWORDS according to network endian - const short endianIndex = 0x0100; - byte *idx = (byte*)&endianIndex; - WriteUBitLong(pLongs[*idx++], sizeof(long) << 3); - WriteUBitLong(pLongs[*idx], sizeof(long) << 3); -} - -bool CBitWrite::WriteBits(const void *pInData, int nBits) -{ - unsigned char *pOut = (unsigned char*)pInData; - int nBitsLeft = nBits; - - // Bounds checking.. - if ( ( GetNumBitsWritten() + nBits) > m_nDataBits ) - { - SetOverflowFlag(); - CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, m_pDebugName ); - return false; - } - - // !! speed!! need fast paths - // write remaining bytes - while ( nBitsLeft >= 8 ) - { - WriteUBitLong( *pOut, 8, false ); - ++pOut; - nBitsLeft -= 8; - } - - // write remaining bits - if ( nBitsLeft ) - { - WriteUBitLong( *pOut, nBitsLeft, false ); - } - - return !IsOverflowed(); -} - -void CBitWrite::WriteBytes( const void *pBuf, int nBytes ) -{ - WriteBits(pBuf, nBytes << 3); -} - -void CBitWrite::WriteBitCoord (const float f) -{ - int signbit = (f <= -COORD_RESOLUTION); - int intval = (int)abs(f); - int fractval = abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1); - - - // Send the bit flags that indicate whether we have an integer part and/or a fraction part. - WriteOneBit( intval ); - WriteOneBit( fractval ); - - if ( intval || fractval ) - { - // Send the sign bit - WriteOneBit( signbit ); - - // Send the integer if we have one. - if ( intval ) - { - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - - // Send the fraction if we have one - if ( fractval ) - { - WriteUBitLong( (unsigned int)fractval, COORD_FRACTIONAL_BITS ); - } - } -} - -void CBitWrite::WriteBitCoordMP (const float f, bool bIntegral, bool bLowPrecision ) -{ - int signbit = (f <= -( bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION )); - int intval = (int)abs(f); - int fractval = bLowPrecision ? - ( abs((int)(f*COORD_DENOMINATOR_LOWPRECISION)) & (COORD_DENOMINATOR_LOWPRECISION-1) ) : - ( abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1) ); - - bool bInBounds = intval < (1 << COORD_INTEGER_BITS_MP ); - - WriteOneBit( bInBounds ); - - if ( bIntegral ) - { - // Send the sign bit - WriteOneBit( intval ); - if ( intval ) - { - WriteOneBit( signbit ); - // Send the integer if we have one. - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - if ( bInBounds ) - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS_MP ); - } - else - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - } - } - else - { - // Send the bit flags that indicate whether we have an integer part and/or a fraction part. - WriteOneBit( intval ); - // Send the sign bit - WriteOneBit( signbit ); - - // Send the integer if we have one. - if ( intval ) - { - // Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1] - intval--; - if ( bInBounds ) - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS_MP ); - } - else - { - WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS ); - } - } - WriteUBitLong( (unsigned int)fractval, bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS ); - } -} - -void CBitWrite::SeekToBit( int nBit ) -{ - TempFlush(); - m_pDataOut = m_pData + ( nBit / 32 ); - m_nOutBufWord = *( m_pDataOut ); - m_nOutBitsAvail = 32 - ( nBit & 31 ); -} - - - -void CBitWrite::WriteBitVec3Coord( const Vector& fa ) -{ - int xflag, yflag, zflag; - - xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION); - yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION); - zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION); - - WriteOneBit( xflag ); - WriteOneBit( yflag ); - WriteOneBit( zflag ); - - if ( xflag ) - WriteBitCoord( fa[0] ); - if ( yflag ) - WriteBitCoord( fa[1] ); - if ( zflag ) - WriteBitCoord( fa[2] ); -} - -void CBitWrite::WriteBitNormal( float f ) -{ - int signbit = (f <= -NORMAL_RESOLUTION); - - // NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones - unsigned int fractval = abs( (int)(f*NORMAL_DENOMINATOR) ); - - // clamp.. - if (fractval > NORMAL_DENOMINATOR) - fractval = NORMAL_DENOMINATOR; - - // Send the sign bit - WriteOneBit( signbit ); - - // Send the fractional component - WriteUBitLong( fractval, NORMAL_FRACTIONAL_BITS ); -} - -void CBitWrite::WriteBitVec3Normal( const Vector& fa ) -{ - int xflag, yflag; - - xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION); - yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION); - - WriteOneBit( xflag ); - WriteOneBit( yflag ); - - if ( xflag ) - WriteBitNormal( fa[0] ); - if ( yflag ) - WriteBitNormal( fa[1] ); - - // Write z sign bit - int signbit = (fa[2] <= -NORMAL_RESOLUTION); - WriteOneBit( signbit ); -} - -void CBitWrite::WriteBitAngle( float fAngle, int numbits ) -{ - - unsigned int shift = GetBitForBitnum(numbits); - unsigned int mask = shift - 1; - - int d = (int)( (fAngle / 360.0) * shift ); - d &= mask; - - WriteUBitLong((unsigned int)d, numbits); -} - -bool CBitWrite::WriteBitsFromBuffer( bf_read *pIn, int nBits ) -{ -// This could be optimized a little by - while ( nBits > 32 ) - { - WriteUBitLong( pIn->ReadUBitLong( 32 ), 32 ); - nBits -= 32; - } - - WriteUBitLong( pIn->ReadUBitLong( nBits ), nBits ); - return !IsOverflowed() && !pIn->IsOverflowed(); -} - -void CBitWrite::WriteBitAngles( const QAngle& fa ) -{ - // FIXME: - Vector tmp( fa.x, fa.y, fa.z ); - WriteBitVec3Coord( tmp ); -} - -bool CBitRead::Seek( int nPosition ) -{ - bool bSucc = true; - if ( nPosition < 0 || nPosition > m_nDataBits) - { - SetOverflowFlag(); - bSucc = false; - nPosition = m_nDataBits; - } - int nHead = m_nDataBytes & 3; // non-multiple-of-4 bytes at head of buffer. We put the "round off" - // at the head to make reading and detecting the end efficient. - - int nByteOfs = nPosition / 8; - if ( ( m_nDataBytes < 4 ) || ( nHead && ( nByteOfs < nHead ) ) ) - { - // partial first dword - uint8 const *pPartial = ( uint8 const *) m_pData; - if ( m_pData ) - { - m_nInBufWord = *( pPartial++ ); - if ( nHead > 1 ) - m_nInBufWord |= ( *pPartial++ ) << 8; - if ( nHead > 2 ) - m_nInBufWord |= ( *pPartial++ ) << 16; - } - m_pDataIn = ( uint32 const * ) pPartial; - m_nInBufWord >>= ( nPosition & 31 ); - m_nBitsAvail = ( nHead << 3 ) - ( nPosition & 31 ); - } - else - { - int nAdjPosition = nPosition - ( nHead << 3 ); - m_pDataIn = reinterpret_cast ( - reinterpret_cast( m_pData ) + ( ( nAdjPosition / 32 ) << 2 ) + nHead ); - if ( m_pData ) - { - m_nBitsAvail = 32; - GrabNextDWord(); - } - else - { - m_nInBufWord = 0; - m_nBitsAvail = 1; - } - m_nInBufWord >>= ( nAdjPosition & 31 ); - m_nBitsAvail = min( m_nBitsAvail, 32 - ( nAdjPosition & 31 ) ); // in case grabnextdword overflowed - } - return bSucc; -} - - -void CBitRead::StartReading( const void *pData, int nBytes, int iStartBit, int nBits ) -{ -// Make sure it's dword aligned and padded. - Assert(((unsigned long)pData & 3) == 0); - m_pData = (uint32 *) pData; - m_pDataIn = m_pData; - m_nDataBytes = nBytes; - - if ( nBits == -1 ) - { - m_nDataBits = nBytes << 3; - } - else - { - Assert( nBits <= nBytes*8 ); - m_nDataBits = nBits; - } - m_bOverflow = false; - m_pBufferEnd = reinterpret_cast ( reinterpret_cast< uint8 const *> (m_pData) + nBytes ); - if ( m_pData ) - Seek( iStartBit ); - -} - -bool CBitRead::ReadString( char *pStr, int maxLen, bool bLine, int *pOutNumChars ) -{ - Assert( maxLen != 0 ); - - bool bTooSmall = false; - int iChar = 0; - while(1) - { - char val = ReadChar(); - if ( val == 0 ) - break; - else if ( bLine && val == '\n' ) - break; - - if ( iChar < (maxLen-1) ) - { - pStr[iChar] = val; - ++iChar; - } - else - { - bTooSmall = true; - } - } - - // Make sure it's null-terminated. - Assert( iChar < maxLen ); - pStr[iChar] = 0; - - if ( pOutNumChars ) - *pOutNumChars = iChar; - - return !IsOverflowed() && !bTooSmall; -} - -char* CBitRead::ReadAndAllocateString( bool *pOverflow ) -{ - char str[2048]; - - int nChars; - bool bOverflow = !ReadString( str, sizeof( str ), false, &nChars ); - if ( pOverflow ) - *pOverflow = bOverflow; - - // Now copy into the output and return it; - char *pRet = new char[ nChars + 1 ]; - for ( int i=0; i <= nChars; i++ ) - pRet[i] = str[i]; - - return pRet; -} - -int64 CBitRead::ReadLongLong( void ) -{ - int64 retval; - uint *pLongs = (uint*)&retval; - - // Read the two DWORDs according to network endian - const short endianIndex = 0x0100; - byte *idx = (byte*)&endianIndex; - pLongs[*idx++] = ReadUBitLong(sizeof(long) << 3); - pLongs[*idx] = ReadUBitLong(sizeof(long) << 3); - return retval; -} - -void CBitRead::ReadBits(void *pOutData, int nBits) -{ - unsigned char *pOut = (unsigned char*)pOutData; - int nBitsLeft = nBits; - - - // align output to dword boundary - while( ((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8 ) - { - *pOut = (unsigned char)ReadUBitLong(8); - ++pOut; - nBitsLeft -= 8; - } - - // X360TBD: Can't read dwords in ReadBits because they'll get swapped - if ( IsPC() ) - { - // read dwords - while ( nBitsLeft >= 32 ) - { - *((unsigned long*)pOut) = ReadUBitLong(32); - pOut += sizeof(unsigned long); - nBitsLeft -= 32; - } - } - - // read remaining bytes - while ( nBitsLeft >= 8 ) - { - *pOut = ReadUBitLong(8); - ++pOut; - nBitsLeft -= 8; - } - - // read remaining bits - if ( nBitsLeft ) - { - *pOut = ReadUBitLong(nBitsLeft); - } - -} - -bool CBitRead::ReadBytes(void *pOut, int nBytes) -{ - ReadBits(pOut, nBytes << 3); - return !IsOverflowed(); -} - -float CBitRead::ReadBitAngle( int numbits ) -{ - float shift = (float)( GetBitForBitnum(numbits) ); - - int i = ReadUBitLong( numbits ); - float fReturn = (float)i * (360.0 / shift); - - return fReturn; -} - -// Basic Coordinate Routines (these contain bit-field size AND fixed point scaling constants) -float CBitRead::ReadBitCoord (void) -{ - int intval=0,fractval=0,signbit=0; - float value = 0.0; - - - // Read the required integer and fraction flags - intval = ReadOneBit(); - fractval = ReadOneBit(); - - // If we got either parse them, otherwise it's a zero. - if ( intval || fractval ) - { - // Read the sign bit - signbit = ReadOneBit(); - - // If there's an integer, read it in - if ( intval ) - { - // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] - intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - - // If there's a fraction, read it in - if ( fractval ) - { - fractval = ReadUBitLong( COORD_FRACTIONAL_BITS ); - } - - // Calculate the correct floating point value - value = intval + ((float)fractval * COORD_RESOLUTION); - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - } - - return value; -} - -float CBitRead::ReadBitCoordMP( bool bIntegral, bool bLowPrecision ) -{ - int intval=0,fractval=0,signbit=0; - float value = 0.0; - - bool bInBounds = ReadOneBit() ? true : false; - - if ( bIntegral ) - { - // Read the required integer and fraction flags - intval = ReadOneBit(); - // If we got either parse them, otherwise it's a zero. - if ( intval ) - { - // Read the sign bit - signbit = ReadOneBit(); - - // If there's an integer, read it in - // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] - if ( bInBounds ) - { - value = ReadUBitLong( COORD_INTEGER_BITS_MP ) + 1; - } - else - { - value = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - } - } - else - { - // Read the required integer and fraction flags - intval = ReadOneBit(); - - // Read the sign bit - signbit = ReadOneBit(); - - // If we got either parse them, otherwise it's a zero. - if ( intval ) - { - if ( bInBounds ) - { - intval = ReadUBitLong( COORD_INTEGER_BITS_MP ) + 1; - } - else - { - intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1; - } - } - - // If there's a fraction, read it in - fractval = ReadUBitLong( bLowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS ); - - // Calculate the correct floating point value - value = intval + ((float)fractval * ( bLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION ) ); - } - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - - return value; -} - -void CBitRead::ReadBitVec3Coord( Vector& fa ) -{ - int xflag, yflag, zflag; - - // This vector must be initialized! Otherwise, If any of the flags aren't set, - // the corresponding component will not be read and will be stack garbage. - fa.Init( 0, 0, 0 ); - - xflag = ReadOneBit(); - yflag = ReadOneBit(); - zflag = ReadOneBit(); - - if ( xflag ) - fa[0] = ReadBitCoord(); - if ( yflag ) - fa[1] = ReadBitCoord(); - if ( zflag ) - fa[2] = ReadBitCoord(); -} - -float CBitRead::ReadBitNormal (void) -{ - // Read the sign bit - int signbit = ReadOneBit(); - - // Read the fractional part - unsigned int fractval = ReadUBitLong( NORMAL_FRACTIONAL_BITS ); - - // Calculate the correct floating point value - float value = (float)fractval * NORMAL_RESOLUTION; - - // Fixup the sign if negative. - if ( signbit ) - value = -value; - - return value; -} - -void CBitRead::ReadBitVec3Normal( Vector& fa ) -{ - int xflag = ReadOneBit(); - int yflag = ReadOneBit(); - - if (xflag) - fa[0] = ReadBitNormal(); - else - fa[0] = 0.0f; - - if (yflag) - fa[1] = ReadBitNormal(); - else - fa[1] = 0.0f; - - // The first two imply the third (but not its sign) - int znegative = ReadOneBit(); - - float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1]; - if (fafafbfb < 1.0f) - fa[2] = sqrt( 1.0f - fafafbfb ); - else - fa[2] = 0.0f; - - if (znegative) - fa[2] = -fa[2]; -} - -void CBitRead::ReadBitAngles( QAngle& fa ) -{ - Vector tmp; - ReadBitVec3Coord( tmp ); - fa.Init( tmp.x, tmp.y, tmp.z ); -} diff --git a/Resources/NetHook/tier1/processor_detect.cpp b/Resources/NetHook/tier1/processor_detect.cpp deleted file mode 100644 index 2639ec88..00000000 --- a/Resources/NetHook/tier1/processor_detect.cpp +++ /dev/null @@ -1,278 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: win32 dependant ASM code for CPU capability detection -// -// $Workfile: $ -// $NoKeywords: $ -//=============================================================================// - -#ifdef _LINUX - -#include "processor_detect_linux.cpp" - -#elif defined( _X360 ) - -bool CheckMMXTechnology(void) { return false; } -bool CheckSSETechnology(void) { return false; } -bool CheckSSE2Technology(void) { return false; } -bool Check3DNowTechnology(void) { return false; } - -#elif defined( _WIN32 ) && !defined( _X360 ) - -#pragma optimize( "", off ) -#pragma warning( disable: 4800 ) //'int' : forcing value to bool 'true' or 'false' (performance warning) - -// stuff from windows.h -#ifndef EXCEPTION_EXECUTE_HANDLER -#define EXCEPTION_EXECUTE_HANDLER 1 -#endif - -bool CheckMMXTechnology(void) -{ - int retval = true; - unsigned int RegEDX = 0; - -#ifdef CPUID - _asm pushad; -#endif - - __try - { - _asm - { -#ifdef CPUID - xor edx, edx // Clue the compiler that EDX is about to be used. -#endif - mov eax, 1 // set up CPUID to return processor version and features - // 0 = vendor string, 1 = version info, 2 = cache info - CPUID // code bytes = 0fh, 0a2h - mov RegEDX, edx // features returned in edx - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - - // If CPUID not supported, then certainly no MMX extensions. - if (retval) - { - if (RegEDX & 0x800000) // bit 23 is set for MMX technology - { - __try - { - // try executing the MMX instruction "emms" - _asm EMMS - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - } - - else - retval = false; // processor supports CPUID but does not support MMX technology - - // if retval == 0 here, it means the processor has MMX technology but - // floating-point emulation is on; so MMX technology is unavailable - } - -#ifdef CPUID - _asm popad; -#endif - - return retval; -} - -bool CheckSSETechnology(void) -{ - int retval = true; - unsigned int RegEDX = 0; - -#ifdef CPUID - _asm pushad; -#endif - - // Do we have support for the CPUID function? - __try - { - _asm - { -#ifdef CPUID - xor edx, edx // Clue the compiler that EDX is about to be used. -#endif - mov eax, 1 // set up CPUID to return processor version and features - // 0 = vendor string, 1 = version info, 2 = cache info - CPUID // code bytes = 0fh, 0a2h - mov RegEDX, edx // features returned in edx - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - - // If CPUID not supported, then certainly no SSE extensions. - if (retval) - { - // Do we have support for SSE in this processor? - if ( RegEDX & 0x2000000L ) // bit 25 is set for SSE technology - { - // Make sure that SSE is supported by executing an inline SSE instruction - -// BUGBUG, FIXME - Visual C Version 6.0 does not support SSE inline code YET (No macros from Intel either) -// Fix this if VC7 supports inline SSE instructinons like "xorps" as shown below. -#if 1 - __try - { - _asm - { - // Attempt execution of a SSE instruction to make sure OS supports SSE FPU context switches - xorps xmm0, xmm0 - // This will work on Win2k+ (Including masking SSE FPU exception to "normalized" values) - // This will work on Win98+ (But no "masking" of FPU exceptions provided) - } - } - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - - { - retval = false; - } - } - else - retval = false; - } -#ifdef CPUID - _asm popad; -#endif - - return retval; -} - -bool CheckSSE2Technology(void) -{ - int retval = true; - unsigned int RegEDX = 0; - -#ifdef CPUID - _asm pushad; -#endif - - // Do we have support for the CPUID function? - __try - { - _asm - { -#ifdef CPUID - xor edx, edx // Clue the compiler that EDX is about to be used. -#endif - mov eax, 1 // set up CPUID to return processor version and features - // 0 = vendor string, 1 = version info, 2 = cache info - CPUID // code bytes = 0fh, 0a2h - mov RegEDX, edx // features returned in edx - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - - // If CPUID not supported, then certainly no SSE extensions. - if (retval) - { - // Do we have support for SSE in this processor? - if ( RegEDX & 0x04000000 ) // bit 26 is set for SSE2 technology - { - // Make sure that SSE is supported by executing an inline SSE instruction - - __try - { - _asm - { - // Attempt execution of a SSE2 instruction to make sure OS supports SSE FPU context switches - xorpd xmm0, xmm0 - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - - { - retval = false; - } - } - else - retval = false; - } -#ifdef CPUID - _asm popad; -#endif - - return retval; -} - -bool Check3DNowTechnology(void) -{ - int retval = true; - unsigned int RegEAX = 0; - -#ifdef CPUID - _asm pushad; -#endif - - // First see if we can execute CPUID at all - __try - { - _asm - { -#ifdef CPUID -// xor edx, edx // Clue the compiler that EDX is about to be used. -#endif - mov eax, 0x80000000 // setup CPUID to return whether AMD >0x80000000 function are supported. - // 0x80000000 = Highest 0x80000000+ function, 0x80000001 = 3DNow support - CPUID // code bytes = 0fh, 0a2h - mov RegEAX, eax // result returned in eax - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - - // If CPUID not supported, then there is definitely no 3DNow support - if (retval) - { - // Are there any "higher" AMD CPUID functions? - if (RegEAX > 0x80000000L ) - { - __try - { - _asm - { - mov eax, 0x80000001 // setup to test for CPU features - CPUID // code bytes = 0fh, 0a2h - shr edx, 31 // If bit 31 is set, we have 3DNow support! - mov retval, edx // Save the return value for end of function - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - retval = false; - } - } - else - { - // processor supports CPUID but does not support AMD CPUID functions - retval = false; - } - } - -#ifdef CPUID - _asm popad; -#endif - - return retval; -} - -#pragma optimize( "", on ) - -#endif // _WIN32 diff --git a/Resources/NetHook/tier1/processor_detect.h b/Resources/NetHook/tier1/processor_detect.h deleted file mode 100644 index 64cb5559..00000000 --- a/Resources/NetHook/tier1/processor_detect.h +++ /dev/null @@ -1,12 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: functions to expose CPU capabilities -// -// $NoKeywords: $ -//=============================================================================// - -bool CheckMMXTechnology(void); -bool CheckSSETechnology(void); -bool CheckSSE2Technology(void); -bool Check3DNowTechnology(void); - diff --git a/Resources/NetHook/tier1/processor_detect_linux.cpp b/Resources/NetHook/tier1/processor_detect_linux.cpp deleted file mode 100644 index b09df0e0..00000000 --- a/Resources/NetHook/tier1/processor_detect_linux.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: linux dependant ASM code for CPU capability detection -// -// $Workfile: $ -// $NoKeywords: $ -//=============================================================================// - -#define cpuid(in,a,b,c,d) \ - asm("pushl %%ebx\n\t" "cpuid\n\t" "movl %%ebx,%%esi\n\t" "pop %%ebx": "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (in)); - -bool CheckMMXTechnology(void) -{ - unsigned long eax,ebx,edx,unused; - cpuid(1,eax,ebx,unused,edx); - - return edx & 0x800000; -} - -bool CheckSSETechnology(void) -{ - unsigned long eax,ebx,edx,unused; - cpuid(1,eax,ebx,unused,edx); - - return edx & 0x2000000L; -} - -bool CheckSSE2Technology(void) -{ - unsigned long eax,ebx,edx,unused; - cpuid(1,eax,ebx,unused,edx); - - return edx & 0x04000000; -} - -bool Check3DNowTechnology(void) -{ - unsigned long eax, unused; - cpuid(0x80000000,eax,unused,unused,unused); - - if ( eax > 0x80000000L ) - { - cpuid(0x80000001,unused,unused,unused,eax); - return ( eax & 1<<31 ); - } - return false; -} diff --git a/Resources/NetHook/tier1/rangecheckedvar.cpp b/Resources/NetHook/tier1/rangecheckedvar.cpp deleted file mode 100644 index a342dcd9..00000000 --- a/Resources/NetHook/tier1/rangecheckedvar.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "rangecheckedvar.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -bool g_bDoRangeChecks = true; - - -static int g_nDisables = 0; - - -CDisableRangeChecks::CDisableRangeChecks() -{ - if ( !ThreadInMainThread() ) - return; - g_nDisables++; - g_bDoRangeChecks = false; -} - - -CDisableRangeChecks::~CDisableRangeChecks() -{ - if ( !ThreadInMainThread() ) - return; - Assert( g_nDisables > 0 ); - --g_nDisables; - if ( g_nDisables == 0 ) - { - g_bDoRangeChecks = true; - } -} - - - - diff --git a/Resources/NetHook/tier1/rangecheckedvar.h b/Resources/NetHook/tier1/rangecheckedvar.h deleted file mode 100644 index cf04e7b9..00000000 --- a/Resources/NetHook/tier1/rangecheckedvar.h +++ /dev/null @@ -1,113 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#ifndef RANGECHECKEDVAR_H -#define RANGECHECKEDVAR_H -#ifdef _WIN32 -#pragma once -#endif - - -#include "tier0/dbg.h" -#include "tier0/threadtools.h" -#include "mathlib/vector.h" -#include - - -// Use this to disable range checks within a scope. -class CDisableRangeChecks -{ -public: - CDisableRangeChecks(); - ~CDisableRangeChecks(); -}; - - -template< class T > -inline void RangeCheck( const T &value, int minValue, int maxValue ) -{ -#ifdef _DEBUG - extern bool g_bDoRangeChecks; - if ( ThreadInMainThread() && g_bDoRangeChecks ) - { - // Ignore the min/max stuff for now.. just make sure it's not a NAN. - Assert( _finite( value ) ); - } -#endif -} - -inline void RangeCheck( const Vector &value, int minValue, int maxValue ) -{ -#ifdef _DEBUG - RangeCheck( value.x, minValue, maxValue ); - RangeCheck( value.y, minValue, maxValue ); - RangeCheck( value.z, minValue, maxValue ); -#endif -} - - -template< class T, int minValue, int maxValue, int startValue > -class CRangeCheckedVar -{ -public: - - inline CRangeCheckedVar() - { - m_Val = startValue; - } - - inline CRangeCheckedVar( const T &value ) - { - *this = value; - } - - // Clamp the value to its limits. Interpolation code uses this after interpolating. - inline void Clamp() - { - if ( m_Val < minValue ) - m_Val = minValue; - else if ( m_Val > maxValue ) - m_Val = maxValue; - } - - inline operator const T&() const - { - return m_Val; - } - - inline CRangeCheckedVar& operator=( const T &value ) - { - RangeCheck( value, minValue, maxValue ); - m_Val = value; - return *this; - } - - inline CRangeCheckedVar& operator+=( const T &value ) - { - return (*this = m_Val + value); - } - - inline CRangeCheckedVar& operator-=( const T &value ) - { - return (*this = m_Val - value); - } - - inline CRangeCheckedVar& operator*=( const T &value ) - { - return (*this = m_Val * value); - } - - inline CRangeCheckedVar& operator/=( const T &value ) - { - return (*this = m_Val / value); - } - -private: - - T m_Val; -}; - -#endif // RANGECHECKEDVAR_H diff --git a/Resources/NetHook/tier1/refcount.h b/Resources/NetHook/tier1/refcount.h deleted file mode 100644 index d5a7e2d4..00000000 --- a/Resources/NetHook/tier1/refcount.h +++ /dev/null @@ -1,385 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: Tools for correctly implementing & handling reference counted -// objects -// -//============================================================================= - -#ifndef REFCOUNT_H -#define REFCOUNT_H - -#include "tier0/threadtools.h" - -#if defined( _WIN32 ) -#pragma once -#endif - -//----------------------------------------------------------------------------- -// Purpose: Implement a standard reference counted interface. Use of this -// is optional insofar as all the concrete tools only require -// at compile time that the function signatures match. -//----------------------------------------------------------------------------- - -class IRefCounted -{ -public: - virtual int AddRef() = 0; - virtual int Release() = 0; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Release a pointer and mark it NULL -//----------------------------------------------------------------------------- - -template -inline int SafeRelease( REFCOUNTED_ITEM_PTR &pRef ) -{ - // Use funny syntax so that this works on "auto pointers" - REFCOUNTED_ITEM_PTR *ppRef = &pRef; - if ( *ppRef ) - { - int result = (*ppRef)->Release(); - *ppRef = NULL; - return result; - } - return 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Maintain a reference across a scope -//----------------------------------------------------------------------------- - -template -class CAutoRef -{ -public: - CAutoRef( T *pRef ) - : m_pRef( pRef ) - { - if ( m_pRef ) - m_pRef->AddRef(); - } - - ~CAutoRef() - { - if (m_pRef) - m_pRef->Release(); - } - -private: - T *m_pRef; -}; - -//----------------------------------------------------------------------------- -// Purpose: Do a an inline AddRef then return the pointer, useful when -// returning an object from a function -//----------------------------------------------------------------------------- - -#define RetAddRef( p ) ( (p)->AddRef(), (p) ) -#define InlineAddRef( p ) ( (p)->AddRef(), (p) ) - - -//----------------------------------------------------------------------------- -// Purpose: A class to both hold a pointer to an object and its reference. -// Base exists to support other cleanup models -//----------------------------------------------------------------------------- - -template -class CBaseAutoPtr -{ -public: - CBaseAutoPtr() : m_pObject(0) {} - CBaseAutoPtr(T *pFrom) : m_pObject(pFrom) {} - - operator const void *() const { return m_pObject; } - operator void *() { return m_pObject; } - - operator const T *() const { return m_pObject; } - operator const T *() { return m_pObject; } - operator T *() { return m_pObject; } - - int operator=( int i ) { AssertMsg( i == 0, "Only NULL allowed on integer assign" ); m_pObject = 0; return 0; } - T * operator=( T *p ) { m_pObject = p; return p; } - - bool operator !() const { return ( !m_pObject ); } - bool operator!=( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (m_pObject != NULL); } - bool operator==( const void *p ) const { return ( m_pObject == p ); } - bool operator!=( const void *p ) const { return ( m_pObject != p ); } - bool operator==( T *p ) const { return operator==( (void *)p ); } - bool operator!=( T *p ) const { return operator!=( (void *)p ); } - bool operator==( const CBaseAutoPtr &p ) const { return operator==( (const void *)p ); } - bool operator!=( const CBaseAutoPtr &p ) const { return operator!=( (const void *)p ); } - - T * operator->() { return m_pObject; } - T & operator *() { return *m_pObject; } - T ** operator &() { return &m_pObject; } - - const T * operator->() const { return m_pObject; } - const T & operator *() const { return *m_pObject; } - T * const * operator &() const { return &m_pObject; } - -protected: - CBaseAutoPtr( const CBaseAutoPtr &from ) : m_pObject( from.m_pObject ) {} - void operator=( const CBaseAutoPtr &from ) { m_pObject = from.m_pObject; } - - T *m_pObject; -}; - -//--------------------------------------------------------- - -template -class CRefPtr : public CBaseAutoPtr -{ - typedef CBaseAutoPtr BaseClass; -public: - CRefPtr() {} - CRefPtr( T *pInit ) : BaseClass( pInit ) {} - CRefPtr( const CRefPtr &from ) : BaseClass( from ) {} - ~CRefPtr() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->Release(); } - - void operator=( const CRefPtr &from ) { BaseClass::operator=( from ); } - - int operator=( int i ) { return BaseClass::operator=( i ); } - T *operator=( T *p ) { return BaseClass::operator=( p ); } - - operator bool() const { return !BaseClass::operator!(); } - operator bool() { return !BaseClass::operator!(); } - - void SafeRelease() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->Release(); BaseClass::m_pObject = 0; } - void AssignAddRef( T *pFrom ) { SafeRelease(); if (pFrom) pFrom->AddRef(); BaseClass::m_pObject = pFrom; } - void AddRefAssignTo( T *&pTo ) { ::SafeRelease( pTo ); if ( BaseClass::m_pObject ) BaseClass::m_pObject->AddRef(); pTo = BaseClass::m_pObject; } -}; - - -//----------------------------------------------------------------------------- -// Purpose: Traits classes defining reference count threading model -//----------------------------------------------------------------------------- - -class CRefMT -{ -public: - static int Increment( int *p) { return ThreadInterlockedIncrement( (long *)p ); } - static int Decrement( int *p) { return ThreadInterlockedDecrement( (long *)p ); } -}; - -class CRefST -{ -public: - static int Increment( int *p) { return ++(*p); } - static int Decrement( int *p) { return --(*p); } -}; - -//----------------------------------------------------------------------------- -// Purpose: Actual reference counting implementation. Pulled out to reduce -// code bloat. -//----------------------------------------------------------------------------- - -template -class NO_VTABLE CRefCountServiceBase -{ -protected: - CRefCountServiceBase() - : m_iRefs( 1 ) - { - } - - virtual ~CRefCountServiceBase() - { - } - - virtual bool OnFinalRelease() - { - return true; - } - - int GetRefCount() const - { - return m_iRefs; - } - - int DoAddRef() - { - return CRefThreading::Increment( &m_iRefs ); - } - - int DoRelease() - { - int result = CRefThreading::Decrement( &m_iRefs ); - if ( result ) - return result; - if ( OnFinalRelease() && bSelfDelete ) - delete this; - return 0; - } - -private: - int m_iRefs; -}; - -class CRefCountServiceNull -{ -protected: - static int DoAddRef() { return 1; } - static int DoRelease() { return 1; } -}; - -template -class NO_VTABLE CRefCountServiceDestruct -{ -protected: - CRefCountServiceDestruct() - : m_iRefs( 1 ) - { - } - - virtual ~CRefCountServiceDestruct() - { - } - - int GetRefCount() const - { - return m_iRefs; - } - - int DoAddRef() - { - return CRefThreading::Increment( &m_iRefs ); - } - - int DoRelease() - { - int result = CRefThreading::Decrement( &m_iRefs ); - if ( result ) - return result; - this->~CRefCountServiceDestruct(); - return 0; - } - -private: - int m_iRefs; -}; - - -typedef CRefCountServiceBase CRefCountServiceST; -typedef CRefCountServiceBase CRefCountServiceNoDeleteST; - -typedef CRefCountServiceBase CRefCountServiceMT; -typedef CRefCountServiceBase CRefCountServiceNoDeleteMT; - -// Default to threadsafe -typedef CRefCountServiceNoDeleteMT CRefCountServiceNoDelete; -typedef CRefCountServiceMT CRefCountService; - -//----------------------------------------------------------------------------- -// Purpose: Base classes to implement reference counting -//----------------------------------------------------------------------------- - -template < class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted : public REFCOUNT_SERVICE -{ -public: - virtual ~CRefCounted() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//------------------------------------- - -template < class BASE1, class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted1 : public BASE1, - public REFCOUNT_SERVICE -{ -public: - virtual ~CRefCounted1() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//------------------------------------- - -template < class BASE1, class BASE2, class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted2 : public BASE1, public BASE2, - public REFCOUNT_SERVICE -{ -public: - virtual ~CRefCounted2() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//------------------------------------- - -template < class BASE1, class BASE2, class BASE3, class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted3 : public BASE1, public BASE2, public BASE3, - public REFCOUNT_SERVICE -{ - virtual ~CRefCounted3() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//------------------------------------- - -template < class BASE1, class BASE2, class BASE3, class BASE4, class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted4 : public BASE1, public BASE2, public BASE3, public BASE4, - public REFCOUNT_SERVICE -{ -public: - virtual ~CRefCounted4() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//------------------------------------- - -template < class BASE1, class BASE2, class BASE3, class BASE4, class BASE5, class REFCOUNT_SERVICE = CRefCountService > -class NO_VTABLE CRefCounted5 : public BASE1, public BASE2, public BASE3, public BASE4, public BASE5, - public REFCOUNT_SERVICE -{ -public: - virtual ~CRefCounted5() {} - int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } - int Release() { return REFCOUNT_SERVICE::DoRelease(); } -}; - -//----------------------------------------------------------------------------- -// Purpose: Class to throw around a reference counted item to debug -// referencing problems -//----------------------------------------------------------------------------- - -template -class CRefDebug : public BASE_REFCOUNTED -{ -public: -#ifdef _DEBUG - CRefDebug() - { - AssertMsg( GetRefCount() == 1, "Expected initial ref count of 1" ); - DevMsg( "%s:create 0x%x\n", ( pszName ) ? pszName : "", this ); - } - - virtual ~CRefDebug() - { - AssertDevMsg( GetRefCount() == FINAL_REFS, "Object still referenced on destroy?" ); - DevMsg( "%s:destroy 0x%x\n", ( pszName ) ? pszName : "", this ); - } - - int AddRef() - { - DevMsg( "%s:(0x%x)->AddRef() --> %d\n", ( pszName ) ? pszName : "", this, GetRefCount() + 1 ); - return BASE_REFCOUNTED::AddRef(); - } - - int Release() - { - DevMsg( "%s:(0x%x)->Release() --> %d\n", ( pszName ) ? pszName : "", this, GetRefCount() - 1 ); - Assert( GetRefCount() > 0 ); - return BASE_REFCOUNTED::Release(); - } -#endif -}; - -//----------------------------------------------------------------------------- - -#endif // REFCOUNT_H diff --git a/Resources/NetHook/tier1/smartptr.h b/Resources/NetHook/tier1/smartptr.h deleted file mode 100644 index fa17a792..00000000 --- a/Resources/NetHook/tier1/smartptr.h +++ /dev/null @@ -1,279 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef SMARTPTR_H -#define SMARTPTR_H -#ifdef _WIN32 -#pragma once -#endif - - -class CRefCountAccessor -{ -public: - template< class T > - static void AddRef( T *pObj ) - { - pObj->AddRef(); - } - - template< class T > - static void Release( T *pObj ) - { - pObj->Release(); - } -}; - -// This can be used if your objects use AddReference/ReleaseReference function names. -class CRefCountAccessorLongName -{ -public: - template< class T > - static void AddRef( T *pObj ) - { - pObj->AddReference(); - } - - template< class T > - static void Release( T *pObj ) - { - pObj->ReleaseReference(); - } -}; - - -// -// CPlainAutoPtr -// is a smart wrapper for a pointer on the stack that performs "delete" upon destruction. -// -// No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used -// for readability and ease of maintenance. -// -// Auto pointer supports an "arrow" operator for invoking methods on the pointee and a "dereference" operator -// for getting a pointee reference. -// -// No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom" -// if casting to bool or pointer happens to be useful). -// -// Test for validity with "IsValid", get the pointer with "Get". -// -template < typename T > -class CPlainAutoPtr -{ -public: - explicit CPlainAutoPtr( T *p = NULL ) : m_p( p ) {} - ~CPlainAutoPtr( void ) { Delete(); } - -public: - void Delete( void ) { delete Detach(); } - -private: // Disallow copying, use Detach() instead to avoid ambiguity - CPlainAutoPtr( CPlainAutoPtr const &x ); - CPlainAutoPtr & operator = ( CPlainAutoPtr const &x ); - -public: - void Attach( T *p ) { m_p = p; } - T * Detach( void ) { T * p( m_p ); m_p = NULL; return p; } - -public: - bool IsValid( void ) const { return m_p != NULL; } - T * Get( void ) const { return m_p; } - T * operator -> ( void ) const { return Get(); } - T & operator * ( void ) const { return *Get(); } - -private: - T * m_p; -}; - -// -// CArrayAutoPtr -// is a smart wrapper for an array pointer on the stack that performs "delete []" upon destruction. -// -// No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used -// for readability and ease of maintenance. -// -// Auto pointer supports an "indexing" operator for accessing array elements. -// -// No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom" -// if casting to bool or pointer happens to be useful). -// -// Test for validity with "IsValid", get the array pointer with "Get". -// -template < typename T > -class CArrayAutoPtr : public CPlainAutoPtr < T > // Warning: no polymorphic destructor (delete on base class will be a mistake) -{ -public: - explicit CArrayAutoPtr( T *p = NULL ) { Attach( p ); } - ~CArrayAutoPtr( void ) { Delete(); } - -public: - void Delete( void ) { delete [] Detach(); } - -public: - T & operator [] ( int k ) const { return Get()[ k ]; } -}; - - -// Smart pointers can be used to automatically free an object when nobody points -// at it anymore. Things contained in smart pointers must implement AddRef and Release -// functions. If those functions are private, then the class must make -// CRefCountAccessor a friend. -template -class CSmartPtr -{ -public: - CSmartPtr(); - CSmartPtr( T *pObj ); - CSmartPtr( const CSmartPtr &other ); - ~CSmartPtr(); - - T* operator=( T *pObj ); - void operator=( const CSmartPtr &other ); - const T* operator->() const; - T* operator->(); - bool operator!() const; - bool operator==( const T *pOther ) const; - bool IsValid() const; // Tells if the pointer is valid. - T* GetObject() const; // Get temporary object pointer, don't store it for later reuse! - void MarkDeleted(); - -private: - T *m_pObj; -}; - - -template< class T, class RefCountAccessor > -inline CSmartPtr::CSmartPtr() -{ - m_pObj = NULL; -} - -template< class T, class RefCountAccessor > -inline CSmartPtr::CSmartPtr( T *pObj ) -{ - m_pObj = NULL; - *this = pObj; -} - -template< class T, class RefCountAccessor > -inline CSmartPtr::CSmartPtr( const CSmartPtr &other ) -{ - m_pObj = NULL; - *this = other; -} - -template< class T, class RefCountAccessor > -inline CSmartPtr::~CSmartPtr() -{ - if ( m_pObj ) - { - RefCountAccessor::Release( m_pObj ); - } -} - -template< class T, class RefCountAccessor > -inline T* CSmartPtr::operator=( T *pObj ) -{ - if ( pObj == m_pObj ) - return pObj; - - if ( pObj ) - { - RefCountAccessor::AddRef( pObj ); - } - if ( m_pObj ) - { - RefCountAccessor::Release( m_pObj ); - } - m_pObj = pObj; - return pObj; -} - -template< class T, class RefCountAccessor > -inline void CSmartPtr::MarkDeleted() -{ - m_pObj = NULL; -} - -template< class T, class RefCountAccessor > -inline void CSmartPtr::operator=( const CSmartPtr &other ) -{ - *this = other.m_pObj; -} - -template< class T, class RefCountAccessor > -inline const T* CSmartPtr::operator->() const -{ - return m_pObj; -} - -template< class T, class RefCountAccessor > -inline T* CSmartPtr::operator->() -{ - return m_pObj; -} - -template< class T, class RefCountAccessor > -inline bool CSmartPtr::operator!() const -{ - return !m_pObj; -} - -template< class T, class RefCountAccessor > -inline bool CSmartPtr::operator==( const T *pOther ) const -{ - return m_pObj == pOther; -} - -template< class T, class RefCountAccessor > -inline bool CSmartPtr::IsValid() const -{ - return m_pObj != NULL; -} - -template< class T, class RefCountAccessor > -inline T* CSmartPtr::GetObject() const -{ - return m_pObj; -} - - -// -// CAutoPushPop -// allows you to set value of a variable upon construction and destruction. -// Constructors: -// CAutoPushPop x( myvar ) -// saves the value and restores upon destruction. -// CAutoPushPop x( myvar, newvalue ) -// saves the value, assigns new value upon construction, restores saved value upon destruction. -// CAutoPushPop x( myvar, newvalue, restorevalue ) -// assigns new value upon construction, assignes restorevalue upon destruction. -// -template < typename T > -class CAutoPushPop -{ -public: - explicit CAutoPushPop( T& var ) : m_rVar( var ), m_valPop( var ) {} - CAutoPushPop( T& var, T const &valPush ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; } - CAutoPushPop( T& var, T const &valPush, T const &valPop ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; } - - ~CAutoPushPop() { m_rVar = m_valPop; } - -private: // forbid copying - CAutoPushPop( CAutoPushPop const &x ); - CAutoPushPop & operator = ( CAutoPushPop const &x ); - -public: - T & Get() { return m_rVar; } - -private: - T &m_rVar; - T m_valPop; -}; - - -#endif // SMARTPTR_H diff --git a/Resources/NetHook/tier1/stringpool.cpp b/Resources/NetHook/tier1/stringpool.cpp deleted file mode 100644 index 8924034e..00000000 --- a/Resources/NetHook/tier1/stringpool.cpp +++ /dev/null @@ -1,334 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "convar.h" -#include "tier0/dbg.h" -#include "stringpool.h" -#include "tier1/strtools.h" -#include "generichash.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- -// Purpose: Comparison function for string sorted associative data structures -//----------------------------------------------------------------------------- - -bool StrLess( const char * const &pszLeft, const char * const &pszRight ) -{ - return ( Q_stricmp( pszLeft, pszRight) < 0 ); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -CStringPool::CStringPool() - : m_Strings( 32, 256, StrLess ) -{ -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -CStringPool::~CStringPool() -{ - FreeAll(); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -unsigned int CStringPool::Count() const -{ - return m_Strings.Count(); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -const char * CStringPool::Find( const char *pszValue ) -{ - unsigned short i = m_Strings.Find(pszValue); - if ( m_Strings.IsValidIndex(i) ) - return m_Strings[i]; - - return NULL; -} - -const char * CStringPool::Allocate( const char *pszValue ) -{ - char *pszNew; - - unsigned short i = m_Strings.Find(pszValue); - bool bNew = (i == m_Strings.InvalidIndex()); - - if ( !bNew ) - return m_Strings[i]; - - pszNew = strdup( pszValue ); - - if ( bNew ) - m_Strings.Insert( pszNew ); - - return pszNew; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -void CStringPool::FreeAll() -{ - unsigned short i = m_Strings.FirstInorder(); - while ( i != m_Strings.InvalidIndex() ) - { - free( (void *)m_Strings[i] ); - i = m_Strings.NextInorder(i); - } - m_Strings.RemoveAll(); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - - -CCountedStringPool::CCountedStringPool() -{ - MEM_ALLOC_CREDIT(); - m_HashTable.EnsureCount(HASH_TABLE_SIZE); - - for( int i = 0; i < m_HashTable.Count(); i++ ) - { - m_HashTable[i] = INVALID_ELEMENT; - } - - m_FreeListStart = INVALID_ELEMENT; - m_Elements.AddToTail(); - m_Elements[0].pString = NULL; - m_Elements[0].nReferenceCount = 0; - m_Elements[0].nNextElement = INVALID_ELEMENT; -} - -CCountedStringPool::~CCountedStringPool() -{ - FreeAll(); -} - -void CCountedStringPool::FreeAll() -{ - int i; - - // Reset the hash table: - for( i = 0; i < m_HashTable.Count(); i++ ) - { - m_HashTable[i] = INVALID_ELEMENT; - } - - // Blow away the free list: - m_FreeListStart = INVALID_ELEMENT; - - for( i = 0; i < m_Elements.Count(); i++ ) - { - if( m_Elements[i].pString ) - { - delete [] m_Elements[i].pString; - m_Elements[i].pString = NULL; - m_Elements[i].nReferenceCount = 0; - m_Elements[i].nNextElement = INVALID_ELEMENT; - } - } - - // Remove all but the invalid element: - m_Elements.RemoveAll(); - m_Elements.AddToTail(); - m_Elements[0].pString = NULL; - m_Elements[0].nReferenceCount = 0; - m_Elements[0].nNextElement = INVALID_ELEMENT; -} - - -unsigned short CCountedStringPool::FindStringHandle( const char* pIntrinsic ) -{ - if( pIntrinsic == NULL ) - return INVALID_ELEMENT; - - unsigned short nHashBucketIndex = (HashStringCaseless(pIntrinsic ) %HASH_TABLE_SIZE); - unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; - - // Does the bucket already exist? - if( nCurrentBucket != INVALID_ELEMENT ) - { - for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) - { - if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) - { - return nCurrentBucket; - } - } - } - - return 0; - -} - -char* CCountedStringPool::FindString( const char* pIntrinsic ) -{ - if( pIntrinsic == NULL ) - return NULL; - - // Yes, this will be NULL on failure. - return m_Elements[FindStringHandle(pIntrinsic)].pString; -} - -unsigned short CCountedStringPool::ReferenceStringHandle( const char* pIntrinsic ) -{ - if( pIntrinsic == NULL ) - return INVALID_ELEMENT; - - unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % HASH_TABLE_SIZE); - unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; - - // Does the bucket already exist? - if( nCurrentBucket != INVALID_ELEMENT ) - { - for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) - { - if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) - { - // Anyone who hits 65k references is permanant - if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE ) - { - m_Elements[nCurrentBucket].nReferenceCount ++ ; - } - return nCurrentBucket; - } - } - } - - if( m_FreeListStart != INVALID_ELEMENT ) - { - nCurrentBucket = m_FreeListStart; - m_FreeListStart = m_Elements[nCurrentBucket].nNextElement; - } - else - { - nCurrentBucket = m_Elements.AddToTail(); - } - - m_Elements[nCurrentBucket].nReferenceCount = 1; - - // Insert at the beginning of the bucket: - m_Elements[nCurrentBucket].nNextElement = m_HashTable[ nHashBucketIndex ]; - m_HashTable[ nHashBucketIndex ] = nCurrentBucket; - - m_Elements[nCurrentBucket].pString = new char[Q_strlen( pIntrinsic ) + 1]; - Q_strcpy( m_Elements[nCurrentBucket].pString, pIntrinsic ); - - return nCurrentBucket; -} - - -char* CCountedStringPool::ReferenceString( const char* pIntrinsic ) -{ - if(!pIntrinsic) - return NULL; - - return m_Elements[ReferenceStringHandle( pIntrinsic)].pString; -} - -void CCountedStringPool::DereferenceString( const char* pIntrinsic ) -{ - // If we get a NULL pointer, just return - if (!pIntrinsic) - return; - - unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % m_HashTable.Count()); - unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; - - // If there isn't anything in the bucket, just return. - if ( nCurrentBucket == INVALID_ELEMENT ) - return; - - for( unsigned short previous = INVALID_ELEMENT; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) - { - if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) - { - // Anyone who hits 65k references is permanant - if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE ) - { - m_Elements[nCurrentBucket].nReferenceCount --; - } - - if( m_Elements[nCurrentBucket].nReferenceCount == 0 ) - { - if( previous == INVALID_ELEMENT ) - { - m_HashTable[nHashBucketIndex] = m_Elements[nCurrentBucket].nNextElement; - } - else - { - m_Elements[previous].nNextElement = m_Elements[nCurrentBucket].nNextElement; - } - - delete [] m_Elements[nCurrentBucket].pString; - m_Elements[nCurrentBucket].pString = NULL; - m_Elements[nCurrentBucket].nReferenceCount = 0; - - m_Elements[nCurrentBucket].nNextElement = m_FreeListStart; - m_FreeListStart = nCurrentBucket; - break; - - } - } - - previous = nCurrentBucket; - } -} - -char* CCountedStringPool::HandleToString( unsigned short handle ) -{ - return m_Elements[handle].pString; -} - -void CCountedStringPool::SpewStrings() -{ - int i; - for ( i = 0; i < m_Elements.Count(); i++ ) - { - char* string = m_Elements[i].pString; - - Msg("String %d: ref:%d %s", i, m_Elements[i].nReferenceCount, string == NULL? "EMPTY - ok for slot zero only!" : string); - } - - Msg("\n%d total counted strings.", m_Elements.Count()); -} - -#ifdef _DEBUG -CON_COMMAND( test_stringpool, "Tests the class CStringPool" ) -{ - CStringPool pool; - - Assert(pool.Count() == 0); - - pool.Allocate("test"); - Assert(pool.Count() == 1); - - pool.Allocate("test"); - Assert(pool.Count() == 1); - - pool.Allocate("test2"); - Assert(pool.Count() == 2); - - Assert( pool.Find("test2") != NULL ); - Assert( pool.Find("TEST") != NULL ); - Assert( pool.Find("Test2") != NULL ); - Assert( pool.Find("test") != NULL ); - - pool.FreeAll(); - Assert(pool.Count() == 0); - - Msg("Pass."); -} -#endif diff --git a/Resources/NetHook/tier1/stringpool.h b/Resources/NetHook/tier1/stringpool.h deleted file mode 100644 index 42eb6c90..00000000 --- a/Resources/NetHook/tier1/stringpool.h +++ /dev/null @@ -1,91 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef STRINGPOOL_H -#define STRINGPOOL_H - -#if defined( _WIN32 ) -#pragma once -#endif - -#include "utlrbtree.h" -#include "utlvector.h" - -//----------------------------------------------------------------------------- -// Purpose: Allocates memory for strings, checking for duplicates first, -// reusing exising strings if duplicate found. -//----------------------------------------------------------------------------- - -class CStringPool -{ -public: - CStringPool(); - ~CStringPool(); - - unsigned int Count() const; - - const char * Allocate( const char *pszValue ); - void FreeAll(); - - // searches for a string already in the pool - const char * CStringPool::Find( const char *pszValue ); - -protected: - typedef CUtlRBTree CStrSet; - - CStrSet m_Strings; -}; - -//----------------------------------------------------------------------------- -// Purpose: A reference counted string pool. -// -// Elements are stored more efficiently than in the conventional string pool, -// quicker to look up, and storage is tracked via reference counts. -// -// At some point this should replace CStringPool -//----------------------------------------------------------------------------- -class CCountedStringPool -{ -public: // HACK, hash_item_t structure should not be public. - - struct hash_item_t - { - char* pString; - unsigned short nNextElement; - unsigned char nReferenceCount; - unsigned char pad; - }; - - enum - { - INVALID_ELEMENT = 0, - MAX_REFERENCE = 0xFF, - HASH_TABLE_SIZE = 1024 - }; - - CUtlVector m_HashTable; // Points to each element - CUtlVector m_Elements; - unsigned short m_FreeListStart; - -public: - CCountedStringPool(); - virtual ~CCountedStringPool(); - - void FreeAll(); - - char *FindString( const char* pIntrinsic ); - char *ReferenceString( const char* pIntrinsic ); - void DereferenceString( const char* pIntrinsic ); - - // These are only reliable if there are less than 64k strings in your string pool - unsigned short FindStringHandle( const char* pIntrinsic ); - unsigned short ReferenceStringHandle( const char* pIntrinsic ); - char *HandleToString( unsigned short handle ); - void SpewStrings(); -}; - -#endif // STRINGPOOL_H diff --git a/Resources/NetHook/tier1/strtools.cpp b/Resources/NetHook/tier1/strtools.cpp deleted file mode 100644 index 76a6a20e..00000000 --- a/Resources/NetHook/tier1/strtools.cpp +++ /dev/null @@ -1,2015 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: String Tools -// -//===========================================================================// - -// These are redefined in the project settings to prevent anyone from using them. -// We in this module are of a higher caste and thus are privileged in their use. -#ifdef strncpy - #undef strncpy -#endif - -#ifdef _snprintf - #undef _snprintf -#endif - -#if defined( sprintf ) - #undef sprintf -#endif - -#if defined( vsprintf ) - #undef vsprintf -#endif - -#ifdef _vsnprintf -#ifdef _WIN32 - #undef _vsnprintf -#endif -#endif - -#ifdef vsnprintf -#ifndef _WIN32 - #undef vsnprintf -#endif -#endif - -#if defined( strcat ) - #undef strcat -#endif - -#ifdef strncat - #undef strncat -#endif - -// NOTE: I have to include stdio + stdarg first so vsnprintf gets compiled in -#include -#include - -#ifdef _LINUX -#include -#include -#include -#define _getcwd getcwd -#elif _WIN32 -#include -#if !defined( _X360 ) -#define WIN32_LEAN_AND_MEAN -#include -#endif -#endif - -#ifdef _WIN32 -#ifndef CP_UTF8 -#define CP_UTF8 65001 -#endif -#endif -#include "tier0/dbg.h" -#include "tier1/strtools.h" -#include -#include -#include "tier0/basetypes.h" -#include "tier1/utldict.h" -#if defined( _X360 ) -#include "xbox/xbox_win32stubs.h" -#endif -#include "tier0/memdbgon.h" - -void _V_memset (const char* file, int line, void *dest, int fill, int count) -{ - Assert( count >= 0 ); - AssertValidWritePtr( dest, count ); - - memset(dest,fill,count); -} - -void _V_memcpy (const char* file, int line, void *dest, const void *src, int count) -{ - Assert( count >= 0 ); - AssertValidReadPtr( src, count ); - AssertValidWritePtr( dest, count ); - - memcpy( dest, src, count ); -} - -void _V_memmove(const char* file, int line, void *dest, const void *src, int count) -{ - Assert( count >= 0 ); - AssertValidReadPtr( src, count ); - AssertValidWritePtr( dest, count ); - - memmove( dest, src, count ); -} - -int _V_memcmp (const char* file, int line, const void *m1, const void *m2, int count) -{ - Assert( count >= 0 ); - AssertValidReadPtr( m1, count ); - AssertValidReadPtr( m2, count ); - - return memcmp( m1, m2, count ); -} - -int _V_strlen(const char* file, int line, const char *str) -{ - AssertValidStringPtr(str); - return strlen( str ); -} - -void _V_strcpy (const char* file, int line, char *dest, const char *src) -{ - AssertValidWritePtr(dest); - AssertValidStringPtr(src); - - strcpy( dest, src ); -} - -int _V_wcslen(const char* file, int line, const wchar_t *pwch) -{ - return wcslen( pwch ); -} - -char *_V_strrchr(const char* file, int line, const char *s, char c) -{ - AssertValidStringPtr( s ); - int len = V_strlen(s); - s += len; - while (len--) - if (*--s == c) return (char *)s; - return 0; -} - -int _V_strcmp (const char* file, int line, const char *s1, const char *s2) -{ - AssertValidStringPtr( s1 ); - AssertValidStringPtr( s2 ); - - return strcmp( s1, s2 ); -} - -int _V_wcscmp (const char* file, int line, const wchar_t *s1, const wchar_t *s2) -{ - while (1) - { - if (*s1 != *s2) - return -1; // strings not equal - if (!*s1) - return 0; // strings are equal - s1++; - s2++; - } - - return -1; -} - - - -int _V_stricmp(const char* file, int line, const char *s1, const char *s2 ) -{ - AssertValidStringPtr( s1 ); - AssertValidStringPtr( s2 ); - - return stricmp( s1, s2 ); -} - - -char *_V_strstr(const char* file, int line, const char *s1, const char *search ) -{ - AssertValidStringPtr( s1 ); - AssertValidStringPtr( search ); - -#if defined( _X360 ) - return (char *)strstr( (char *)s1, search ); -#else - return (char *)strstr( s1, search ); -#endif -} - -char *_V_strupr (const char* file, int line, char *start) -{ - AssertValidStringPtr( start ); - return strupr( start ); -} - - -char *_V_strlower (const char* file, int line, char *start) -{ - AssertValidStringPtr( start ); - return strlwr(start); -} - -int V_strncmp (const char *s1, const char *s2, int count) -{ - Assert( count >= 0 ); - AssertValidStringPtr( s1, count ); - AssertValidStringPtr( s2, count ); - - while ( count-- > 0 ) - { - if ( *s1 != *s2 ) - return *s1 < *s2 ? -1 : 1; // string different - if ( *s1 == '\0' ) - return 0; // null terminator hit - strings the same - s1++; - s2++; - } - - return 0; // count characters compared the same -} - -char *V_strnlwr(char *s, size_t count) -{ - Assert( count >= 0 ); - AssertValidStringPtr( s, count ); - - char* pRet = s; - if ( !s ) - return s; - - while ( --count >= 0 ) - { - if ( !*s ) - break; - - *s = tolower( *s ); - ++s; - } - - if ( count > 0 ) - { - s[count-1] = 0; - } - - return pRet; -} - - -int V_strncasecmp (const char *s1, const char *s2, int n) -{ - Assert( n >= 0 ); - AssertValidStringPtr( s1 ); - AssertValidStringPtr( s2 ); - - while ( n-- > 0 ) - { - int c1 = *s1++; - int c2 = *s2++; - - if (c1 != c2) - { - if (c1 >= 'a' && c1 <= 'z') - c1 -= ('a' - 'A'); - if (c2 >= 'a' && c2 <= 'z') - c2 -= ('a' - 'A'); - if (c1 != c2) - return c1 < c2 ? -1 : 1; - } - if ( c1 == '\0' ) - return 0; // null terminator hit - strings the same - } - - return 0; // n characters compared the same -} - -int V_strcasecmp( const char *s1, const char *s2 ) -{ - AssertValidStringPtr( s1 ); - AssertValidStringPtr( s2 ); - - return stricmp( s1, s2 ); -} - -int V_strnicmp (const char *s1, const char *s2, int n) -{ - Assert( n >= 0 ); - AssertValidStringPtr(s1); - AssertValidStringPtr(s2); - - return V_strncasecmp( s1, s2, n ); -} - - -const char *StringAfterPrefix( const char *str, const char *prefix ) -{ - AssertValidStringPtr( str ); - AssertValidStringPtr( prefix ); - do - { - if ( !*prefix ) - return str; - } - while ( tolower( *str++ ) == tolower( *prefix++ ) ); - return NULL; -} - -const char *StringAfterPrefixCaseSensitive( const char *str, const char *prefix ) -{ - AssertValidStringPtr( str ); - AssertValidStringPtr( prefix ); - do - { - if ( !*prefix ) - return str; - } - while ( *str++ == *prefix++ ); - return NULL; -} - - -int V_atoi (const char *str) -{ - AssertValidStringPtr( str ); - - int val; - int sign; - int c; - - Assert( str ); - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val<<4) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val<<4) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val<<4) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - while (1) - { - c = *str++; - if (c <'0' || c > '9') - return val*sign; - val = val*10 + c - '0'; - } - - return 0; -} - - -float V_atof (const char *str) -{ - AssertValidStringPtr( str ); - double val; - int sign; - int c; - int decimal, total; - - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val*16) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val*16) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val*16) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - decimal = -1; - total = 0; - while (1) - { - c = *str++; - if (c == '.') - { - decimal = total; - continue; - } - if (c <'0' || c > '9') - break; - val = val*10 + c - '0'; - total++; - } - - if (decimal == -1) - return val*sign; - while (total > decimal) - { - val /= 10; - total--; - } - - return val*sign; -} - -//----------------------------------------------------------------------------- -// Normalizes a float string in place. -// -// (removes leading zeros, trailing zeros after the decimal point, and the decimal point itself where possible) -//----------------------------------------------------------------------------- -void V_normalizeFloatString( char* pFloat ) -{ - // If we have a decimal point, remove trailing zeroes: - if( strchr( pFloat,'.' ) ) - { - int len = V_strlen(pFloat); - - while( len > 1 && pFloat[len - 1] == '0' ) - { - pFloat[len - 1] = '\0'; - len--; - } - - if( len > 1 && pFloat[ len - 1 ] == '.' ) - { - pFloat[len - 1] = '\0'; - len--; - } - } - - // TODO: Strip leading zeros - -} - - -//----------------------------------------------------------------------------- -// Finds a string in another string with a case insensitive test -//----------------------------------------------------------------------------- -char const* V_stristr( char const* pStr, char const* pSearch ) -{ - AssertValidStringPtr(pStr); - AssertValidStringPtr(pSearch); - - if (!pStr || !pSearch) - return 0; - - char const* pLetter = pStr; - - // Check the entire string - while (*pLetter != 0) - { - // Skip over non-matches - if (tolower((unsigned char)*pLetter) == tolower((unsigned char)*pSearch)) - { - // Check for match - char const* pMatch = pLetter + 1; - char const* pTest = pSearch + 1; - while (*pTest != 0) - { - // We've run off the end; don't bother. - if (*pMatch == 0) - return 0; - - if (tolower((unsigned char)*pMatch) != tolower((unsigned char)*pTest)) - break; - - ++pMatch; - ++pTest; - } - - // Found a match! - if (*pTest == 0) - return pLetter; - } - - ++pLetter; - } - - return 0; -} - -char* V_stristr( char* pStr, char const* pSearch ) -{ - AssertValidStringPtr( pStr ); - AssertValidStringPtr( pSearch ); - - return (char*)V_stristr( (char const*)pStr, pSearch ); -} - -//----------------------------------------------------------------------------- -// Finds a string in another string with a case insensitive test w/ length validation -//----------------------------------------------------------------------------- -char const* V_strnistr( char const* pStr, char const* pSearch, int n ) -{ - AssertValidStringPtr(pStr); - AssertValidStringPtr(pSearch); - - if (!pStr || !pSearch) - return 0; - - char const* pLetter = pStr; - - // Check the entire string - while (*pLetter != 0) - { - if ( n <= 0 ) - return 0; - - // Skip over non-matches - if (tolower(*pLetter) == tolower(*pSearch)) - { - int n1 = n - 1; - - // Check for match - char const* pMatch = pLetter + 1; - char const* pTest = pSearch + 1; - while (*pTest != 0) - { - if ( n1 <= 0 ) - return 0; - - // We've run off the end; don't bother. - if (*pMatch == 0) - return 0; - - if (tolower(*pMatch) != tolower(*pTest)) - break; - - ++pMatch; - ++pTest; - --n1; - } - - // Found a match! - if (*pTest == 0) - return pLetter; - } - - ++pLetter; - --n; - } - - return 0; -} - -const char* V_strnchr( const char* pStr, char c, int n ) -{ - char const* pLetter = pStr; - char const* pLast = pStr + n; - - // Check the entire string - while ( (pLetter < pLast) && (*pLetter != 0) ) - { - if (*pLetter == c) - return pLetter; - ++pLetter; - } - return NULL; -} - -void V_strncpy( char *pDest, char const *pSrc, int maxLen ) -{ - Assert( maxLen >= 0 ); - AssertValidWritePtr( pDest, maxLen ); - AssertValidStringPtr( pSrc ); - - strncpy( pDest, pSrc, maxLen ); - if ( maxLen > 0 ) - { - pDest[maxLen-1] = 0; - } -} - -void V_wcsncpy( wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes ) -{ - Assert( maxLenInBytes >= 0 ); - AssertValidWritePtr( pDest, maxLenInBytes ); - AssertValidReadPtr( pSrc ); - - int maxLen = maxLenInBytes / sizeof(wchar_t); - - wcsncpy( pDest, pSrc, maxLen ); - if( maxLen ) - { - pDest[maxLen-1] = 0; - } -} - - - -int V_snwprintf( wchar_t *pDest, int maxLen, const wchar_t *pFormat, ... ) -{ - Assert( maxLen >= 0 ); - AssertValidWritePtr( pDest, maxLen ); - AssertValidReadPtr( pFormat ); - - va_list marker; - - va_start( marker, pFormat ); -#ifdef _WIN32 - int len = _snwprintf( pDest, maxLen, pFormat, marker ); -#elif _LINUX - int len = swprintf( pDest, maxLen, pFormat, marker ); -#else -#error "define vsnwprintf type." -#endif - va_end( marker ); - - // Len < 0 represents an overflow - if( len < 0 ) - { - len = maxLen; - pDest[maxLen-1] = 0; - } - - return len; -} - - -int V_snprintf( char *pDest, int maxLen, char const *pFormat, ... ) -{ - Assert( maxLen >= 0 ); - AssertValidWritePtr( pDest, maxLen ); - AssertValidStringPtr( pFormat ); - - va_list marker; - - va_start( marker, pFormat ); -#ifdef _WIN32 - int len = _vsnprintf( pDest, maxLen, pFormat, marker ); -#elif _LINUX - int len = vsnprintf( pDest, maxLen, pFormat, marker ); -#else - #error "define vsnprintf type." -#endif - va_end( marker ); - - // Len < 0 represents an overflow - if( len < 0 ) - { - len = maxLen; - pDest[maxLen-1] = 0; - } - - return len; -} - - -int V_vsnprintf( char *pDest, int maxLen, char const *pFormat, va_list params ) -{ - Assert( maxLen > 0 ); - AssertValidWritePtr( pDest, maxLen ); - AssertValidStringPtr( pFormat ); - - int len = _vsnprintf( pDest, maxLen, pFormat, params ); - - if( len < 0 ) - { - len = maxLen; - pDest[maxLen-1] = 0; - } - - return len; -} - - - -//----------------------------------------------------------------------------- -// Purpose: If COPY_ALL_CHARACTERS == max_chars_to_copy then we try to add the whole pSrc to the end of pDest, otherwise -// we copy only as many characters as are specified in max_chars_to_copy (or the # of characters in pSrc if thats's less). -// Input : *pDest - destination buffer -// *pSrc - string to append -// destBufferSize - sizeof the buffer pointed to by pDest -// max_chars_to_copy - COPY_ALL_CHARACTERS in pSrc or max # to copy -// Output : char * the copied buffer -//----------------------------------------------------------------------------- -char *V_strncat(char *pDest, const char *pSrc, size_t destBufferSize, int max_chars_to_copy ) -{ - size_t charstocopy = (size_t)0; - - Assert( destBufferSize >= 0 ); - AssertValidStringPtr( pDest); - AssertValidStringPtr( pSrc ); - - size_t len = strlen(pDest); - size_t srclen = strlen( pSrc ); - if ( max_chars_to_copy <= COPY_ALL_CHARACTERS ) - { - charstocopy = srclen; - } - else - { - charstocopy = (size_t)min( max_chars_to_copy, (int)srclen ); - } - - if ( len + charstocopy >= destBufferSize ) - { - charstocopy = destBufferSize - len - 1; - } - - if ( !charstocopy ) - { - return pDest; - } - - char *pOut = strncat( pDest, pSrc, charstocopy ); - pOut[destBufferSize-1] = 0; - return pOut; -} - - - -//----------------------------------------------------------------------------- -// Purpose: Converts value into x.xx MB/ x.xx KB, x.xx bytes format, including commas -// Input : value - -// 2 - -// false - -// Output : char -//----------------------------------------------------------------------------- -#define NUM_PRETIFYMEM_BUFFERS 8 -char *V_pretifymem( float value, int digitsafterdecimal /*= 2*/, bool usebinaryonek /*= false*/ ) -{ - static char output[ NUM_PRETIFYMEM_BUFFERS ][ 32 ]; - static int current; - - float onekb = usebinaryonek ? 1024.0f : 1000.0f; - float onemb = onekb * onekb; - - char *out = output[ current ]; - current = ( current + 1 ) & ( NUM_PRETIFYMEM_BUFFERS -1 ); - - char suffix[ 8 ]; - - // First figure out which bin to use - if ( value > onemb ) - { - value /= onemb; - V_snprintf( suffix, sizeof( suffix ), " MB" ); - } - else if ( value > onekb ) - { - value /= onekb; - V_snprintf( suffix, sizeof( suffix ), " KB" ); - } - else - { - V_snprintf( suffix, sizeof( suffix ), " bytes" ); - } - - char val[ 32 ]; - - // Clamp to >= 0 - digitsafterdecimal = max( digitsafterdecimal, 0 ); - - // If it's basically integral, don't do any decimals - if ( FloatMakePositive( value - (int)value ) < 0.00001 ) - { - V_snprintf( val, sizeof( val ), "%i%s", (int)value, suffix ); - } - else - { - char fmt[ 32 ]; - - // Otherwise, create a format string for the decimals - V_snprintf( fmt, sizeof( fmt ), "%%.%if%s", digitsafterdecimal, suffix ); - V_snprintf( val, sizeof( val ), fmt, value ); - } - - // Copy from in to out - char *i = val; - char *o = out; - - // Search for decimal or if it was integral, find the space after the raw number - char *dot = strstr( i, "." ); - if ( !dot ) - { - dot = strstr( i, " " ); - } - - // Compute position of dot - int pos = dot - i; - // Don't put a comma if it's <= 3 long - pos -= 3; - - while ( *i ) - { - // If pos is still valid then insert a comma every third digit, except if we would be - // putting one in the first spot - if ( pos >= 0 && !( pos % 3 ) ) - { - // Never in first spot - if ( o != out ) - { - *o++ = ','; - } - } - - // Count down comma position - pos--; - - // Copy rest of data as normal - *o++ = *i++; - } - - // Terminate - *o = 0; - - return out; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns a string representation of an integer with commas -// separating the 1000s (ie, 37,426,421) -// Input : value - Value to convert -// Output : Pointer to a static buffer containing the output -//----------------------------------------------------------------------------- -#define NUM_PRETIFYNUM_BUFFERS 8 -char *V_pretifynum( int64 value ) -{ - static char output[ NUM_PRETIFYMEM_BUFFERS ][ 32 ]; - static int current; - - char *out = output[ current ]; - current = ( current + 1 ) & ( NUM_PRETIFYMEM_BUFFERS -1 ); - - *out = 0; - - // Render the leading -, if necessary - if ( value < 0 ) - { - char *pchRender = out + V_strlen( out ); - V_snprintf( pchRender, 32, "-" ); - value = -value; - } - - // Render quadrillions - if ( value >= 1000000000000 ) - { - char *pchRender = out + V_strlen( out ); - V_snprintf( pchRender, 32, "%d,", value / 1000000000000 ); - } - - // Render trillions - if ( value >= 1000000000000 ) - { - char *pchRender = out + V_strlen( out ); - V_snprintf( pchRender, 32, "%d,", value / 1000000000000 ); - } - - // Render billions - if ( value >= 1000000000 ) - { - char *pchRender = out + V_strlen( out ); - V_snprintf( pchRender, 32, "%d,", value / 1000000000 ); - } - - // Render millions - if ( value >= 1000000 ) - { - char *pchRender = out + V_strlen( out ); - if ( value >= 1000000000 ) - V_snprintf( pchRender, 32, "%03d,", ( value / 1000000 ) % 1000 ); - else - V_snprintf( pchRender, 32, "%d,", ( value / 1000000 ) % 1000 ); - } - - // Render thousands - if ( value >= 1000 ) - { - char *pchRender = out + V_strlen( out ); - if ( value >= 1000000 ) - V_snprintf( pchRender, 32, "%03d,", ( value / 1000 ) % 1000 ); - else - V_snprintf( pchRender, 32, "%d,", ( value / 1000 ) % 1000 ); - } - - // Render units - char *pchRender = out + V_strlen( out ); - if ( value > 1000 ) - V_snprintf( pchRender, 32, "%03d", value % 1000 ); - else - V_snprintf( pchRender, 32, "%d", value % 1000 ); - - return out; -} - - -//----------------------------------------------------------------------------- -// Purpose: Converts a UTF8 string into a unicode string -//----------------------------------------------------------------------------- -int V_UTF8ToUnicode( const char *pUTF8, wchar_t *pwchDest, int cubDestSizeInBytes ) -{ - AssertValidStringPtr(pUTF8); - AssertValidWritePtr(pwchDest); - - pwchDest[0] = 0; -#ifdef _WIN32 - int cchResult = MultiByteToWideChar( CP_UTF8, 0, pUTF8, -1, pwchDest, cubDestSizeInBytes / sizeof(wchar_t) ); -#elif _LINUX - int cchResult = mbstowcs( pwchDest, pUTF8, cubDestSizeInBytes / sizeof(wchar_t) ); -#endif - pwchDest[(cubDestSizeInBytes / sizeof(wchar_t)) - 1] = 0; - return cchResult; -} - -//----------------------------------------------------------------------------- -// Purpose: Converts a unicode string into a UTF8 (standard) string -//----------------------------------------------------------------------------- -int V_UnicodeToUTF8( const wchar_t *pUnicode, char *pUTF8, int cubDestSizeInBytes ) -{ - AssertValidStringPtr(pUTF8, cubDestSizeInBytes); - AssertValidReadPtr(pUnicode); - - pUTF8[0] = 0; -#ifdef _WIN32 - int cchResult = WideCharToMultiByte( CP_UTF8, 0, pUnicode, -1, pUTF8, cubDestSizeInBytes, NULL, NULL ); -#elif _LINUX - int cchResult = wcstombs( pUTF8, pUnicode, cubDestSizeInBytes ); -#endif - pUTF8[cubDestSizeInBytes - 1] = 0; - return cchResult; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the 4 bit nibble for a hex character -// Input : c - -// Output : unsigned char -//----------------------------------------------------------------------------- -static unsigned char V_nibble( char c ) -{ - if ( ( c >= '0' ) && - ( c <= '9' ) ) - { - return (unsigned char)(c - '0'); - } - - if ( ( c >= 'A' ) && - ( c <= 'F' ) ) - { - return (unsigned char)(c - 'A' + 0x0a); - } - - if ( ( c >= 'a' ) && - ( c <= 'f' ) ) - { - return (unsigned char)(c - 'a' + 0x0a); - } - - return '0'; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *in - -// numchars - -// *out - -// maxoutputbytes - -//----------------------------------------------------------------------------- -void V_hextobinary( char const *in, int numchars, byte *out, int maxoutputbytes ) -{ - int len = V_strlen( in ); - numchars = min( len, numchars ); - // Make sure it's even - numchars = ( numchars ) & ~0x1; - - // Must be an even # of input characters (two chars per output byte) - Assert( numchars >= 2 ); - - memset( out, 0x00, maxoutputbytes ); - - byte *p; - int i; - - p = out; - for ( i = 0; - ( i < numchars ) && ( ( p - out ) < maxoutputbytes ); - i+=2, p++ ) - { - *p = ( V_nibble( in[i] ) << 4 ) | V_nibble( in[i+1] ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *in - -// inputbytes - -// *out - -// outsize - -//----------------------------------------------------------------------------- -void V_binarytohex( const byte *in, int inputbytes, char *out, int outsize ) -{ - Assert( outsize >= 1 ); - char doublet[10]; - int i; - - out[0]=0; - - for ( i = 0; i < inputbytes; i++ ) - { - unsigned char c = in[i]; - V_snprintf( doublet, sizeof( doublet ), "%02x", c ); - V_strncat( out, doublet, outsize, COPY_ALL_CHARACTERS ); - } -} - -#if defined( _WIN32 ) || defined( WIN32 ) -#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/') -#else //_WIN32 -#define PATHSEPARATOR(c) ((c) == '/') -#endif //_WIN32 - - -//----------------------------------------------------------------------------- -// Purpose: Extracts the base name of a file (no path, no extension, assumes '/' or '\' as path separator) -// Input : *in - -// *out - -// maxlen - -//----------------------------------------------------------------------------- -void V_FileBase( const char *in, char *out, int maxlen ) -{ - Assert( maxlen >= 1 ); - Assert( in ); - Assert( out ); - - if ( !in || !in[ 0 ] ) - { - *out = 0; - return; - } - - int len, start, end; - - len = V_strlen( in ); - - // scan backward for '.' - end = len - 1; - while ( end&& in[end] != '.' && !PATHSEPARATOR( in[end] ) ) - { - end--; - } - - if ( in[end] != '.' ) // no '.', copy to end - { - end = len-1; - } - else - { - end--; // Found ',', copy to left of '.' - } - - // Scan backward for '/' - start = len-1; - while ( start >= 0 && !PATHSEPARATOR( in[start] ) ) - { - start--; - } - - if ( start < 0 || !PATHSEPARATOR( in[start] ) ) - { - start = 0; - } - else - { - start++; - } - - // Length of new sting - len = end - start + 1; - - int maxcopy = min( len + 1, maxlen ); - - // Copy partial string - V_strncpy( out, &in[start], maxcopy ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *ppath - -//----------------------------------------------------------------------------- -void V_StripTrailingSlash( char *ppath ) -{ - Assert( ppath ); - - int len = V_strlen( ppath ); - if ( len > 0 ) - { - if ( PATHSEPARATOR( ppath[ len - 1 ] ) ) - { - ppath[ len - 1 ] = 0; - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *in - -// *out - -// outSize - -//----------------------------------------------------------------------------- -void V_StripExtension( const char *in, char *out, int outSize ) -{ - // Find the last dot. If it's followed by a dot or a slash, then it's part of a - // directory specifier like ../../somedir/./blah. - - // scan backward for '.' - int end = V_strlen( in ) - 1; - while ( end > 0 && in[end] != '.' && !PATHSEPARATOR( in[end] ) ) - { - --end; - } - - if (end > 0 && !PATHSEPARATOR( in[end] ) && end < outSize) - { - int nChars = min( end, outSize-1 ); - if ( out != in ) - { - memcpy( out, in, nChars ); - } - out[nChars] = 0; - } - else - { - // nothing found - if ( out != in ) - { - V_strncpy( out, in, outSize ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *path - -// *extension - -// pathStringLength - -//----------------------------------------------------------------------------- -void V_DefaultExtension( char *path, const char *extension, int pathStringLength ) -{ - Assert( path ); - Assert( pathStringLength >= 1 ); - Assert( extension ); - Assert( extension[0] == '.' ); - - char *src; - - // if path doesn't have a .EXT, append extension - // (extension should include the .) - src = path + V_strlen(path) - 1; - - while ( !PATHSEPARATOR( *src ) && ( src > path ) ) - { - if (*src == '.') - { - // it has an extension - return; - } - src--; - } - - // Concatenate the desired extension - V_strncat( path, extension, pathStringLength, COPY_ALL_CHARACTERS ); -} - -//----------------------------------------------------------------------------- -// Purpose: Force extension... -// Input : *path - -// *extension - -// pathStringLength - -//----------------------------------------------------------------------------- -void V_SetExtension( char *path, const char *extension, int pathStringLength ) -{ - V_StripExtension( path, path, pathStringLength ); - V_DefaultExtension( path, extension, pathStringLength ); -} - -//----------------------------------------------------------------------------- -// Purpose: Remove final filename from string -// Input : *path - -// Output : void V_StripFilename -//----------------------------------------------------------------------------- -void V_StripFilename (char *path) -{ - int length; - - length = V_strlen( path )-1; - if ( length <= 0 ) - return; - - while ( length > 0 && - !PATHSEPARATOR( path[length] ) ) - { - length--; - } - - path[ length ] = 0; -} - -#ifdef _WIN32 -#define CORRECT_PATH_SEPARATOR '\\' -#define INCORRECT_PATH_SEPARATOR '/' -#elif _LINUX -#define CORRECT_PATH_SEPARATOR '/' -#define INCORRECT_PATH_SEPARATOR '\\' -#endif - -//----------------------------------------------------------------------------- -// Purpose: Changes all '/' or '\' characters into separator -// Input : *pname - -// separator - -//----------------------------------------------------------------------------- -void V_FixSlashes( char *pname, char separator /* = CORRECT_PATH_SEPARATOR */ ) -{ - while ( *pname ) - { - if ( *pname == INCORRECT_PATH_SEPARATOR || *pname == CORRECT_PATH_SEPARATOR ) - { - *pname = separator; - } - pname++; - } -} - - -//----------------------------------------------------------------------------- -// Purpose: This function fixes cases of filenames like materials\\blah.vmt or somepath\otherpath\\ and removes the extra double slash. -//----------------------------------------------------------------------------- -void V_FixDoubleSlashes( char *pStr ) -{ - int len = V_strlen( pStr ); - - for ( int i=1; i < len-1; i++ ) - { - if ( (pStr[i] == '/' || pStr[i] == '\\') && (pStr[i+1] == '/' || pStr[i+1] == '\\') ) - { - // This means there's a double slash somewhere past the start of the filename. That - // can happen in Hammer if they use a material in the root directory. You'll get a filename - // that looks like 'materials\\blah.vmt' - V_memmove( &pStr[i], &pStr[i+1], len - i ); - --len; - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Strip off the last directory from dirName -// Input : *dirName - -// maxlen - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool V_StripLastDir( char *dirName, int maxlen ) -{ - if( dirName[0] == 0 || - !V_stricmp( dirName, "./" ) || - !V_stricmp( dirName, ".\\" ) ) - return false; - - int len = V_strlen( dirName ); - - Assert( len < maxlen ); - - // skip trailing slash - if ( PATHSEPARATOR( dirName[len-1] ) ) - { - len--; - } - - while ( len > 0 ) - { - if ( PATHSEPARATOR( dirName[len-1] ) ) - { - dirName[len] = 0; - V_FixSlashes( dirName, CORRECT_PATH_SEPARATOR ); - return true; - } - len--; - } - - // Allow it to return an empty string and true. This can happen if something like "tf2/" is passed in. - // The correct behavior is to strip off the last directory ("tf2") and return true. - if( len == 0 ) - { - V_snprintf( dirName, maxlen, ".%c", CORRECT_PATH_SEPARATOR ); - return true; - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns a pointer to the beginning of the unqualified file name -// (no path information) -// Input: in - file name (may be unqualified, relative or absolute path) -// Output: pointer to unqualified file name -//----------------------------------------------------------------------------- -const char * V_UnqualifiedFileName( const char * in ) -{ - // back up until the character after the first path separator we find, - // or the beginning of the string - const char * out = in + strlen( in ) - 1; - while ( ( out > in ) && ( !PATHSEPARATOR( *( out-1 ) ) ) ) - out--; - return out; -} - - -//----------------------------------------------------------------------------- -// Purpose: Composes a path and filename together, inserting a path separator -// if need be -// Input: path - path to use -// filename - filename to use -// dest - buffer to compose result in -// destSize - size of destination buffer -//----------------------------------------------------------------------------- -void V_ComposeFileName( const char *path, const char *filename, char *dest, int destSize ) -{ - V_strncpy( dest, path, destSize ); - V_AppendSlash( dest, destSize ); - V_strncat( dest, filename, destSize, COPY_ALL_CHARACTERS ); - V_FixSlashes( dest ); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *path - -// *dest - -// destSize - -// Output : void V_ExtractFilePath -//----------------------------------------------------------------------------- -bool V_ExtractFilePath (const char *path, char *dest, int destSize ) -{ - Assert( destSize >= 1 ); - if ( destSize < 1 ) - { - return false; - } - - // Last char - int len = V_strlen(path); - const char *src = path + (len ? len-1 : 0); - - // back up until a \ or the start - while ( src != path && !PATHSEPARATOR( *(src-1) ) ) - { - src--; - } - - int copysize = min( src - path, destSize - 1 ); - memcpy( dest, path, copysize ); - dest[copysize] = 0; - - return copysize != 0 ? true : false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *path - -// *dest - -// destSize - -// Output : void V_ExtractFileExtension -//----------------------------------------------------------------------------- -void V_ExtractFileExtension( const char *path, char *dest, int destSize ) -{ - *dest = NULL; - const char * extension = V_GetFileExtension( path ); - if ( NULL != extension ) - V_strncpy( dest, extension, destSize ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns a pointer to the file extension within a file name string -// Input: in - file name -// Output: pointer to beginning of extension (after the "."), or NULL -// if there is no extension -//----------------------------------------------------------------------------- -const char * V_GetFileExtension( const char * path ) -{ - const char *src; - - src = path + strlen(path) - 1; - -// -// back up until a . or the start -// - while (src != path && *(src-1) != '.' ) - src--; - - // check to see if the '.' is part of a pathname - if (src == path || PATHSEPARATOR( *src ) ) - { - return NULL; // no extension - } - - return src; -} - -bool V_RemoveDotSlashes( char *pFilename, char separator ) -{ - // Remove '//' or '\\' - char *pIn = pFilename; - char *pOut = pFilename; - bool bPrevPathSep = false; - while ( *pIn ) - { - bool bIsPathSep = PATHSEPARATOR( *pIn ); - if ( !bIsPathSep || !bPrevPathSep ) - { - *pOut++ = *pIn; - } - bPrevPathSep = bIsPathSep; - ++pIn; - } - *pOut = 0; - - // Get rid of "./"'s - pIn = pFilename; - pOut = pFilename; - while ( *pIn ) - { - // The logic on the second line is preventing it from screwing up "../" - if ( pIn[0] == '.' && PATHSEPARATOR( pIn[1] ) && - (pIn == pFilename || pIn[-1] != '.') ) - { - pIn += 2; - } - else - { - *pOut = *pIn; - ++pIn; - ++pOut; - } - } - *pOut = 0; - - // Get rid of a trailing "/." (needless). - int len = strlen( pFilename ); - if ( len > 2 && pFilename[len-1] == '.' && PATHSEPARATOR( pFilename[len-2] ) ) - { - pFilename[len-2] = 0; - } - - // Each time we encounter a "..", back up until we've read the previous directory name, - // then get rid of it. - pIn = pFilename; - while ( *pIn ) - { - if ( pIn[0] == '.' && - pIn[1] == '.' && - (pIn == pFilename || PATHSEPARATOR(pIn[-1])) && // Preceding character must be a slash. - (pIn[2] == 0 || PATHSEPARATOR(pIn[2])) ) // Following character must be a slash or the end of the string. - { - char *pEndOfDots = pIn + 2; - char *pStart = pIn - 2; - - // Ok, now scan back for the path separator that starts the preceding directory. - while ( 1 ) - { - if ( pStart < pFilename ) - return false; - - if ( PATHSEPARATOR( *pStart ) ) - break; - - --pStart; - } - - // Now slide the string down to get rid of the previous directory and the ".." - memmove( pStart, pEndOfDots, strlen( pEndOfDots ) + 1 ); - - // Start over. - pIn = pFilename; - } - else - { - ++pIn; - } - } - - V_FixSlashes( pFilename, separator ); - return true; -} - - -void V_AppendSlash( char *pStr, int strSize ) -{ - int len = V_strlen( pStr ); - if ( len > 0 && !PATHSEPARATOR(pStr[len-1]) ) - { - if ( len+1 >= strSize ) - Error( "V_AppendSlash: ran out of space on %s.", pStr ); - - pStr[len] = CORRECT_PATH_SEPARATOR; - pStr[len+1] = 0; - } -} - - -void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir ) -{ - if ( V_IsAbsolutePath( pPath ) ) - { - // pPath is not relative.. just copy it. - V_strncpy( pOut, pPath, outLen ); - } - else - { - // Make sure the starting directory is absolute.. - if ( pStartingDir && V_IsAbsolutePath( pStartingDir ) ) - { - V_strncpy( pOut, pStartingDir, outLen ); - } - else - { - if ( !_getcwd( pOut, outLen ) ) - Error( "V_MakeAbsolutePath: _getcwd failed." ); - - if ( pStartingDir ) - { - V_AppendSlash( pOut, outLen ); - V_strncat( pOut, pStartingDir, outLen, COPY_ALL_CHARACTERS ); - } - } - - // Concatenate the paths. - V_AppendSlash( pOut, outLen ); - V_strncat( pOut, pPath, outLen, COPY_ALL_CHARACTERS ); - } - - if ( !V_RemoveDotSlashes( pOut ) ) - Error( "V_MakeAbsolutePath: tried to \"..\" past the root." ); - - V_FixSlashes( pOut ); -} - - -//----------------------------------------------------------------------------- -// Makes a relative path -//----------------------------------------------------------------------------- -bool V_MakeRelativePath( const char *pFullPath, const char *pDirectory, char *pRelativePath, int nBufLen ) -{ - pRelativePath[0] = 0; - - const char *pPath = pFullPath; - const char *pDir = pDirectory; - - // Strip out common parts of the path - const char *pLastCommonPath = NULL; - const char *pLastCommonDir = NULL; - while ( *pPath && ( tolower( *pPath ) == tolower( *pDir ) || - ( PATHSEPARATOR( *pPath ) && ( PATHSEPARATOR( *pDir ) || (*pDir == 0) ) ) ) ) - { - if ( PATHSEPARATOR( *pPath ) ) - { - pLastCommonPath = pPath + 1; - pLastCommonDir = pDir + 1; - } - if ( *pDir == 0 ) - { - --pLastCommonDir; - break; - } - ++pDir; ++pPath; - } - - // Nothing in common - if ( !pLastCommonPath ) - return false; - - // For each path separator remaining in the dir, need a ../ - int nOutLen = 0; - bool bLastCharWasSeparator = true; - for ( ; *pLastCommonDir; ++pLastCommonDir ) - { - if ( PATHSEPARATOR( *pLastCommonDir ) ) - { - pRelativePath[nOutLen++] = '.'; - pRelativePath[nOutLen++] = '.'; - pRelativePath[nOutLen++] = CORRECT_PATH_SEPARATOR; - bLastCharWasSeparator = true; - } - else - { - bLastCharWasSeparator = false; - } - } - - // Deal with relative paths not specified with a trailing slash - if ( !bLastCharWasSeparator ) - { - pRelativePath[nOutLen++] = '.'; - pRelativePath[nOutLen++] = '.'; - pRelativePath[nOutLen++] = CORRECT_PATH_SEPARATOR; - } - - // Copy the remaining part of the relative path over, fixing the path separators - for ( ; *pLastCommonPath; ++pLastCommonPath ) - { - if ( PATHSEPARATOR( *pLastCommonPath ) ) - { - pRelativePath[nOutLen++] = CORRECT_PATH_SEPARATOR; - } - else - { - pRelativePath[nOutLen++] = *pLastCommonPath; - } - - // Check for overflow - if ( nOutLen == nBufLen - 1 ) - break; - } - - pRelativePath[nOutLen] = 0; - return true; -} - - -//----------------------------------------------------------------------------- -// small helper function shared by lots of modules -//----------------------------------------------------------------------------- -bool V_IsAbsolutePath( const char *pStr ) -{ - bool bIsAbsolute = ( pStr[0] && pStr[1] == ':' ) || pStr[0] == '/' || pStr[0] == '\\'; - if ( IsX360() && !bIsAbsolute ) - { - bIsAbsolute = ( V_stristr( pStr, ":" ) != NULL ); - } - return bIsAbsolute; -} - - -// Copies at most nCharsToCopy bytes from pIn into pOut. -// Returns false if it would have overflowed pOut's buffer. -static bool CopyToMaxChars( char *pOut, int outSize, const char *pIn, int nCharsToCopy ) -{ - if ( outSize == 0 ) - return false; - - int iOut = 0; - while ( *pIn && nCharsToCopy > 0 ) - { - if ( iOut == (outSize-1) ) - { - pOut[iOut] = 0; - return false; - } - pOut[iOut] = *pIn; - ++iOut; - ++pIn; - --nCharsToCopy; - } - - pOut[iOut] = 0; - return true; -} - - -//----------------------------------------------------------------------------- -// Fixes up a file name, removing dot slashes, fixing slashes, converting to lowercase, etc. -//----------------------------------------------------------------------------- -void V_FixupPathName( char *pOut, size_t nOutLen, const char *pPath ) -{ - V_strncpy( pOut, pPath, nOutLen ); - V_FixSlashes( pOut ); - V_RemoveDotSlashes( pOut ); - V_FixDoubleSlashes( pOut ); - V_strlower( pOut ); -} - - -// Returns true if it completed successfully. -// If it would overflow pOut, it fills as much as it can and returns false. -bool V_StrSubst( - const char *pIn, - const char *pMatch, - const char *pReplaceWith, - char *pOut, - int outLen, - bool bCaseSensitive - ) -{ - int replaceFromLen = strlen( pMatch ); - int replaceToLen = strlen( pReplaceWith ); - - const char *pInStart = pIn; - char *pOutPos = pOut; - pOutPos[0] = 0; - - while ( 1 ) - { - int nRemainingOut = outLen - (pOutPos - pOut); - - const char *pTestPos = ( bCaseSensitive ? strstr( pInStart, pMatch ) : V_stristr( pInStart, pMatch ) ); - if ( pTestPos ) - { - // Found an occurence of pMatch. First, copy whatever leads up to the string. - int copyLen = pTestPos - pInStart; - if ( !CopyToMaxChars( pOutPos, nRemainingOut, pInStart, copyLen ) ) - return false; - - // Did we hit the end of the output string? - if ( copyLen > nRemainingOut-1 ) - return false; - - pOutPos += strlen( pOutPos ); - nRemainingOut = outLen - (pOutPos - pOut); - - // Now add the replacement string. - if ( !CopyToMaxChars( pOutPos, nRemainingOut, pReplaceWith, replaceToLen ) ) - return false; - - pInStart += copyLen + replaceFromLen; - pOutPos += replaceToLen; - } - else - { - // We're at the end of pIn. Copy whatever remains and get out. - int copyLen = strlen( pInStart ); - V_strncpy( pOutPos, pInStart, nRemainingOut ); - return ( copyLen <= nRemainingOut-1 ); - } - } -} - - -char* AllocString( const char *pStr, int nMaxChars ) -{ - int allocLen; - if ( nMaxChars == -1 ) - allocLen = strlen( pStr ) + 1; - else - allocLen = min( (int)strlen(pStr), nMaxChars ) + 1; - - char *pOut = new char[allocLen]; - V_strncpy( pOut, pStr, allocLen ); - return pOut; -} - - -void V_SplitString2( const char *pString, const char **pSeparators, int nSeparators, CUtlVector &outStrings ) -{ - outStrings.Purge(); - const char *pCurPos = pString; - while ( 1 ) - { - int iFirstSeparator = -1; - const char *pFirstSeparator = 0; - for ( int i=0; i < nSeparators; i++ ) - { - const char *pTest = V_stristr( pCurPos, pSeparators[i] ); - if ( pTest && (!pFirstSeparator || pTest < pFirstSeparator) ) - { - iFirstSeparator = i; - pFirstSeparator = pTest; - } - } - - if ( pFirstSeparator ) - { - // Split on this separator and continue on. - int separatorLen = strlen( pSeparators[iFirstSeparator] ); - if ( pFirstSeparator > pCurPos ) - { - outStrings.AddToTail( AllocString( pCurPos, pFirstSeparator-pCurPos ) ); - } - - pCurPos = pFirstSeparator + separatorLen; - } - else - { - // Copy the rest of the string - if ( strlen( pCurPos ) ) - { - outStrings.AddToTail( AllocString( pCurPos, -1 ) ); - } - return; - } - } -} - - -void V_SplitString( const char *pString, const char *pSeparator, CUtlVector &outStrings ) -{ - V_SplitString2( pString, &pSeparator, 1, outStrings ); -} - - -bool V_GetCurrentDirectory( char *pOut, int maxLen ) -{ -#ifdef LINUX - return getcwd( pOut, maxLen ) == pOut; -#else - return _getcwd( pOut, maxLen ) == pOut; -#endif -} - - -bool V_SetCurrentDirectory( const char *pDirName ) -{ -#ifdef LINUX - return chdir( pDirName ) == 0; -#else - return _chdir( pDirName ) == 0; -#endif -} - - -// This function takes a slice out of pStr and stores it in pOut. -// It follows the Python slice convention: -// Negative numbers wrap around the string (-1 references the last character). -// Numbers are clamped to the end of the string. -void V_StrSlice( const char *pStr, int firstChar, int lastCharNonInclusive, char *pOut, int outSize ) -{ - if ( outSize == 0 ) - return; - - int length = strlen( pStr ); - - // Fixup the string indices. - if ( firstChar < 0 ) - { - firstChar = length - (-firstChar % length); - } - else if ( firstChar >= length ) - { - pOut[0] = 0; - return; - } - - if ( lastCharNonInclusive < 0 ) - { - lastCharNonInclusive = length - (-lastCharNonInclusive % length); - } - else if ( lastCharNonInclusive > length ) - { - lastCharNonInclusive %= length; - } - - if ( lastCharNonInclusive <= firstChar ) - { - pOut[0] = 0; - return; - } - - int copyLen = lastCharNonInclusive - firstChar; - if ( copyLen <= (outSize-1) ) - { - memcpy( pOut, &pStr[firstChar], copyLen ); - pOut[copyLen] = 0; - } - else - { - memcpy( pOut, &pStr[firstChar], outSize-1 ); - pOut[outSize-1] = 0; - } -} - - -void V_StrLeft( const char *pStr, int nChars, char *pOut, int outSize ) -{ - if ( nChars == 0 ) - { - if ( outSize != 0 ) - pOut[0] = 0; - - return; - } - - V_StrSlice( pStr, 0, nChars, pOut, outSize ); -} - - -void V_StrRight( const char *pStr, int nChars, char *pOut, int outSize ) -{ - int len = strlen( pStr ); - if ( nChars >= len ) - { - V_strncpy( pOut, pStr, outSize ); - } - else - { - V_StrSlice( pStr, -nChars, strlen( pStr ), pOut, outSize ); - } -} - -//----------------------------------------------------------------------------- -// Convert multibyte to wchar + back -//----------------------------------------------------------------------------- -void V_strtowcs( const char *pString, int nInSize, wchar_t *pWString, int nOutSize ) -{ -#ifdef _WIN32 - if ( !MultiByteToWideChar( CP_UTF8, 0, pString, nInSize, pWString, nOutSize ) ) - { - *pWString = L'\0'; - } -#elif _LINUX - if ( mbstowcs( pWString, pString, nOutSize / sizeof(wchar_t) ) <= 0 ) - { - *pWString = 0; - } -#endif -} - -void V_wcstostr( const wchar_t *pWString, int nInSize, char *pString, int nOutSize ) -{ -#ifdef _WIN32 - if ( !WideCharToMultiByte( CP_UTF8, 0, pWString, nInSize, pString, nOutSize, NULL, NULL ) ) - { - *pString = '\0'; - } -#elif _LINUX - if ( wcstombs( pString, pWString, nOutSize ) <= 0 ) - { - *pString = '\0'; - } -#endif -} - - - -//-------------------------------------------------------------------------------- -// backslashification -//-------------------------------------------------------------------------------- - -static char s_BackSlashMap[]="\tt\nn\rr\"\"\\\\"; - -char *V_AddBackSlashesToSpecialChars( char const *pSrc ) -{ - // first, count how much space we are going to need - int nSpaceNeeded = 0; - for( char const *pScan = pSrc; *pScan; pScan++ ) - { - nSpaceNeeded++; - for(char const *pCharSet=s_BackSlashMap; *pCharSet; pCharSet += 2 ) - { - if ( *pCharSet == *pScan ) - nSpaceNeeded++; // we need to store a bakslash - } - } - char *pRet = new char[ nSpaceNeeded + 1 ]; // +1 for null - char *pOut = pRet; - - for( char const *pScan = pSrc; *pScan; pScan++ ) - { - bool bIsSpecial = false; - for(char const *pCharSet=s_BackSlashMap; *pCharSet; pCharSet += 2 ) - { - if ( *pCharSet == *pScan ) - { - *( pOut++ ) = '\\'; - *( pOut++ ) = pCharSet[1]; - bIsSpecial = true; - break; - } - } - if (! bIsSpecial ) - { - *( pOut++ ) = *pScan; - } - } - *( pOut++ ) = 0; - return pRet; -} diff --git a/Resources/NetHook/tier1/strtools.h b/Resources/NetHook/tier1/strtools.h deleted file mode 100644 index 986f236c..00000000 --- a/Resources/NetHook/tier1/strtools.h +++ /dev/null @@ -1,462 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// - -#ifndef TIER1_STRTOOLS_H -#define TIER1_STRTOOLS_H - -#include "tier0/platform.h" - -#ifdef _WIN32 -#pragma once -#elif _LINUX -#include -#include -#endif - -#include -#include - -template< class T, class I > class CUtlMemory; -template< class T, class A > class CUtlVector; - - -//----------------------------------------------------------------------------- -// Portable versions of standard string functions -//----------------------------------------------------------------------------- -void _V_memset ( const char* file, int line, void *dest, int fill, int count ); -void _V_memcpy ( const char* file, int line, void *dest, const void *src, int count ); -void _V_memmove ( const char* file, int line, void *dest, const void *src, int count ); -int _V_memcmp ( const char* file, int line, const void *m1, const void *m2, int count ); -int _V_strlen ( const char* file, int line, const char *str ); -void _V_strcpy ( const char* file, int line, char *dest, const char *src ); -char* _V_strrchr ( const char* file, int line, const char *s, char c ); -int _V_strcmp ( const char* file, int line, const char *s1, const char *s2 ); -int _V_wcscmp ( const char* file, int line, const wchar_t *s1, const wchar_t *s2 ); -int _V_stricmp ( const char* file, int line, const char *s1, const char *s2 ); -char* _V_strstr ( const char* file, int line, const char *s1, const char *search ); -char* _V_strupr ( const char* file, int line, char *start ); -char* _V_strlower ( const char* file, int line, char *start ); -int _V_wcslen ( const char* file, int line, const wchar_t *pwch ); - - -#ifdef _DEBUG - -#define V_memset(dest, fill, count) _V_memset (__FILE__, __LINE__, (dest), (fill), (count)) -#define V_memcpy(dest, src, count) _V_memcpy (__FILE__, __LINE__, (dest), (src), (count)) -#define V_memmove(dest, src, count) _V_memmove (__FILE__, __LINE__, (dest), (src), (count)) -#define V_memcmp(m1, m2, count) _V_memcmp (__FILE__, __LINE__, (m1), (m2), (count)) -#define V_strlen(str) _V_strlen (__FILE__, __LINE__, (str)) -#define V_strcpy(dest, src) _V_strcpy (__FILE__, __LINE__, (dest), (src)) -#define V_strrchr(s, c) _V_strrchr (__FILE__, __LINE__, (s), (c)) -#define V_strcmp(s1, s2) _V_strcmp (__FILE__, __LINE__, (s1), (s2)) -#define V_wcscmp(s1, s2) _V_wcscmp (__FILE__, __LINE__, (s1), (s2)) -#define V_stricmp(s1, s2 ) _V_stricmp (__FILE__, __LINE__, (s1), (s2) ) -#define V_strstr(s1, search ) _V_strstr (__FILE__, __LINE__, (s1), (search) ) -#define V_strupr(start) _V_strupr (__FILE__, __LINE__, (start)) -#define V_strlower(start) _V_strlower (__FILE__, __LINE__, (start)) -#define V_wcslen(pwch) _V_wcslen (__FILE__, __LINE__, (pwch)) - -#else - -#ifdef _LINUX -inline char *strupr( char *start ) -{ - char *str = start; - while( str && *str ) - { - *str = (char)toupper(*str); - str++; - } - return start; -} - -inline char *strlwr( char *start ) -{ - char *str = start; - while( str && *str ) - { - *str = (char)tolower(*str); - str++; - } - return start; -} - -#endif // _LINUX - -inline void V_memset (void *dest, int fill, int count) { memset( dest, fill, count ); } -inline void V_memcpy (void *dest, const void *src, int count) { memcpy( dest, src, count ); } -inline void V_memmove (void *dest, const void *src, int count) { memmove( dest, src, count ); } -inline int V_memcmp (const void *m1, const void *m2, int count){ return memcmp( m1, m2, count ); } -inline int V_strlen (const char *str) { return (int) strlen ( str ); } -inline void V_strcpy (char *dest, const char *src) { strcpy( dest, src ); } -inline int V_wcslen(const wchar_t *pwch) { return (int)wcslen(pwch); } -inline char* V_strrchr (const char *s, char c) { return (char*)strrchr( s, c ); } -inline int V_strcmp (const char *s1, const char *s2) { return strcmp( s1, s2 ); } -inline int V_wcscmp (const wchar_t *s1, const wchar_t *s2) { return wcscmp( s1, s2 ); } -inline int V_stricmp( const char *s1, const char *s2 ) { return stricmp( s1, s2 ); } -inline char* V_strstr( const char *s1, const char *search ) { return (char*)strstr( s1, search ); } -inline char* V_strupr (char *start) { return strupr( start ); } -inline char* V_strlower (char *start) { return strlwr( start ); } - -#endif - -int V_strncmp (const char *s1, const char *s2, int count); -int V_strcasecmp (const char *s1, const char *s2); -int V_strncasecmp (const char *s1, const char *s2, int n); -int V_strnicmp (const char *s1, const char *s2, int n); -int V_atoi (const char *str); -float V_atof (const char *str); -char* V_stristr( char* pStr, const char* pSearch ); -const char* V_stristr( const char* pStr, const char* pSearch ); -const char* V_strnistr( const char* pStr, const char* pSearch, int n ); -const char* V_strnchr( const char* pStr, char c, int n ); - -// returns string immediately following prefix, (ie str+strlen(prefix)) or NULL if prefix not found -const char *StringAfterPrefix ( const char *str, const char *prefix ); -const char *StringAfterPrefixCaseSensitive( const char *str, const char *prefix ); -inline bool StringHasPrefix ( const char *str, const char *prefix ) { return StringAfterPrefix ( str, prefix ) != NULL; } -inline bool StringHasPrefixCaseSensitive( const char *str, const char *prefix ) { return StringAfterPrefixCaseSensitive( str, prefix ) != NULL; } - - -// Normalizes a float string in place. -// (removes leading zeros, trailing zeros after the decimal point, and the decimal point itself where possible) -void V_normalizeFloatString( char* pFloat ); - - - -// These are versions of functions that guarantee NULL termination. -// -// maxLen is the maximum number of bytes in the destination string. -// pDest[maxLen-1] is always NULL terminated if pSrc's length is >= maxLen. -// -// This means the last parameter can usually be a sizeof() of a string. -void V_strncpy( char *pDest, const char *pSrc, int maxLen ); -int V_snprintf( char *pDest, int destLen, const char *pFormat, ... ); -void V_wcsncpy( wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes ); -int V_snwprintf( wchar_t *pDest, int destLen, const wchar_t *pFormat, ... ); - -#define COPY_ALL_CHARACTERS -1 -char *V_strncat(char *, const char *, size_t destBufferSize, int max_chars_to_copy=COPY_ALL_CHARACTERS ); -char *V_strnlwr(char *, size_t); - - -// UNDONE: Find a non-compiler-specific way to do this -#ifdef _WIN32 -#ifndef _VA_LIST_DEFINED - -#ifdef _M_ALPHA - -struct va_list -{ - char *a0; /* pointer to first homed integer argument */ - int offset; /* byte offset of next parameter */ -}; - -#else // !_M_ALPHA - -typedef char * va_list; - -#endif // !_M_ALPHA - -#define _VA_LIST_DEFINED - -#endif // _VA_LIST_DEFINED - -#elif _LINUX -#include -#endif - -#ifdef _WIN32 -#define CORRECT_PATH_SEPARATOR '\\' -#define INCORRECT_PATH_SEPARATOR '/' -#elif _LINUX -#define CORRECT_PATH_SEPARATOR '/' -#define INCORRECT_PATH_SEPARATOR '\\' -#endif - -int V_vsnprintf( char *pDest, int maxLen, const char *pFormat, va_list params ); - -// Prints out a pretified memory counter string value ( e.g., 7,233.27 Mb, 1,298.003 Kb, 127 bytes ) -char *V_pretifymem( float value, int digitsafterdecimal = 2, bool usebinaryonek = false ); - -// Prints out a pretified integer with comma separators (eg, 7,233,270,000) -char *V_pretifynum( int64 value ); - -// conversion functions wchar_t <-> char, returning the number of characters converted -int V_UTF8ToUnicode( const char *pUTF8, wchar_t *pwchDest, int cubDestSizeInBytes ); -int V_UnicodeToUTF8( const wchar_t *pUnicode, char *pUTF8, int cubDestSizeInBytes ); - -// Functions for converting hexidecimal character strings back into binary data etc. -// -// e.g., -// int output; -// V_hextobinary( "ffffffff", 8, &output, sizeof( output ) ); -// would make output == 0xfffffff or -1 -// Similarly, -// char buffer[ 9 ]; -// V_binarytohex( &output, sizeof( output ), buffer, sizeof( buffer ) ); -// would put "ffffffff" into buffer (note null terminator!!!) -void V_hextobinary( char const *in, int numchars, byte *out, int maxoutputbytes ); -void V_binarytohex( const byte *in, int inputbytes, char *out, int outsize ); - -// Tools for working with filenames -// Extracts the base name of a file (no path, no extension, assumes '/' or '\' as path separator) -void V_FileBase( const char *in, char *out,int maxlen ); -// Remove the final characters of ppath if it's '\' or '/'. -void V_StripTrailingSlash( char *ppath ); -// Remove any extension from in and return resulting string in out -void V_StripExtension( const char *in, char *out, int outLen ); -// Make path end with extension if it doesn't already have an extension -void V_DefaultExtension( char *path, const char *extension, int pathStringLength ); -// Strips any current extension from path and ensures that extension is the new extension -void V_SetExtension( char *path, const char *extension, int pathStringLength ); -// Removes any filename from path ( strips back to previous / or \ character ) -void V_StripFilename( char *path ); -// Remove the final directory from the path -bool V_StripLastDir( char *dirName, int maxlen ); -// Returns a pointer to the unqualified file name (no path) of a file name -const char * V_UnqualifiedFileName( const char * in ); -// Given a path and a filename, composes "path\filename", inserting the (OS correct) separator if necessary -void V_ComposeFileName( const char *path, const char *filename, char *dest, int destSize ); - -// Copy out the path except for the stuff after the final pathseparator -bool V_ExtractFilePath( const char *path, char *dest, int destSize ); -// Copy out the file extension into dest -void V_ExtractFileExtension( const char *path, char *dest, int destSize ); - -const char *V_GetFileExtension( const char * path ); - -// This removes "./" and "../" from the pathname. pFilename should be a full pathname. -// Returns false if it tries to ".." past the root directory in the drive (in which case -// it is an invalid path). -bool V_RemoveDotSlashes( char *pFilename, char separator = CORRECT_PATH_SEPARATOR ); - -// If pPath is a relative path, this function makes it into an absolute path -// using the current working directory as the base, or pStartingDir if it's non-NULL. -// Returns false if it runs out of room in the string, or if pPath tries to ".." past the root directory. -void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir = NULL ); - -// Creates a relative path given two full paths -// The first is the full path of the file to make a relative path for. -// The second is the full path of the directory to make the first file relative to -// Returns false if they can't be made relative (on separate drives, for example) -bool V_MakeRelativePath( const char *pFullPath, const char *pDirectory, char *pRelativePath, int nBufLen ); - -// Fixes up a file name, removing dot slashes, fixing slashes, converting to lowercase, etc. -void V_FixupPathName( char *pOut, size_t nOutLen, const char *pPath ); - -// Adds a path separator to the end of the string if there isn't one already. Returns false if it would run out of space. -void V_AppendSlash( char *pStr, int strSize ); - -// Returns true if the path is an absolute path. -bool V_IsAbsolutePath( const char *pPath ); - -// Scans pIn and replaces all occurences of pMatch with pReplaceWith. -// Writes the result to pOut. -// Returns true if it completed successfully. -// If it would overflow pOut, it fills as much as it can and returns false. -bool V_StrSubst( const char *pIn, const char *pMatch, const char *pReplaceWith, - char *pOut, int outLen, bool bCaseSensitive=false ); - -// Split the specified string on the specified separator. -// Returns a list of strings separated by pSeparator. -// You are responsible for freeing the contents of outStrings (call outStrings.PurgeAndDeleteElements). -void V_SplitString( const char *pString, const char *pSeparator, CUtlVector > &outStrings ); - -// Just like V_SplitString, but it can use multiple possible separators. -void V_SplitString2( const char *pString, const char **pSeparators, int nSeparators, CUtlVector > &outStrings ); - -// Returns false if the buffer is not large enough to hold the working directory name. -bool V_GetCurrentDirectory( char *pOut, int maxLen ); - -// Set the working directory thus. -bool V_SetCurrentDirectory( const char *pDirName ); - - -// This function takes a slice out of pStr and stores it in pOut. -// It follows the Python slice convention: -// Negative numbers wrap around the string (-1 references the last character). -// Large numbers are clamped to the end of the string. -void V_StrSlice( const char *pStr, int firstChar, int lastCharNonInclusive, char *pOut, int outSize ); - -// Chop off the left nChars of a string. -void V_StrLeft( const char *pStr, int nChars, char *pOut, int outSize ); - -// Chop off the right nChars of a string. -void V_StrRight( const char *pStr, int nChars, char *pOut, int outSize ); - -// change "special" characters to have their c-style backslash sequence. like \n, \r, \t, ", etc. -// returns a pointer to a newly allocated string, which you must delete[] when finished with. -char *V_AddBackSlashesToSpecialChars( char const *pSrc ); - -// Force slashes of either type to be = separator character -void V_FixSlashes( char *pname, char separator = CORRECT_PATH_SEPARATOR ); - -// This function fixes cases of filenames like materials\\blah.vmt or somepath\otherpath\\ and removes the extra double slash. -void V_FixDoubleSlashes( char *pStr ); - -// Convert multibyte to wchar + back -// Specify -1 for nInSize for null-terminated string -void V_strtowcs( const char *pString, int nInSize, wchar_t *pWString, int nOutSize ); -void V_wcstostr( const wchar_t *pWString, int nInSize, char *pString, int nOutSize ); - -// buffer-safe strcat -inline void V_strcat( char *dest, const char *src, int cchDest ) -{ - V_strncat( dest, src, cchDest, COPY_ALL_CHARACTERS ); -} - - -//----------------------------------------------------------------------------- -// generic unique name helper functions -//----------------------------------------------------------------------------- - -// returns startindex if none found, 2 if "prefix" found, and n+1 if "prefixn" found -template < class NameArray > -int V_GenerateUniqueNameIndex( const char *prefix, const NameArray &nameArray, int startindex = 0 ) -{ - if ( prefix == NULL ) - return 0; - - int freeindex = startindex; - - int nNames = nameArray.Count(); - for ( int i = 0; i < nNames; ++i ) - { - const char *pName = nameArray[ i ]; - if ( !pName ) - continue; - - const char *pIndexStr = StringAfterPrefix( pName, prefix ); - if ( pIndexStr ) - { - int index = *pIndexStr ? atoi( pIndexStr ) : 1; - if ( index >= freeindex ) - { - // TODO - check that there isn't more junk after the index in pElementName - freeindex = index + 1; - } - } - } - - return freeindex; -} - -template < class NameArray > -bool V_GenerateUniqueName( char *name, int memsize, const char *prefix, const NameArray &nameArray ) -{ - if ( name == NULL || memsize == 0 ) - return false; - - if ( prefix == NULL ) - { - name[ 0 ] = '\0'; - return false; - } - - int prefixLength = V_strlen( prefix ); - if ( prefixLength + 1 > memsize ) - { - name[ 0 ] = '\0'; - return false; - } - - int i = V_GenerateUniqueNameIndex( prefix, nameArray ); - if ( i <= 0 ) - { - V_strncpy( name, prefix, memsize ); - return true; - } - - int newlen = prefixLength + ( int )log10( ( float )i ) + 1; - if ( newlen + 1 > memsize ) - { - V_strncpy( name, prefix, memsize ); - return false; - } - - V_snprintf( name, memsize, "%s%d", prefix, i ); - return true; -} - - - -// NOTE: This is for backward compatability! -// We need to DLL-export the Q methods in vstdlib but not link to them in other projects -#if !defined( VSTDLIB_BACKWARD_COMPAT ) - -#define Q_memset V_memset -#define Q_memcpy V_memcpy -#define Q_memmove V_memmove -#define Q_memcmp V_memcmp -#define Q_strlen V_strlen -#define Q_strcpy V_strcpy -#define Q_strrchr V_strrchr -#define Q_strcmp V_strcmp -#define Q_wcscmp V_wcscmp -#define Q_stricmp V_stricmp -#define Q_strstr V_strstr -#define Q_strupr V_strupr -#define Q_strlower V_strlower -#define Q_wcslen V_wcslen -#define Q_strncmp V_strncmp -#define Q_strcasecmp V_strcasecmp -#define Q_strncasecmp V_strncasecmp -#define Q_strnicmp V_strnicmp -#define Q_atoi V_atoi -#define Q_atof V_atof -#define Q_stristr V_stristr -#define Q_strnistr V_strnistr -#define Q_strnchr V_strnchr -#define Q_normalizeFloatString V_normalizeFloatString -#define Q_strncpy V_strncpy -#define Q_snprintf V_snprintf -#define Q_wcsncpy V_wcsncpy -#define Q_strncat V_strncat -#define Q_strnlwr V_strnlwr -#define Q_vsnprintf V_vsnprintf -#define Q_pretifymem V_pretifymem -#define Q_pretifynum V_pretifynum -#define Q_UTF8ToUnicode V_UTF8ToUnicode -#define Q_UnicodeToUTF8 V_UnicodeToUTF8 -#define Q_hextobinary V_hextobinary -#define Q_binarytohex V_binarytohex -#define Q_FileBase V_FileBase -#define Q_StripTrailingSlash V_StripTrailingSlash -#define Q_StripExtension V_StripExtension -#define Q_DefaultExtension V_DefaultExtension -#define Q_SetExtension V_SetExtension -#define Q_StripFilename V_StripFilename -#define Q_StripLastDir V_StripLastDir -#define Q_UnqualifiedFileName V_UnqualifiedFileName -#define Q_ComposeFileName V_ComposeFileName -#define Q_ExtractFilePath V_ExtractFilePath -#define Q_ExtractFileExtension V_ExtractFileExtension -#define Q_GetFileExtension V_GetFileExtension -#define Q_RemoveDotSlashes V_RemoveDotSlashes -#define Q_MakeAbsolutePath V_MakeAbsolutePath -#define Q_AppendSlash V_AppendSlash -#define Q_IsAbsolutePath V_IsAbsolutePath -#define Q_StrSubst V_StrSubst -#define Q_SplitString V_SplitString -#define Q_SplitString2 V_SplitString2 -#define Q_StrSlice V_StrSlice -#define Q_StrLeft V_StrLeft -#define Q_StrRight V_StrRight -#define Q_FixSlashes V_FixSlashes -#define Q_strtowcs V_strtowcs -#define Q_wcstostr V_wcstostr -#define Q_strcat V_strcat -#define Q_GenerateUniqueNameIndex V_GenerateUniqueNameIndex -#define Q_GenerateUniqueName V_GenerateUniqueName -#define Q_MakeRelativePath V_MakeRelativePath - -#endif // !defined( VSTDLIB_DLL_EXPORT ) - - -#endif // TIER1_STRTOOLS_H diff --git a/Resources/NetHook/tier1/tier1.cpp b/Resources/NetHook/tier1/tier1.cpp deleted file mode 100644 index 7a20917d..00000000 --- a/Resources/NetHook/tier1/tier1.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//===== Copyright © 2005-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: A higher level link library for general use in the game and tools. -// -//===========================================================================// - -#include -#include "tier0/dbg.h" -#include "vstdlib/iprocessutils.h" -#include "icvar.h" - - -//----------------------------------------------------------------------------- -// These tier1 libraries must be set by any users of this library. -// They can be set by calling ConnectTier1Libraries or InitDefaultFileSystem. -// It is hoped that setting this, and using this library will be the common mechanism for -// allowing link libraries to access tier1 library interfaces -//----------------------------------------------------------------------------- -ICvar *cvar = 0; -ICvar *g_pCVar = 0; -IProcessUtils *g_pProcessUtils = 0; -static bool s_bConnected = false; - -// for utlsortvector.h -#ifndef _WIN32 - void *g_pUtlSortVectorQSortContext = NULL; -#endif - - -//----------------------------------------------------------------------------- -// Call this to connect to all tier 1 libraries. -// It's up to the caller to check the globals it cares about to see if ones are missing -//----------------------------------------------------------------------------- -void ConnectTier1Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount ) -{ - // Don't connect twice.. - if ( s_bConnected ) - return; - - s_bConnected = true; - - for ( int i = 0; i < nFactoryCount; ++i ) - { - if ( !g_pCVar ) - { - cvar = g_pCVar = ( ICvar * )pFactoryList[i]( CVAR_INTERFACE_VERSION, NULL ); - } - if ( !g_pProcessUtils ) - { - g_pProcessUtils = ( IProcessUtils * )pFactoryList[i]( PROCESS_UTILS_INTERFACE_VERSION, NULL ); - } - } -} - -void DisconnectTier1Libraries() -{ - if ( !s_bConnected ) - return; - - g_pCVar = cvar = 0; - g_pProcessUtils = NULL; - s_bConnected = false; -} diff --git a/Resources/NetHook/tier1/tier1.h b/Resources/NetHook/tier1/tier1.h deleted file mode 100644 index f12c7171..00000000 --- a/Resources/NetHook/tier1/tier1.h +++ /dev/null @@ -1,106 +0,0 @@ -//===== Copyright © 2005-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: A higher level link library for general use in the game and tools. -// -//===========================================================================// - - -#ifndef TIER1_H -#define TIER1_H - -#if defined( _WIN32 ) -#pragma once -#endif - -#include "appframework/IAppSystem.h" -#include "tier1/convar.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class ICvar; -class IProcessUtils; - - -//----------------------------------------------------------------------------- -// These tier1 libraries must be set by any users of this library. -// They can be set by calling ConnectTier1Libraries. -// It is hoped that setting this, and using this library will be the common mechanism for -// allowing link libraries to access tier1 library interfaces -//----------------------------------------------------------------------------- - -// These are marked DLL_EXPORT for Linux. -DLL_EXPORT ICvar *cvar; -DLL_EXPORT ICvar *g_pCVar; -extern IProcessUtils *g_pProcessUtils; - - -//----------------------------------------------------------------------------- -// Call this to connect to/disconnect from all tier 1 libraries. -// It's up to the caller to check the globals it cares about to see if ones are missing -//----------------------------------------------------------------------------- -void ConnectTier1Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount ); -void DisconnectTier1Libraries(); - - -//----------------------------------------------------------------------------- -// Helper empty implementation of an IAppSystem for tier2 libraries -//----------------------------------------------------------------------------- -template< class IInterface, int ConVarFlag = 0 > -class CTier1AppSystem : public CTier0AppSystem< IInterface > -{ - typedef CTier0AppSystem< IInterface > BaseClass; - -public: - CTier1AppSystem( bool bIsPrimaryAppSystem = true ) : BaseClass( bIsPrimaryAppSystem ) - { - } - - virtual bool Connect( CreateInterfaceFn factory ) - { - if ( !BaseClass::Connect( factory ) ) - return false; - - if ( IsPrimaryAppSystem() ) - { - ConnectTier1Libraries( &factory, 1 ); - } - return true; - } - - virtual void Disconnect() - { - if ( IsPrimaryAppSystem() ) - { - DisconnectTier1Libraries(); - } - BaseClass::Disconnect(); - } - - virtual InitReturnVal_t Init() - { - InitReturnVal_t nRetVal = BaseClass::Init(); - if ( nRetVal != INIT_OK ) - return nRetVal; - - if ( g_pCVar && IsPrimaryAppSystem() ) - { - ConVar_Register( ConVarFlag ); - } - return INIT_OK; - } - - virtual void Shutdown() - { - if ( g_pCVar && IsPrimaryAppSystem() ) - { - ConVar_Unregister( ); - } - BaseClass::Shutdown( ); - } -}; - - -#endif // TIER1_H - diff --git a/Resources/NetHook/tier1/tokenreader.cpp b/Resources/NetHook/tier1/tokenreader.cpp deleted file mode 100644 index 46d9547c..00000000 --- a/Resources/NetHook/tier1/tokenreader.cpp +++ /dev/null @@ -1,480 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include -#include -#include -#include "tokenreader.h" -#include "tier0/platform.h" -#include "tier1/strtools.h" -#include "tier0/dbg.h" - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -TokenReader::TokenReader(void) -{ - m_szFilename[0] = '\0'; - m_nLine = 1; - m_nErrorCount = 0; - m_bStuffed = false; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pszFilename - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool TokenReader::Open(const char *pszFilename) -{ - open(pszFilename, std::ios::in | std::ios::binary ); - Q_strncpy(m_szFilename, pszFilename, sizeof( m_szFilename ) ); - m_nLine = 1; - m_nErrorCount = 0; - m_bStuffed = false; - return(is_open() != 0); -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void TokenReader::Close() -{ - close(); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *error - -// Output : const char -//----------------------------------------------------------------------------- -const char *TokenReader::Error(char *error, ...) -{ - static char szErrorBuf[256]; - Q_snprintf(szErrorBuf, sizeof( szErrorBuf ), "File %s, line %d: ", m_szFilename, m_nLine); - Q_strncat(szErrorBuf, error, sizeof( szErrorBuf ), COPY_ALL_CHARACTERS ); - m_nErrorCount++; - return(szErrorBuf); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : pszStore - -// nSize - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -trtoken_t TokenReader::GetString(char *pszStore, int nSize) -{ - if (nSize <= 0) - { - return TOKENERROR; - } - - char szBuf[1024]; - - // - // Until we reach the end of this string or run out of room in - // the destination buffer... - // - while (true) - { - // - // Fetch the next batch of text from the file. - // - get(szBuf, sizeof(szBuf), '\"'); - if (eof()) - { - return TOKENEOF; - } - - if (fail()) - { - // Just means nothing was read (empty string probably "") - clear(); - } - - // - // Transfer the text to the destination buffer. - // - char *pszSrc = szBuf; - while ((*pszSrc != '\0') && (nSize > 1)) - { - if (*pszSrc == 0x0d) - { - // - // Newline encountered before closing quote -- unterminated string. - // - *pszStore = '\0'; - return TOKENSTRINGTOOLONG; - } - else if (*pszSrc != '\\') - { - *pszStore = *pszSrc; - pszSrc++; - } - else - { - // - // Backslash sequence - replace with the appropriate character. - // - pszSrc++; - - if (*pszSrc == 'n') - { - *pszStore = '\n'; - } - - pszSrc++; - } - - pszStore++; - nSize--; - } - - if (*pszSrc != '\0') - { - // - // Ran out of room in the destination buffer. Skip to the close-quote, - // terminate the string, and exit. - // - ignore(1024, '\"'); - *pszStore = '\0'; - return TOKENSTRINGTOOLONG; - } - - // - // Check for closing quote. - // - if (peek() == '\"') - { - // - // Eat the close quote and any whitespace. - // - get(); - - bool bCombineStrings = SkipWhiteSpace(); - - // - // Combine consecutive quoted strings if the combine strings character was - // encountered between the two strings. - // - if (bCombineStrings && (peek() == '\"')) - { - // - // Eat the open quote and keep parsing this string. - // - get(); - } - else - { - // - // Done with this string, terminate the string and exit. - // - *pszStore = '\0'; - return STRING; - } - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns the next token, allocating enough memory to store the token -// plus a terminating NULL. -// Input : pszStore - Pointer to a string that will be allocated. -// Output : Returns the type of token that was read, or TOKENERROR. -//----------------------------------------------------------------------------- -trtoken_t TokenReader::NextTokenDynamic(char **ppszStore) -{ - char szTempBuffer[8192]; - trtoken_t eType = NextToken(szTempBuffer, sizeof(szTempBuffer)); - - int len = Q_strlen(szTempBuffer) + 1; - *ppszStore = new char [len]; - Assert( *ppszStore ); - Q_strncpy(*ppszStore, szTempBuffer, len ); - - return(eType); -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns the next token. -// Input : pszStore - Pointer to a string that will receive the token. -// Output : Returns the type of token that was read, or TOKENERROR. -//----------------------------------------------------------------------------- -trtoken_t TokenReader::NextToken(char *pszStore, int nSize) -{ - char *pStart = pszStore; - - if (!is_open()) - { - return TOKENEOF; - } - - // - // If they stuffed a token, return that token. - // - if (m_bStuffed) - { - m_bStuffed = false; - Q_strncpy( pszStore, m_szStuffed, nSize ); - return m_eStuffed; - } - - SkipWhiteSpace(); - - if (eof()) - { - return TOKENEOF; - } - - if (fail()) - { - return TOKENEOF; - } - - char ch = get(); - - // - // Look for all the valid operators. - // - switch (ch) - { - case '@': - case ',': - case '!': - case '+': - case '&': - case '*': - case '$': - case '.': - case '=': - case ':': - case '[': - case ']': - case '(': - case ')': - case '{': - case '}': - case '\\': - { - pszStore[0] = ch; - pszStore[1] = 0; - return OPERATOR; - } - } - - // - // Look for the start of a quoted string. - // - if (ch == '\"') - { - return GetString(pszStore, nSize); - } - - // - // Integers consist of numbers with an optional leading minus sign. - // - if (isdigit(ch) || (ch == '-')) - { - do - { - if ( (pszStore - pStart + 1) < nSize ) - { - *pszStore = ch; - pszStore++; - } - - ch = get(); - if (ch == '-') - { - return TOKENERROR; - } - } while (isdigit(ch)); - - // - // No identifier characters are allowed contiguous with numbers. - // - if (isalpha(ch) || (ch == '_')) - { - return TOKENERROR; - } - - // - // Put back the non-numeric character for the next call. - // - putback(ch); - *pszStore = '\0'; - return INTEGER; - } - - // - // Identifiers consist of a consecutive string of alphanumeric - // characters and underscores. - // - while ( isalpha(ch) || isdigit(ch) || (ch == '_') ) - { - if ( (pszStore - pStart + 1) < nSize ) - { - *pszStore = ch; - pszStore++; - } - - ch = get(); - } - - // - // Put back the non-identifier character for the next call. - // - putback(ch); - *pszStore = '\0'; - return IDENT; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : ttype - -// *pszToken - -//----------------------------------------------------------------------------- -void TokenReader::IgnoreTill(trtoken_t ttype, const char *pszToken) -{ - trtoken_t _ttype; - char szBuf[1024]; - - while(1) - { - _ttype = NextToken(szBuf, sizeof(szBuf)); - if(_ttype == TOKENEOF) - return; - if(_ttype == ttype) - { - if(IsToken(pszToken, szBuf)) - { - Stuff(ttype, pszToken); - return; - } - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : ttype - -// pszToken - -//----------------------------------------------------------------------------- -void TokenReader::Stuff(trtoken_t eType, const char *pszToken) -{ - m_eStuffed = eType; - Q_strncpy(m_szStuffed, pszToken, sizeof( m_szStuffed ) ); - m_bStuffed = true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : ttype - -// pszToken - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool TokenReader::Expecting(trtoken_t ttype, const char *pszToken) -{ - char szBuf[1024]; - if (NextToken(szBuf, sizeof(szBuf)) != ttype || !IsToken(pszToken, szBuf)) - { - return false; - } - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : pszStore - -// Output : -//----------------------------------------------------------------------------- -trtoken_t TokenReader::PeekTokenType(char *pszStore, int maxlen ) -{ - if (!m_bStuffed) - { - m_eStuffed = NextToken(m_szStuffed, sizeof(m_szStuffed)); - m_bStuffed = true; - } - - if (pszStore) - { - Q_strncpy(pszStore, m_szStuffed, maxlen ); - } - - return(m_eStuffed); -} - - -//----------------------------------------------------------------------------- -// Purpose: Gets the next non-whitespace character from the file. -// Input : ch - Receives the character. -// Output : Returns true if the whitespace contained the combine strings -// character '\', which is used to merge consecutive quoted strings. -//----------------------------------------------------------------------------- -bool TokenReader::SkipWhiteSpace(void) -{ - bool bCombineStrings = false; - - while (true) - { - char ch = get(); - - if ((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == 0)) - { - continue; - } - - if (ch == '+') - { - bCombineStrings = true; - continue; - } - - if (ch == '\n') - { - m_nLine++; - continue; - } - - if (eof()) - { - return(bCombineStrings); - } - - // - // Check for the start of a comment. - // - if (ch == '/') - { - if (peek() == '/') - { - ignore(1024, '\n'); - m_nLine++; - } - } - else - { - // - // It is a worthy character. Put it back. - // - putback(ch); - return(bCombineStrings); - } - } -} - diff --git a/Resources/NetHook/tier1/tokenreader.h b/Resources/NetHook/tier1/tokenreader.h deleted file mode 100644 index c2a918aa..00000000 --- a/Resources/NetHook/tier1/tokenreader.h +++ /dev/null @@ -1,105 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef TOKENREADER_H -#define TOKENREADER_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/basetypes.h" - -#ifdef _WIN32 -#pragma warning(push, 1) -#pragma warning(disable:4701 4702 4530) -#endif - -#include - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -#include - - -typedef enum -{ - TOKENSTRINGTOOLONG = -4, - TOKENERROR = -3, - TOKENNONE = -2, - TOKENEOF = -1, - OPERATOR, - INTEGER, - STRING, - IDENT -} trtoken_t; - - -#define IsToken(s1, s2) !strcmpi(s1, s2) - -#define MAX_TOKEN 128 + 1 -#define MAX_IDENT 64 + 1 -#define MAX_STRING 128 + 1 - - -class TokenReader : private std::ifstream -{ -public: - - TokenReader(); - - bool Open(const char *pszFilename); - trtoken_t NextToken(char *pszStore, int nSize); - trtoken_t NextTokenDynamic(char **ppszStore); - void Close(); - - void IgnoreTill(trtoken_t ttype, const char *pszToken); - void Stuff(trtoken_t ttype, const char *pszToken); - bool Expecting(trtoken_t ttype, const char *pszToken); - const char *Error(char *error, ...); - trtoken_t PeekTokenType(char* = NULL, int maxlen = 0); - - inline int GetErrorCount(void); - - inline TokenReader(TokenReader const &) - { - // prevent vc7 warning. compiler can't generate a copy constructor since descended from - // std::ifstream - assert(0); - } - inline int operator=(TokenReader const &) - { - // prevent vc7 warning. compiler can't generate an assignment operator since descended from - // std::ifstream - assert(0); - } -private: - - trtoken_t GetString(char *pszStore, int nSize); - bool SkipWhiteSpace(void); - - int m_nLine; - int m_nErrorCount; - - char m_szFilename[128]; - char m_szStuffed[128]; - bool m_bStuffed; - trtoken_t m_eStuffed; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Returns the total number of parsing errors since this file was opened. -//----------------------------------------------------------------------------- -int TokenReader::GetErrorCount(void) -{ - return(m_nErrorCount); -} - - -#endif // TOKENREADER_H diff --git a/Resources/NetHook/tier1/undiff.cpp b/Resources/NetHook/tier1/undiff.cpp deleted file mode 100644 index 17505b27..00000000 --- a/Resources/NetHook/tier1/undiff.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// UnDiff - Apply difference block -// -//=============================================================================// - -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier1/diff.h" -#include "mathlib/mathlib.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -void ApplyDiffs(uint8 const *OldBlock, uint8 const *DiffList, - int OldSize, int DiffListSize, int &ResultListSize,uint8 *Output,uint32 OutSize) -{ - uint8 const *copy_src=OldBlock; - uint8 const *end_of_diff_list=DiffList+DiffListSize; - uint8 const *obuf=Output; - while(DiffList32767) - copy_ofs|=0xffff0000; - // printf("long cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList+=4; - } - else - { - if (op & 0x80) - { - int copy_sz=op & 0x7f; - int copy_ofs; - if (copy_sz==0) - { - copy_sz=DiffList[0]; - if (copy_sz==0) - { - // big raw copy - copy_sz=DiffList[1]+256*DiffList[2]+65536*DiffList[3]; - memcpy(Output,DiffList+4,copy_sz); - // printf("big rawcopy to %x len=%d\n", Output-obuf,copy_sz); - - DiffList+=copy_sz+4; - Output+=copy_sz; - } - else - { - copy_ofs=DiffList[1]+(DiffList[2]*256); - if (copy_ofs>32767) - copy_ofs|=0xffff0000; - // printf("long ofs cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList+=3; - } - } - else - { - copy_ofs=DiffList[0]; - if (copy_ofs>127) - copy_ofs|=0xffffff80; - // printf("cp from %x to %x len=%d\n", copy_src+copy_ofs-OldBlock,Output-obuf,copy_sz); - - memcpy(Output,copy_src+copy_ofs,copy_sz); - Output+=copy_sz; - copy_src=copy_src+copy_ofs+copy_sz; - DiffList++; - } - } - else - { - // printf("raw copy %d to %x\n",op & 127,Output-obuf); - memcpy(Output,DiffList,op & 127); - Output+=op & 127; - DiffList+=(op & 127); - } - } - } - ResultListSize=Output-obuf; - -} diff --git a/Resources/NetHook/tier1/uniqueid.cpp b/Resources/NetHook/tier1/uniqueid.cpp deleted file mode 100644 index 3fa2661d..00000000 --- a/Resources/NetHook/tier1/uniqueid.cpp +++ /dev/null @@ -1,177 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// Unique ID generation -//=============================================================================// - -#include "tier0/platform.h" - -#ifdef IS_WINDOWS_PC -#include // UUIDCreate -#else -#include "checksum_crc.h" -#endif -#include "tier1/uniqueid.h" -#include "tier1/utlbuffer.h" - -//----------------------------------------------------------------------------- -// Creates a new unique id -//----------------------------------------------------------------------------- -void CreateUniqueId( UniqueId_t *pDest ) -{ -#ifdef IS_WINDOWS_PC - Assert( sizeof( UUID ) == sizeof( *pDest ) ); - UuidCreate( (UUID *)pDest ); -#else - // X360/linux TBD: Need a real UUID Implementation - Q_memset( pDest, 0, sizeof( UniqueId_t ) ); -#endif -} - - -//----------------------------------------------------------------------------- -// Creates a new unique id from a string representation of one -//----------------------------------------------------------------------------- -bool UniqueIdFromString( UniqueId_t *pDest, const char *pBuf, int nMaxLen ) -{ - if ( nMaxLen == 0 ) - { - nMaxLen = Q_strlen( pBuf ); - } - - char *pTemp = (char*)stackalloc( nMaxLen + 1 ); - V_strncpy( pTemp, pBuf, nMaxLen + 1 ); - --nMaxLen; - while( (nMaxLen >= 0) && isspace( pTemp[nMaxLen] ) ) - { - --nMaxLen; - } - pTemp[ nMaxLen + 1 ] = 0; - - while( *pTemp && isspace( *pTemp ) ) - { - ++pTemp; - } - -#ifdef IS_WINDOWS_PC - Assert( sizeof( UUID ) == sizeof( *pDest ) ); - - if ( RPC_S_OK != UuidFromString( (unsigned char *)pTemp, (UUID *)pDest ) ) - { - InvalidateUniqueId( pDest ); - return false; - } -#else - // X360TBD: Need a real UUID Implementation - // For now, use crc to generate a unique ID from the UUID string. - Q_memset( pDest, 0, sizeof( UniqueId_t ) ); - if ( nMaxLen > 0 ) - { - CRC32_t crc; - CRC32_Init( &crc ); - CRC32_ProcessBuffer( &crc, pBuf, nMaxLen ); - CRC32_Final( &crc ); - Q_memcpy( pDest, &crc, sizeof( CRC32_t ) ); - } -#endif - - return true; -} - -//----------------------------------------------------------------------------- -// Sets an object ID to be an invalid state -//----------------------------------------------------------------------------- -void InvalidateUniqueId( UniqueId_t *pDest ) -{ - Assert( pDest ); - memset( pDest, 0, sizeof( UniqueId_t ) ); -} - -bool IsUniqueIdValid( const UniqueId_t &id ) -{ - UniqueId_t invalidId; - memset( &invalidId, 0, sizeof( UniqueId_t ) ); - return !IsUniqueIdEqual( invalidId, id ); -} - -bool IsUniqueIdEqual( const UniqueId_t &id1, const UniqueId_t &id2 ) -{ - return memcmp( &id1, &id2, sizeof( UniqueId_t ) ) == 0; -} - -void UniqueIdToString( const UniqueId_t &id, char *pBuf, int nMaxLen ) -{ - pBuf[ 0 ] = 0; - -// X360TBD: Need a real UUID Implementation -#ifdef IS_WINDOWS_PC - UUID *self = ( UUID * )&id; - - unsigned char *outstring = NULL; - - UuidToString( self, &outstring ); - if ( outstring && *outstring ) - { - Q_strncpy( pBuf, (const char *)outstring, nMaxLen ); - RpcStringFree( &outstring ); - } -#endif -} - -void CopyUniqueId( const UniqueId_t &src, UniqueId_t *pDest ) -{ - memcpy( pDest, &src, sizeof( UniqueId_t ) ); -} - -bool Serialize( CUtlBuffer &buf, const UniqueId_t &src ) -{ -// X360TBD: Need a real UUID Implementation -#ifdef IS_WINDOWS_PC - if ( buf.IsText() ) - { - UUID *pId = ( UUID * )&src; - - unsigned char *outstring = NULL; - - UuidToString( pId, &outstring ); - if ( outstring && *outstring ) - { - buf.PutString( (const char *)outstring ); - RpcStringFree( &outstring ); - } - else - { - buf.PutChar( '\0' ); - } - } - else - { - buf.Put( &src, sizeof(UniqueId_t) ); - } - return buf.IsValid(); -#else - return false; -#endif -} - -bool Unserialize( CUtlBuffer &buf, UniqueId_t &dest ) -{ - if ( buf.IsText() ) - { - int nTextLen = buf.PeekStringLength(); - char *pBuf = (char*)stackalloc( nTextLen ); - buf.GetString( pBuf, nTextLen ); - UniqueIdFromString( &dest, pBuf, nTextLen ); - } - else - { - buf.Get( &dest, sizeof(UniqueId_t) ); - } - return buf.IsValid(); -} - - - diff --git a/Resources/NetHook/tier1/uniqueid.h b/Resources/NetHook/tier1/uniqueid.h deleted file mode 100644 index ca1cc24b..00000000 --- a/Resources/NetHook/tier1/uniqueid.h +++ /dev/null @@ -1,56 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// Utilities for globally unique IDs -//=============================================================================// - -#ifndef UNIQUEID_H -#define UNIQUEID_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlvector.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -struct UniqueId_t; -class CUtlBuffer; - - -//----------------------------------------------------------------------------- -// Defines a globally unique ID -//----------------------------------------------------------------------------- -struct UniqueId_t -{ - unsigned char m_Value[16]; -}; - - -//----------------------------------------------------------------------------- -// Methods related to unique ids -//----------------------------------------------------------------------------- -void CreateUniqueId( UniqueId_t *pDest ); -void InvalidateUniqueId( UniqueId_t *pDest ); -bool IsUniqueIdValid( const UniqueId_t &id ); -bool IsUniqueIdEqual( const UniqueId_t &id1, const UniqueId_t &id2 ); -void UniqueIdToString( const UniqueId_t &id, char *pBuf, int nMaxLen ); -bool UniqueIdFromString( UniqueId_t *pDest, const char *pBuf, int nMaxLen = 0 ); -void CopyUniqueId( const UniqueId_t &src, UniqueId_t *pDest ); -bool Serialize( CUtlBuffer &buf, const UniqueId_t &src ); -bool Unserialize( CUtlBuffer &buf, UniqueId_t &dest ); - -inline bool operator ==( const UniqueId_t& lhs, const UniqueId_t& rhs ) -{ - return !Q_memcmp( (void *)&lhs.m_Value[ 0 ], (void *)&rhs.m_Value[ 0 ], sizeof( lhs.m_Value ) ); -} - - -#endif // UNIQUEID_H - diff --git a/Resources/NetHook/tier1/utlbidirectionalset.h b/Resources/NetHook/tier1/utlbidirectionalset.h deleted file mode 100644 index 32b8622d..00000000 --- a/Resources/NetHook/tier1/utlbidirectionalset.h +++ /dev/null @@ -1,381 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Bi-directional set. A Bucket knows about the elements that lie -// in it, and the elements know about the buckets they lie in. -// -// $Revision: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLBIDIRECTIONALSET_H -#define UTLBIDIRECTIONALSET_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "utllinkedlist.h" - -//----------------------------------------------------------------------------- -// Templatized helper class to deal with the kinds of things that spatial -// partition code always seems to have; buckets with lists of lots of elements -// and elements that live in lots of buckets. This makes it really quick to -// add and remove elements, and to iterate over all elements in a bucket. -// -// For this to work, you must initialize the set with two functions one that -// maps from bucket to the index of the first element in that bucket, and one -// that maps from element to the index of the first bucket that element lies in. -// The set will completely manage the index, it's just expected that those -// indices will be stored outside the set. -// -// S is the storage type of the index; it is the type that you may use to -// save indices into memory. I is the local iterator type, which you should -// use in any local scope (eg, inside a for() loop.) The reason for this is -// that you may wish to use unsigned shorts inside the structs you are -// saving with a CBidirectionalSet; but 16-bit arithmetic is catastrophically -// slow on a PowerPC -- during testing we saw CBidirectionalSet:: operations -// consume as much as 8% of the frame. -// -// For this reason, on the 360, the handles have been typedef'd to native -// register types (U32) which are accepted as parameters by the functions. -// The implicit assumption is that CBucketHandle and CElementHandle can -// be safely cast to ints! You can increase to U64 without performance -// penalty if necessary; the PowerPC is a 64-bit processor. -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I = S > -class CBidirectionalSet -{ -public: - // Install methods to get at the first bucket given a element - // and vice versa... - typedef S& (*FirstElementFunc_t)(CBucketHandle); - typedef S& (*FirstBucketFunc_t)(CElementHandle); - -#ifdef _X360 - typedef uint32 CBucketHandlePram; - typedef uint32 CElementHandlePram; -#else - typedef CBucketHandle CBucketHandlePram; - typedef CElementHandle CElementHandlePram; -#endif - - // Constructor - CBidirectionalSet(); - - // Call this before using the set - void Init( FirstElementFunc_t elemFunc, FirstBucketFunc_t bucketFunc ); - - // Add an element to a particular bucket - void AddElementToBucket( CBucketHandlePram bucket, CElementHandlePram element ); - - // Prevalidate an add to a particular bucket - // NOTE: EXPENSIVE!!! - void ValidateAddElementToBucket( CBucketHandlePram bucket, CElementHandlePram element ); - - // Test if an element is in a particular bucket. - // NOTE: EXPENSIVE!!! - bool IsElementInBucket( CBucketHandlePram bucket, CElementHandlePram element ); - - // Remove an element from a particular bucket - void RemoveElementFromBucket( CBucketHandlePram bucket, CElementHandlePram element ); - - // Remove an element from all buckets - void RemoveElement( CElementHandlePram element ); - void RemoveBucket( CBucketHandlePram element ); - - // Used to iterate elements in a bucket; I is the iterator - I FirstElement( CBucketHandlePram bucket ) const; - I NextElement( I idx ) const; - CElementHandle Element( I idx ) const; - - // Used to iterate buckets associated with an element; I is the iterator - I FirstBucket( CElementHandlePram bucket ) const; - I NextBucket( I idx ) const; - CBucketHandle Bucket( I idx ) const; - - static S InvalidIndex(); - - // Ensure capacity - void EnsureCapacity( int count ); - - // Deallocate.... - void Purge(); - -private: - struct BucketListInfo_t - { - CElementHandle m_Element; - S m_BucketListIndex; // what's the m_BucketsUsedByElement index of the entry? - }; - - struct ElementListInfo_t - { - CBucketHandle m_Bucket; - S m_ElementListIndex; // what's the m_ElementsInBucket index of the entry? - }; - - // Maintains a list of all elements in a particular bucket - CUtlLinkedList< BucketListInfo_t, S, true, I > m_ElementsInBucket; - - // Maintains a list of all buckets a particular element lives in - CUtlLinkedList< ElementListInfo_t, S, true, I > m_BucketsUsedByElement; - - FirstBucketFunc_t m_FirstBucket; - FirstElementFunc_t m_FirstElement; -}; - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -CBidirectionalSet::CBidirectionalSet( ) -{ - m_FirstBucket = NULL; - m_FirstElement = NULL; -} - - -//----------------------------------------------------------------------------- -// Call this before using the set -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::Init( FirstElementFunc_t elemFunc, FirstBucketFunc_t bucketFunc ) -{ - m_FirstBucket = bucketFunc; - m_FirstElement = elemFunc; -} - - -//----------------------------------------------------------------------------- -// Adds an element to the bucket -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::ValidateAddElementToBucket( CBucketHandlePram bucket, CElementHandlePram element ) -{ -#ifdef _DEBUG - // Make sure that this element doesn't already exist in the list of elements in the bucket - I elementInBucket = m_FirstElement( bucket ); - while( elementInBucket != m_ElementsInBucket.InvalidIndex() ) - { - // If you hit an Assert here, fix the calling code. It's too expensive to ensure - // that each item only shows up once here. Hopefully you can do something better - // outside of here. - Assert( m_ElementsInBucket[elementInBucket].m_Element != element ); - elementInBucket = m_ElementsInBucket.Next( elementInBucket ); - } - // Make sure that this bucket doesn't already exist in the element's list of buckets. - I bucketInElement = m_FirstBucket( element ); - while( bucketInElement != m_BucketsUsedByElement.InvalidIndex() ) - { - // If you hit an Assert here, fix the calling code. It's too expensive to ensure - // that each item only shows up once here. Hopefully you can do something better - // outside of here. - Assert( m_BucketsUsedByElement[bucketInElement].m_Bucket != bucket ); - bucketInElement = m_BucketsUsedByElement.Next( bucketInElement ); - } -#endif -} - - -//----------------------------------------------------------------------------- -// Adds an element to the bucket -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::AddElementToBucket( CBucketHandlePram bucket, CElementHandlePram element ) -{ - Assert( m_FirstBucket && m_FirstElement ); - - // Allocate new element + bucket entries - I idx = m_ElementsInBucket.Alloc(true); - I list = m_BucketsUsedByElement.Alloc( true ); - - // Store off the element data - m_ElementsInBucket[idx].m_Element = element; - m_ElementsInBucket[idx].m_BucketListIndex = list; - - // Here's the bucket data - m_BucketsUsedByElement[list].m_Bucket = bucket; - m_BucketsUsedByElement[list].m_ElementListIndex = idx; - - // Insert the element into the list of elements in the bucket - S& firstElementInBucket = m_FirstElement( bucket ); - if ( firstElementInBucket != m_ElementsInBucket.InvalidIndex() ) - m_ElementsInBucket.LinkBefore( firstElementInBucket, idx ); - firstElementInBucket = idx; - - // Insert the bucket into the element's list of buckets - S& firstBucketInElement = m_FirstBucket( element ); - if ( firstBucketInElement != m_BucketsUsedByElement.InvalidIndex() ) - m_BucketsUsedByElement.LinkBefore( firstBucketInElement, list ); - firstBucketInElement = list; -} - -//----------------------------------------------------------------------------- -// Test if an element is in a particular bucket. -// NOTE: EXPENSIVE!!! -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -bool CBidirectionalSet::IsElementInBucket( CBucketHandlePram bucket, CElementHandlePram element ) -{ - // Search through all elements in this bucket to see if element is in there. - I elementInBucket = m_FirstElement( bucket ); - while( elementInBucket != m_ElementsInBucket.InvalidIndex() ) - { - if( m_ElementsInBucket[elementInBucket].m_Element == element ) - { - return true; - } - elementInBucket = m_ElementsInBucket.Next( elementInBucket ); - } - return false; -} - - -//----------------------------------------------------------------------------- -// Remove an element from a particular bucket -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::RemoveElementFromBucket( CBucketHandlePram bucket, CElementHandlePram element ) -{ - // FIXME: Implement me! - Assert(0); -} - - -//----------------------------------------------------------------------------- -// Removes an element from all buckets -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::RemoveElement( CElementHandlePram element ) -{ - Assert( m_FirstBucket && m_FirstElement ); - - // Iterate over the list of all buckets the element is in - I i = m_FirstBucket( element ); - while (i != m_BucketsUsedByElement.InvalidIndex()) - { - CBucketHandlePram bucket = m_BucketsUsedByElement[i].m_Bucket; - I elementListIndex = m_BucketsUsedByElement[i].m_ElementListIndex; - - // Unhook the element from the bucket's list of elements - if (elementListIndex == m_FirstElement(bucket)) - m_FirstElement(bucket) = m_ElementsInBucket.Next(elementListIndex); - m_ElementsInBucket.Free(elementListIndex); - - I prevNode = i; - i = m_BucketsUsedByElement.Next(i); - m_BucketsUsedByElement.Free(prevNode); - } - - // Mark the list as empty - m_FirstBucket( element ) = m_BucketsUsedByElement.InvalidIndex(); -} - -//----------------------------------------------------------------------------- -// Removes a bucket from all elements -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::RemoveBucket( CBucketHandlePram bucket ) -{ - // Iterate over the list of all elements in the bucket - I i = m_FirstElement( bucket ); - while (i != m_ElementsInBucket.InvalidIndex()) - { - CElementHandlePram element = m_ElementsInBucket[i].m_Element; - I bucketListIndex = m_ElementsInBucket[i].m_BucketListIndex; - - // Unhook the bucket from the element's list of buckets - if (bucketListIndex == m_FirstBucket(element)) - m_FirstBucket(element) = m_BucketsUsedByElement.Next(bucketListIndex); - m_BucketsUsedByElement.Free(bucketListIndex); - - // Remove the list element - I prevNode = i; - i = m_ElementsInBucket.Next(i); - m_ElementsInBucket.Free(prevNode); - } - - // Mark the bucket list as empty - m_FirstElement( bucket ) = m_ElementsInBucket.InvalidIndex(); -} - - -//----------------------------------------------------------------------------- -// Ensure capacity -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::EnsureCapacity( int count ) -{ - m_ElementsInBucket.EnsureCapacity( count ); - m_BucketsUsedByElement.EnsureCapacity( count ); -} - - -//----------------------------------------------------------------------------- -// Deallocate.... -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -void CBidirectionalSet::Purge() -{ - m_ElementsInBucket.Purge( ); - m_BucketsUsedByElement.Purge( ); -} - - -//----------------------------------------------------------------------------- -// Invalid index for iteration.. -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -inline S CBidirectionalSet::InvalidIndex() -{ - return CUtlLinkedList< CElementHandle, I >::InvalidIndex(); -} - - -//----------------------------------------------------------------------------- -// Used to iterate elements in a bucket; I is the iterator -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -inline I CBidirectionalSet::FirstElement( CBucketHandlePram bucket ) const -{ - Assert( m_FirstElement ); - return m_FirstElement(bucket); -} - -template< class CBucketHandle, class CElementHandle, class S, class I > -inline I CBidirectionalSet::NextElement( I idx ) const -{ - return m_ElementsInBucket.Next(idx); -} - -template< class CBucketHandle, class CElementHandle, class S, class I > -inline CElementHandle CBidirectionalSet::Element( I idx ) const -{ - return m_ElementsInBucket[idx].m_Element; -} - -//----------------------------------------------------------------------------- -// Used to iterate buckets an element lies in; I is the iterator -//----------------------------------------------------------------------------- -template< class CBucketHandle, class CElementHandle, class S, class I > -inline I CBidirectionalSet::FirstBucket( CElementHandlePram element ) const -{ - Assert( m_FirstBucket ); - return m_FirstBucket(element); -} - -template< class CBucketHandle, class CElementHandle, class S, class I > -inline I CBidirectionalSet::NextBucket( I idx ) const -{ - return m_BucketsUsedByElement.Next(idx); -} - -template< class CBucketHandle, class CElementHandle, class S, class I > -inline CBucketHandle CBidirectionalSet::Bucket( I idx ) const -{ - return m_BucketsUsedByElement[idx].m_Bucket; -} - -#endif // UTLBIDIRECTIONALSET_H diff --git a/Resources/NetHook/tier1/utlblockmemory.h b/Resources/NetHook/tier1/utlblockmemory.h deleted file mode 100644 index 4812d45a..00000000 --- a/Resources/NetHook/tier1/utlblockmemory.h +++ /dev/null @@ -1,349 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -// A growable memory class. -//===========================================================================// - -#ifndef UTLBLOCKMEMORY_H -#define UTLBLOCKMEMORY_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "tier0/platform.h" -#include "mathlib/mathlib.h" - -#include "tier0/memalloc.h" -#include "tier0/memdbgon.h" - -#pragma warning (disable:4100) -#pragma warning (disable:4514) - -//----------------------------------------------------------------------------- - -#ifdef UTLMEMORY_TRACK -#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlBlockMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) -#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlBlockMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) -#else -#define UTLMEMORY_TRACK_ALLOC() ((void)0) -#define UTLMEMORY_TRACK_FREE() ((void)0) -#endif - - -//----------------------------------------------------------------------------- -// The CUtlBlockMemory class: -// A growable memory class that allocates non-sequential blocks, but is indexed sequentially -//----------------------------------------------------------------------------- -template< class T, class I > -class CUtlBlockMemory -{ -public: - // constructor, destructor - CUtlBlockMemory( int nGrowSize = 0, int nInitSize = 0 ); - ~CUtlBlockMemory(); - - // Set the size by which the memory grows - round up to the next power of 2 - void Init( int nGrowSize = 0, int nInitSize = 0 ); - - // here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL - T* Base() { return NULL; } - const T* Base() const { return NULL; } - - class Iterator_t - { - public: - Iterator_t( I i ) : index( i ) {} - I index; - - bool operator==( const Iterator_t it ) const { return index == it.index; } - bool operator!=( const Iterator_t it ) const { return index != it.index; } - }; - Iterator_t First() const { return Iterator_t( IsIdxValid( 0 ) ? 0 : InvalidIndex() ); } - Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( IsIdxValid( it.index + 1 ) ? it.index + 1 : InvalidIndex() ); } - I GetIndex( const Iterator_t &it ) const { return it.index; } - bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; } - bool IsValidIterator( const Iterator_t &it ) const { return IsIdxValid( it.index ); } - Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); } - - // element access - T& operator[]( I i ); - const T& operator[]( I i ) const; - T& Element( I i ); - const T& Element( I i ) const; - - // Can we use this index? - bool IsIdxValid( I i ) const; - static I InvalidIndex() { return ( I )-1; } - - void Swap( CUtlBlockMemory< T, I > &mem ); - - // Size - int NumAllocated() const; - int Count() const { return NumAllocated(); } - - // Grows memory by max(num,growsize) rounded up to the next power of 2, and returns the allocation index/ptr - void Grow( int num = 1 ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - - // Purge all but the given number of elements - void Purge( int numElements ); - -protected: - int Index( int major, int minor ) const { return ( major << m_nIndexShift ) | minor; } - int MajorIndex( int i ) const { return i >> m_nIndexShift; } - int MinorIndex( int i ) const { return i & m_nIndexMask; } - void ChangeSize( int nBlocks ); - int NumElementsInBlock() const { return m_nIndexMask + 1; } - - T** m_pMemory; - int m_nBlocks; - int m_nIndexMask : 27; - int m_nIndexShift : 5; -}; - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T, class I > -CUtlBlockMemory::CUtlBlockMemory( int nGrowSize, int nInitAllocationCount ) -: m_pMemory( 0 ), m_nBlocks( 0 ), m_nIndexMask( 0 ), m_nIndexShift( 0 ) -{ - Init( nGrowSize, nInitAllocationCount ); -} - -template< class T, class I > -CUtlBlockMemory::~CUtlBlockMemory() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -// Fast swap -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlBlockMemory::Swap( CUtlBlockMemory< T, I > &mem ) -{ - swap( m_pMemory, mem.m_pMemory ); - swap( m_nBlocks, mem.m_nBlocks ); - swap( m_nIndexMask, mem.m_nIndexMask ); - swap( m_nIndexShift, mem.m_nIndexShift ); -} - - -//----------------------------------------------------------------------------- -// Set the size by which the memory grows - round up to the next power of 2 -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlBlockMemory::Init( int nGrowSize /* = 0 */, int nInitSize /* = 0 */ ) -{ - Purge(); - - if ( nGrowSize == 0) - { - // default grow size is smallest size s.t. c++ allocation overhead is ~6% of block size - nGrowSize = ( 127 + sizeof( T ) ) / sizeof( T ); - } - nGrowSize = SmallestPowerOfTwoGreaterOrEqual( nGrowSize ); - m_nIndexMask = nGrowSize - 1; - - m_nIndexShift = 0; - while ( nGrowSize > 1 ) - { - nGrowSize >>= 1; - ++m_nIndexShift; - } - Assert( m_nIndexMask + 1 == ( 1 << m_nIndexShift ) ); - - Grow( nInitSize ); -} - - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< class T, class I > -inline T& CUtlBlockMemory::operator[]( I i ) -{ - Assert( IsIdxValid(i) ); - T *pBlock = m_pMemory[ MajorIndex( i ) ]; - return pBlock[ MinorIndex( i ) ]; -} - -template< class T, class I > -inline const T& CUtlBlockMemory::operator[]( I i ) const -{ - Assert( IsIdxValid(i) ); - const T *pBlock = m_pMemory[ MajorIndex( i ) ]; - return pBlock[ MinorIndex( i ) ]; -} - -template< class T, class I > -inline T& CUtlBlockMemory::Element( I i ) -{ - Assert( IsIdxValid(i) ); - T *pBlock = m_pMemory[ MajorIndex( i ) ]; - return pBlock[ MinorIndex( i ) ]; -} - -template< class T, class I > -inline const T& CUtlBlockMemory::Element( I i ) const -{ - Assert( IsIdxValid(i) ); - const T *pBlock = m_pMemory[ MajorIndex( i ) ]; - return pBlock[ MinorIndex( i ) ]; -} - - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- -template< class T, class I > -inline int CUtlBlockMemory::NumAllocated() const -{ - return m_nBlocks * NumElementsInBlock(); -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< class T, class I > -inline bool CUtlBlockMemory::IsIdxValid( I i ) const -{ - return ( i >= 0 ) && ( MajorIndex( i ) < m_nBlocks ); -} - -template< class T, class I > -void CUtlBlockMemory::Grow( int num ) -{ - if ( num <= 0 ) - return; - - int nBlockSize = NumElementsInBlock(); - int nBlocks = ( num + nBlockSize - 1 ) / nBlockSize; - - ChangeSize( m_nBlocks + nBlocks ); -} - -template< class T, class I > -void CUtlBlockMemory::ChangeSize( int nBlocks ) -{ - UTLMEMORY_TRACK_FREE(); // this must stay before the recalculation of m_nBlocks, since it implicitly uses the old value - - int nBlocksOld = m_nBlocks; - m_nBlocks = nBlocks; - - UTLMEMORY_TRACK_ALLOC(); // this must stay after the recalculation of m_nBlocks, since it implicitly uses the new value - - // free old blocks if shrinking - for ( int i = m_nBlocks; i < nBlocksOld; ++i ) - { - UTLMEMORY_TRACK_FREE(); - free( (void*)m_pMemory[ i ] ); - } - - if ( m_pMemory ) - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T**)realloc( m_pMemory, m_nBlocks * sizeof(T*) ); - Assert( m_pMemory ); - } - else - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T**)malloc( m_nBlocks * sizeof(T*) ); - Assert( m_pMemory ); - } - - if ( !m_pMemory ) - { - Error( "CUtlBlockMemory overflow!\n" ); - } - - // allocate new blocks if growing - int nBlockSize = NumElementsInBlock(); - for ( int i = nBlocksOld; i < m_nBlocks; ++i ) - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory[ i ] = (T*)malloc( nBlockSize * sizeof( T ) ); - Assert( m_pMemory[ i ] ); - } -} - - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -template< class T, class I > -inline void CUtlBlockMemory::EnsureCapacity( int num ) -{ - Grow( num - NumAllocated() ); -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlBlockMemory::Purge() -{ - if ( !m_pMemory ) - return; - - for ( int i = 0; i < m_nBlocks; ++i ) - { - UTLMEMORY_TRACK_FREE(); - free( (void*)m_pMemory[ i ] ); - } - m_nBlocks = 0; - - UTLMEMORY_TRACK_FREE(); - free( (void*)m_pMemory ); - m_pMemory = 0; -} - -template< class T, class I > -void CUtlBlockMemory::Purge( int numElements ) -{ - Assert( numElements >= 0 ); - - int nAllocated = NumAllocated(); - if ( numElements > nAllocated ) - { - // Ensure this isn't a grow request in disguise. - Assert( numElements <= nAllocated ); - return; - } - - if ( numElements <= 0 ) - { - Purge(); - return; - } - - int nBlockSize = NumElementsInBlock(); - int nBlocksOld = m_nBlocks; - int nBlocks = ( numElements + nBlockSize - 1 ) / nBlockSize; - - // If the number of blocks is the same as the allocated number of blocks, we are done. - if ( nBlocks == m_nBlocks ) - return; - - ChangeSize( nBlocks ); -} - -#include "tier0/memdbgoff.h" - -#endif // UTLBLOCKMEMORY_H diff --git a/Resources/NetHook/tier1/utlbuffer.cpp b/Resources/NetHook/tier1/utlbuffer.cpp deleted file mode 100644 index 6babdf5d..00000000 --- a/Resources/NetHook/tier1/utlbuffer.cpp +++ /dev/null @@ -1,1747 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// $Header: $ -// $NoKeywords: $ -// -// Serialization buffer -//===========================================================================// - -#pragma warning (disable : 4514) - -#include "utlbuffer.h" -#include -#include -#include -#include -#include -#include "tier1/strtools.h" -#include "tier1/characterset.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -//----------------------------------------------------------------------------- -// Character conversions for C strings -//----------------------------------------------------------------------------- -class CUtlCStringConversion : public CUtlCharConversion -{ -public: - CUtlCStringConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray ); - - // Finds a conversion for the passed-in string, returns length - virtual char FindConversion( const char *pString, int *pLength ); - -private: - char m_pConversion[255]; -}; - - -//----------------------------------------------------------------------------- -// Character conversions for no-escape sequence strings -//----------------------------------------------------------------------------- -class CUtlNoEscConversion : public CUtlCharConversion -{ -public: - CUtlNoEscConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray ) : - CUtlCharConversion( nEscapeChar, pDelimiter, nCount, pArray ) {} - - // Finds a conversion for the passed-in string, returns length - virtual char FindConversion( const char *pString, int *pLength ) { *pLength = 0; return 0; } -}; - - -//----------------------------------------------------------------------------- -// List of character conversions -//----------------------------------------------------------------------------- -BEGIN_CUSTOM_CHAR_CONVERSION( CUtlCStringConversion, s_StringCharConversion, "\"", '\\' ) - { '\n', "n" }, - { '\t', "t" }, - { '\v', "v" }, - { '\b', "b" }, - { '\r', "r" }, - { '\f', "f" }, - { '\a', "a" }, - { '\\', "\\" }, - { '\?', "\?" }, - { '\'', "\'" }, - { '\"', "\"" }, -END_CUSTOM_CHAR_CONVERSION( CUtlCStringConversion, s_StringCharConversion, "\"", '\\' ) - -CUtlCharConversion *GetCStringCharConversion() -{ - return &s_StringCharConversion; -} - -BEGIN_CUSTOM_CHAR_CONVERSION( CUtlNoEscConversion, s_NoEscConversion, "\"", 0x7F ) - { 0x7F, "" }, -END_CUSTOM_CHAR_CONVERSION( CUtlNoEscConversion, s_NoEscConversion, "\"", 0x7F ) - -CUtlCharConversion *GetNoEscCharConversion() -{ - return &s_NoEscConversion; -} - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -CUtlCStringConversion::CUtlCStringConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray ) : - CUtlCharConversion( nEscapeChar, pDelimiter, nCount, pArray ) -{ - memset( m_pConversion, 0x0, sizeof(m_pConversion) ); - for ( int i = 0; i < nCount; ++i ) - { - m_pConversion[ pArray[i].m_pReplacementString[0] ] = pArray[i].m_nActualChar; - } -} - -// Finds a conversion for the passed-in string, returns length -char CUtlCStringConversion::FindConversion( const char *pString, int *pLength ) -{ - char c = m_pConversion[ pString[0] ]; - *pLength = (c != '\0') ? 1 : 0; - return c; -} - - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -CUtlCharConversion::CUtlCharConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray ) -{ - m_nEscapeChar = nEscapeChar; - m_pDelimiter = pDelimiter; - m_nCount = nCount; - m_nDelimiterLength = Q_strlen( pDelimiter ); - m_nMaxConversionLength = 0; - - memset( m_pReplacements, 0, sizeof(m_pReplacements) ); - - for ( int i = 0; i < nCount; ++i ) - { - m_pList[i] = pArray[i].m_nActualChar; - ConversionInfo_t &info = m_pReplacements[ m_pList[i] ]; - Assert( info.m_pReplacementString == 0 ); - info.m_pReplacementString = pArray[i].m_pReplacementString; - info.m_nLength = Q_strlen( info.m_pReplacementString ); - if ( info.m_nLength > m_nMaxConversionLength ) - { - m_nMaxConversionLength = info.m_nLength; - } - } -} - - -//----------------------------------------------------------------------------- -// Escape character + delimiter -//----------------------------------------------------------------------------- -char CUtlCharConversion::GetEscapeChar() const -{ - return m_nEscapeChar; -} - -const char *CUtlCharConversion::GetDelimiter() const -{ - return m_pDelimiter; -} - -int CUtlCharConversion::GetDelimiterLength() const -{ - return m_nDelimiterLength; -} - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -const char *CUtlCharConversion::GetConversionString( char c ) const -{ - return m_pReplacements[ c ].m_pReplacementString; -} - -int CUtlCharConversion::GetConversionLength( char c ) const -{ - return m_pReplacements[ c ].m_nLength; -} - -int CUtlCharConversion::MaxConversionLength() const -{ - return m_nMaxConversionLength; -} - - -//----------------------------------------------------------------------------- -// Finds a conversion for the passed-in string, returns length -//----------------------------------------------------------------------------- -char CUtlCharConversion::FindConversion( const char *pString, int *pLength ) -{ - for ( int i = 0; i < m_nCount; ++i ) - { - if ( !Q_strcmp( pString, m_pReplacements[ m_pList[i] ].m_pReplacementString ) ) - { - *pLength = m_pReplacements[ m_pList[i] ].m_nLength; - return m_pList[i]; - } - } - - *pLength = 0; - return '\0'; -} - - -//----------------------------------------------------------------------------- -// constructors -//----------------------------------------------------------------------------- -CUtlBuffer::CUtlBuffer( int growSize, int initSize, int nFlags ) : - m_Memory( growSize, initSize ), m_Error(0) -{ - m_Get = 0; - m_Put = 0; - m_nTab = 0; - m_nOffset = 0; - m_Flags = nFlags; - if ( (initSize != 0) && !IsReadOnly() ) - { - m_nMaxPut = -1; - AddNullTermination(); - } - else - { - m_nMaxPut = 0; - } - SetOverflowFuncs( &CUtlBuffer::GetOverflow, &CUtlBuffer::PutOverflow ); -} - -CUtlBuffer::CUtlBuffer( const void *pBuffer, int nSize, int nFlags ) : - m_Memory( (unsigned char*)pBuffer, nSize ), m_Error(0) -{ - Assert( nSize != 0 ); - - m_Get = 0; - m_Put = 0; - m_nTab = 0; - m_nOffset = 0; - m_Flags = nFlags; - if ( IsReadOnly() ) - { - m_nMaxPut = nSize; - } - else - { - m_nMaxPut = -1; - AddNullTermination(); - } - SetOverflowFuncs( &CUtlBuffer::GetOverflow, &CUtlBuffer::PutOverflow ); -} - - -//----------------------------------------------------------------------------- -// Modifies the buffer to be binary or text; Blows away the buffer and the CONTAINS_CRLF value. -//----------------------------------------------------------------------------- -void CUtlBuffer::SetBufferType( bool bIsText, bool bContainsCRLF ) -{ -#ifdef _DEBUG - // If the buffer is empty, there is no opportunity for this stuff to fail - if ( TellMaxPut() != 0 ) - { - if ( IsText() ) - { - if ( bIsText ) - { - Assert( ContainsCRLF() == bContainsCRLF ); - } - else - { - Assert( ContainsCRLF() ); - } - } - else - { - if ( bIsText ) - { - Assert( bContainsCRLF ); - } - } - } -#endif - - if ( bIsText ) - { - m_Flags |= TEXT_BUFFER; - } - else - { - m_Flags &= ~TEXT_BUFFER; - } - if ( bContainsCRLF ) - { - m_Flags |= CONTAINS_CRLF; - } - else - { - m_Flags &= ~CONTAINS_CRLF; - } -} - - -//----------------------------------------------------------------------------- -// Attaches the buffer to external memory.... -//----------------------------------------------------------------------------- -void CUtlBuffer::SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags ) -{ - m_Memory.SetExternalBuffer( (unsigned char*)pMemory, nSize ); - - // Reset all indices; we just changed memory - m_Get = 0; - m_Put = nInitialPut; - m_nTab = 0; - m_Error = 0; - m_nOffset = 0; - m_Flags = nFlags; - m_nMaxPut = -1; - AddNullTermination(); -} - -//----------------------------------------------------------------------------- -// Assumes an external buffer but manages its deletion -//----------------------------------------------------------------------------- -void CUtlBuffer::AssumeMemory( void *pMemory, int nSize, int nInitialPut, int nFlags ) -{ - m_Memory.AssumeMemory( (unsigned char*) pMemory, nSize ); - - // Reset all indices; we just changed memory - m_Get = 0; - m_Put = nInitialPut; - m_nTab = 0; - m_Error = 0; - m_nOffset = 0; - m_Flags = nFlags; - m_nMaxPut = -1; - AddNullTermination(); -} - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -void CUtlBuffer::EnsureCapacity( int num ) -{ - // Add one extra for the null termination - num += 1; - if ( m_Memory.IsExternallyAllocated() ) - { - if ( IsGrowable() && ( m_Memory.NumAllocated() < num ) ) - { - m_Memory.ConvertToGrowableMemory( 0 ); - } - else - { - num -= 1; - } - } - - m_Memory.EnsureCapacity( num ); -} - - -//----------------------------------------------------------------------------- -// Base get method from which all others derive -//----------------------------------------------------------------------------- -void CUtlBuffer::Get( void* pMem, int size ) -{ - if ( CheckGet( size ) ) - { - memcpy( pMem, &m_Memory[m_Get - m_nOffset], size ); - m_Get += size; - } -} - - -//----------------------------------------------------------------------------- -// This will get at least 1 byte and up to nSize bytes. -// It will return the number of bytes actually read. -//----------------------------------------------------------------------------- -int CUtlBuffer::GetUpTo( void *pMem, int nSize ) -{ - if ( CheckArbitraryPeekGet( 0, nSize ) ) - { - memcpy( pMem, &m_Memory[m_Get - m_nOffset], nSize ); - m_Get += nSize; - return nSize; - } - return 0; -} - - -//----------------------------------------------------------------------------- -// Eats whitespace -//----------------------------------------------------------------------------- -void CUtlBuffer::EatWhiteSpace() -{ - if ( IsText() && IsValid() ) - { - while ( CheckGet( sizeof(char) ) ) - { - if ( !isspace( *(const unsigned char*)PeekGet() ) ) - break; - m_Get += sizeof(char); - } - } -} - - -//----------------------------------------------------------------------------- -// Eats C++ style comments -//----------------------------------------------------------------------------- -bool CUtlBuffer::EatCPPComment() -{ - if ( IsText() && IsValid() ) - { - // If we don't have a a c++ style comment next, we're done - const char *pPeek = (const char *)PeekGet( 2 * sizeof(char), 0 ); - if ( !pPeek || ( pPeek[0] != '/' ) || ( pPeek[1] != '/' ) ) - return false; - - // Deal with c++ style comments - m_Get += 2; - - // read complete line - for ( char c = GetChar(); IsValid(); c = GetChar() ) - { - if ( c == '\n' ) - break; - } - return true; - } - return false; -} - - -//----------------------------------------------------------------------------- -// Peeks how much whitespace to eat -//----------------------------------------------------------------------------- -int CUtlBuffer::PeekWhiteSpace( int nOffset ) -{ - if ( !IsText() || !IsValid() ) - return 0; - - while ( CheckPeekGet( nOffset, sizeof(char) ) ) - { - if ( !isspace( *(unsigned char*)PeekGet( nOffset ) ) ) - break; - nOffset += sizeof(char); - } - - return nOffset; -} - - -//----------------------------------------------------------------------------- -// Peek size of sting to come, check memory bound -//----------------------------------------------------------------------------- -int CUtlBuffer::PeekStringLength() -{ - if ( !IsValid() ) - return 0; - - // Eat preceeding whitespace - int nOffset = 0; - if ( IsText() ) - { - nOffset = PeekWhiteSpace( nOffset ); - } - - int nStartingOffset = nOffset; - - do - { - int nPeekAmount = 128; - - // NOTE: Add 1 for the terminating zero! - if ( !CheckArbitraryPeekGet( nOffset, nPeekAmount ) ) - { - if ( nOffset == nStartingOffset ) - return 0; - return nOffset - nStartingOffset + 1; - } - - const char *pTest = (const char *)PeekGet( nOffset ); - - if ( !IsText() ) - { - for ( int i = 0; i < nPeekAmount; ++i ) - { - // The +1 here is so we eat the terminating 0 - if ( pTest[i] == 0 ) - return (i + nOffset - nStartingOffset + 1); - } - } - else - { - for ( int i = 0; i < nPeekAmount; ++i ) - { - // The +1 here is so we eat the terminating 0 - if ( isspace((unsigned char)pTest[i]) || (pTest[i] == 0) ) - return (i + nOffset - nStartingOffset + 1); - } - } - - nOffset += nPeekAmount; - - } while ( true ); -} - - -//----------------------------------------------------------------------------- -// Peek size of line to come, check memory bound -//----------------------------------------------------------------------------- -int CUtlBuffer::PeekLineLength() -{ - if ( !IsValid() ) - return 0; - - int nOffset = 0; - int nStartingOffset = nOffset; - - do - { - int nPeekAmount = 128; - - // NOTE: Add 1 for the terminating zero! - if ( !CheckArbitraryPeekGet( nOffset, nPeekAmount ) ) - { - if ( nOffset == nStartingOffset ) - return 0; - return nOffset - nStartingOffset + 1; - } - - const char *pTest = (const char *)PeekGet( nOffset ); - - for ( int i = 0; i < nPeekAmount; ++i ) - { - // The +2 here is so we eat the terminating '\n' and 0 - if ( pTest[i] == '\n' || pTest[i] == '\r' ) - return (i + nOffset - nStartingOffset + 2); - // The +1 here is so we eat the terminating 0 - if ( pTest[i] == 0 ) - return (i + nOffset - nStartingOffset + 1); - } - - nOffset += nPeekAmount; - - } while ( true ); -} - - -//----------------------------------------------------------------------------- -// Does the next bytes of the buffer match a pattern? -//----------------------------------------------------------------------------- -bool CUtlBuffer::PeekStringMatch( int nOffset, const char *pString, int nLen ) -{ - if ( !CheckPeekGet( nOffset, nLen ) ) - return false; - return !Q_strncmp( (const char*)PeekGet(nOffset), pString, nLen ); -} - - -//----------------------------------------------------------------------------- -// This version of PeekStringLength converts \" to \\ and " to \, etc. -// It also reads a " at the beginning and end of the string -//----------------------------------------------------------------------------- -int CUtlBuffer::PeekDelimitedStringLength( CUtlCharConversion *pConv, bool bActualSize ) -{ - if ( !IsText() || !pConv ) - return PeekStringLength(); - - // Eat preceeding whitespace - int nOffset = 0; - if ( IsText() ) - { - nOffset = PeekWhiteSpace( nOffset ); - } - - if ( !PeekStringMatch( nOffset, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) - return 0; - - // Try to read ending ", but don't accept \" - int nActualStart = nOffset; - nOffset += pConv->GetDelimiterLength(); - int nLen = 1; // Starts at 1 for the '\0' termination - - do - { - if ( PeekStringMatch( nOffset, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) - break; - - if ( !CheckPeekGet( nOffset, 1 ) ) - break; - - char c = *(const char*)PeekGet( nOffset ); - ++nLen; - ++nOffset; - if ( c == pConv->GetEscapeChar() ) - { - int nLength = pConv->MaxConversionLength(); - if ( !CheckArbitraryPeekGet( nOffset, nLength ) ) - break; - - pConv->FindConversion( (const char*)PeekGet(nOffset), &nLength ); - nOffset += nLength; - } - } while (true); - - return bActualSize ? nLen : nOffset - nActualStart + pConv->GetDelimiterLength() + 1; -} - - -//----------------------------------------------------------------------------- -// Reads a null-terminated string -//----------------------------------------------------------------------------- -void CUtlBuffer::GetString( char* pString, int nMaxChars ) -{ - if (!IsValid()) - { - *pString = 0; - return; - } - - if ( nMaxChars == 0 ) - { - nMaxChars = INT_MAX; - } - - // Remember, this *includes* the null character - // It will be 0, however, if the buffer is empty. - int nLen = PeekStringLength(); - - if ( IsText() ) - { - EatWhiteSpace(); - } - - if ( nLen == 0 ) - { - *pString = 0; - m_Error |= GET_OVERFLOW; - return; - } - - // Strip off the terminating NULL - if ( nLen <= nMaxChars ) - { - Get( pString, nLen - 1 ); - pString[ nLen - 1 ] = 0; - } - else - { - Get( pString, nMaxChars - 1 ); - pString[ nMaxChars - 1 ] = 0; - SeekGet( SEEK_CURRENT, nLen - 1 - nMaxChars ); - } - - // Read the terminating NULL in binary formats - if ( !IsText() ) - { - VerifyEquals( GetChar(), 0 ); - } -} - - -//----------------------------------------------------------------------------- -// Reads up to and including the first \n -//----------------------------------------------------------------------------- -void CUtlBuffer::GetLine( char* pLine, int nMaxChars ) -{ - Assert( IsText() && !ContainsCRLF() ); - - if ( !IsValid() ) - { - *pLine = 0; - return; - } - - if ( nMaxChars == 0 ) - { - nMaxChars = INT_MAX; - } - - // Remember, this *includes* the null character - // It will be 0, however, if the buffer is empty. - int nLen = PeekLineLength(); - if ( nLen == 0 ) - { - *pLine = 0; - m_Error |= GET_OVERFLOW; - return; - } - - // Strip off the terminating NULL - if ( nLen <= nMaxChars ) - { - Get( pLine, nLen - 1 ); - pLine[ nLen - 1 ] = 0; - } - else - { - Get( pLine, nMaxChars - 1 ); - pLine[ nMaxChars - 1 ] = 0; - SeekGet( SEEK_CURRENT, nLen - 1 - nMaxChars ); - } -} - - -//----------------------------------------------------------------------------- -// This version of GetString converts \ to \\ and " to \", etc. -// It also places " at the beginning and end of the string -//----------------------------------------------------------------------------- -char CUtlBuffer::GetDelimitedCharInternal( CUtlCharConversion *pConv ) -{ - char c = GetChar(); - if ( c == pConv->GetEscapeChar() ) - { - int nLength = pConv->MaxConversionLength(); - if ( !CheckArbitraryPeekGet( 0, nLength ) ) - return '\0'; - - c = pConv->FindConversion( (const char *)PeekGet(), &nLength ); - SeekGet( SEEK_CURRENT, nLength ); - } - - return c; -} - -char CUtlBuffer::GetDelimitedChar( CUtlCharConversion *pConv ) -{ - if ( !IsText() || !pConv ) - return GetChar( ); - return GetDelimitedCharInternal( pConv ); -} - -void CUtlBuffer::GetDelimitedString( CUtlCharConversion *pConv, char *pString, int nMaxChars ) -{ - if ( !IsText() || !pConv ) - { - GetString( pString, nMaxChars ); - return; - } - - if (!IsValid()) - { - *pString = 0; - return; - } - - if ( nMaxChars == 0 ) - { - nMaxChars = INT_MAX; - } - - EatWhiteSpace(); - if ( !PeekStringMatch( 0, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) - return; - - // Pull off the starting delimiter - SeekGet( SEEK_CURRENT, pConv->GetDelimiterLength() ); - - int nRead = 0; - while ( IsValid() ) - { - if ( PeekStringMatch( 0, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) - { - SeekGet( SEEK_CURRENT, pConv->GetDelimiterLength() ); - break; - } - - char c = GetDelimitedCharInternal( pConv ); - - if ( nRead < nMaxChars ) - { - pString[nRead] = c; - ++nRead; - } - } - - if ( nRead >= nMaxChars ) - { - nRead = nMaxChars - 1; - } - pString[nRead] = '\0'; -} - - -//----------------------------------------------------------------------------- -// Checks if a get is ok -//----------------------------------------------------------------------------- -bool CUtlBuffer::CheckGet( int nSize ) -{ - if ( m_Error & GET_OVERFLOW ) - return false; - - if ( TellMaxPut() < m_Get + nSize ) - { - m_Error |= GET_OVERFLOW; - return false; - } - - if ( ( m_Get < m_nOffset ) || ( m_Memory.NumAllocated() < m_Get - m_nOffset + nSize ) ) - { - if ( !OnGetOverflow( nSize ) ) - { - m_Error |= GET_OVERFLOW; - return false; - } - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Checks if a peek get is ok -//----------------------------------------------------------------------------- -bool CUtlBuffer::CheckPeekGet( int nOffset, int nSize ) -{ - if ( m_Error & GET_OVERFLOW ) - return false; - - // Checking for peek can't set the overflow flag - bool bOk = CheckGet( nOffset + nSize ); - m_Error &= ~GET_OVERFLOW; - return bOk; -} - - -//----------------------------------------------------------------------------- -// Call this to peek arbitrarily long into memory. It doesn't fail unless -// it can't read *anything* new -//----------------------------------------------------------------------------- -bool CUtlBuffer::CheckArbitraryPeekGet( int nOffset, int &nIncrement ) -{ - if ( TellGet() + nOffset >= TellMaxPut() ) - { - nIncrement = 0; - return false; - } - - if ( TellGet() + nOffset + nIncrement > TellMaxPut() ) - { - nIncrement = TellMaxPut() - TellGet() - nOffset; - } - - // NOTE: CheckPeekGet could modify TellMaxPut for streaming files - // We have to call TellMaxPut again here - CheckPeekGet( nOffset, nIncrement ); - int nMaxGet = TellMaxPut() - TellGet(); - if ( nMaxGet < nIncrement ) - { - nIncrement = nMaxGet; - } - return (nIncrement != 0); -} - - -//----------------------------------------------------------------------------- -// Peek part of the butt -//----------------------------------------------------------------------------- -const void* CUtlBuffer::PeekGet( int nMaxSize, int nOffset ) -{ - if ( !CheckPeekGet( nOffset, nMaxSize ) ) - return NULL; - return &m_Memory[ m_Get + nOffset - m_nOffset ]; -} - - -//----------------------------------------------------------------------------- -// Change where I'm reading -//----------------------------------------------------------------------------- -void CUtlBuffer::SeekGet( SeekType_t type, int offset ) -{ - switch( type ) - { - case SEEK_HEAD: - m_Get = offset; - break; - - case SEEK_CURRENT: - m_Get += offset; - break; - - case SEEK_TAIL: - m_Get = m_nMaxPut - offset; - break; - } - - if ( m_Get > m_nMaxPut ) - { - m_Error |= GET_OVERFLOW; - } - else - { - m_Error &= ~GET_OVERFLOW; - if ( m_Get < m_nOffset || m_Get >= m_nOffset + Size() ) - { - OnGetOverflow( -1 ); - } - } -} - - -//----------------------------------------------------------------------------- -// Parse... -//----------------------------------------------------------------------------- - -#pragma warning ( disable : 4706 ) - -int CUtlBuffer::VaScanf( const char* pFmt, va_list list ) -{ - Assert( pFmt ); - if ( m_Error || !IsText() ) - return 0; - - int numScanned = 0; - int nLength; - char c; - char* pEnd; - while ( c = *pFmt++ ) - { - // Stop if we hit the end of the buffer - if ( m_Get >= TellMaxPut() ) - { - m_Error |= GET_OVERFLOW; - break; - } - - switch (c) - { - case ' ': - // eat all whitespace - EatWhiteSpace(); - break; - - case '%': - { - // Conversion character... try to convert baby! - char type = *pFmt++; - if (type == 0) - return numScanned; - - switch(type) - { - case 'c': - { - char* ch = va_arg( list, char * ); - if ( CheckPeekGet( 0, sizeof(char) ) ) - { - *ch = *(const char*)PeekGet(); - ++m_Get; - } - else - { - *ch = 0; - return numScanned; - } - } - break; - - case 'i': - case 'd': - { - int* i = va_arg( list, int * ); - - // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters - nLength = 128; - if ( !CheckArbitraryPeekGet( 0, nLength ) ) - { - *i = 0; - return numScanned; - } - - *i = strtol( (char*)PeekGet(), &pEnd, 10 ); - int nBytesRead = (int)( pEnd - (char*)PeekGet() ); - if ( nBytesRead == 0 ) - return numScanned; - m_Get += nBytesRead; - } - break; - - case 'x': - { - int* i = va_arg( list, int * ); - - // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters - nLength = 128; - if ( !CheckArbitraryPeekGet( 0, nLength ) ) - { - *i = 0; - return numScanned; - } - - *i = strtol( (char*)PeekGet(), &pEnd, 16 ); - int nBytesRead = (int)( pEnd - (char*)PeekGet() ); - if ( nBytesRead == 0 ) - return numScanned; - m_Get += nBytesRead; - } - break; - - case 'u': - { - unsigned int* u = va_arg( list, unsigned int *); - - // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters - nLength = 128; - if ( !CheckArbitraryPeekGet( 0, nLength ) ) - { - *u = 0; - return numScanned; - } - - *u = strtoul( (char*)PeekGet(), &pEnd, 10 ); - int nBytesRead = (int)( pEnd - (char*)PeekGet() ); - if ( nBytesRead == 0 ) - return numScanned; - m_Get += nBytesRead; - } - break; - - case 'f': - { - float* f = va_arg( list, float *); - - // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters - nLength = 128; - if ( !CheckArbitraryPeekGet( 0, nLength ) ) - { - *f = 0.0f; - return numScanned; - } - - *f = (float)strtod( (char*)PeekGet(), &pEnd ); - int nBytesRead = (int)( pEnd - (char*)PeekGet() ); - if ( nBytesRead == 0 ) - return numScanned; - m_Get += nBytesRead; - } - break; - - case 's': - { - char* s = va_arg( list, char * ); - GetString( s ); - } - break; - - default: - { - // unimplemented scanf type - Assert(0); - return numScanned; - } - break; - } - - ++numScanned; - } - break; - - default: - { - // Here we have to match the format string character - // against what's in the buffer or we're done. - if ( !CheckPeekGet( 0, sizeof(char) ) ) - return numScanned; - - if ( c != *(const char*)PeekGet() ) - return numScanned; - - ++m_Get; - } - } - } - return numScanned; -} - -#pragma warning ( default : 4706 ) - -int CUtlBuffer::Scanf( const char* pFmt, ... ) -{ - va_list args; - - va_start( args, pFmt ); - int count = VaScanf( pFmt, args ); - va_end( args ); - - return count; -} - - -//----------------------------------------------------------------------------- -// Advance the get index until after the particular string is found -// Do not eat whitespace before starting. Return false if it failed -//----------------------------------------------------------------------------- -bool CUtlBuffer::GetToken( const char *pToken ) -{ - Assert( pToken ); - - // Look for the token - int nLen = Q_strlen( pToken ); - - int nSizeToCheck = Size() - TellGet() - m_nOffset; - - int nGet = TellGet(); - do - { - int nMaxSize = TellMaxPut() - TellGet(); - if ( nMaxSize < nSizeToCheck ) - { - nSizeToCheck = nMaxSize; - } - if ( nLen > nSizeToCheck ) - break; - - if ( !CheckPeekGet( 0, nSizeToCheck ) ) - break; - - const char *pBufStart = (const char*)PeekGet(); - const char *pFoundEnd = Q_strnistr( pBufStart, pToken, nSizeToCheck ); - if ( pFoundEnd ) - { - size_t nOffset = (size_t)pFoundEnd - (size_t)pBufStart; - SeekGet( CUtlBuffer::SEEK_CURRENT, nOffset + nLen ); - return true; - } - - SeekGet( CUtlBuffer::SEEK_CURRENT, nSizeToCheck - nLen - 1 ); - nSizeToCheck = Size() - (nLen-1); - - } while ( true ); - - SeekGet( CUtlBuffer::SEEK_HEAD, nGet ); - return false; -} - - -//----------------------------------------------------------------------------- -// (For text buffers only) -// Parse a token from the buffer: -// Grab all text that lies between a starting delimiter + ending delimiter -// (skipping whitespace that leads + trails both delimiters). -// Note the delimiter checks are case-insensitive. -// If successful, the get index is advanced and the function returns true, -// otherwise the index is not advanced and the function returns false. -//----------------------------------------------------------------------------- -bool CUtlBuffer::ParseToken( const char *pStartingDelim, const char *pEndingDelim, char* pString, int nMaxLen ) -{ - int nCharsToCopy = 0; - int nCurrentGet = 0; - - size_t nEndingDelimLen; - - // Starting delimiter is optional - char emptyBuf = '\0'; - if ( !pStartingDelim ) - { - pStartingDelim = &emptyBuf; - } - - // Ending delimiter is not - Assert( pEndingDelim && pEndingDelim[0] ); - nEndingDelimLen = Q_strlen( pEndingDelim ); - - int nStartGet = TellGet(); - char nCurrChar; - int nTokenStart = -1; - EatWhiteSpace( ); - while ( *pStartingDelim ) - { - nCurrChar = *pStartingDelim++; - if ( !isspace((unsigned char)nCurrChar) ) - { - if ( tolower( GetChar() ) != tolower( nCurrChar ) ) - goto parseFailed; - } - else - { - EatWhiteSpace(); - } - } - - EatWhiteSpace(); - nTokenStart = TellGet(); - if ( !GetToken( pEndingDelim ) ) - goto parseFailed; - - nCurrentGet = TellGet(); - nCharsToCopy = (nCurrentGet - nEndingDelimLen) - nTokenStart; - if ( nCharsToCopy >= nMaxLen ) - { - nCharsToCopy = nMaxLen - 1; - } - - if ( nCharsToCopy > 0 ) - { - SeekGet( CUtlBuffer::SEEK_HEAD, nTokenStart ); - Get( pString, nCharsToCopy ); - if ( !IsValid() ) - goto parseFailed; - - // Eat trailing whitespace - for ( ; nCharsToCopy > 0; --nCharsToCopy ) - { - if ( !isspace( (unsigned char)pString[ nCharsToCopy-1 ] ) ) - break; - } - } - pString[ nCharsToCopy ] = '\0'; - - // Advance the Get index - SeekGet( CUtlBuffer::SEEK_HEAD, nCurrentGet ); - return true; - -parseFailed: - // Revert the get index - SeekGet( SEEK_HEAD, nStartGet ); - pString[0] = '\0'; - return false; -} - - -//----------------------------------------------------------------------------- -// Parses the next token, given a set of character breaks to stop at -//----------------------------------------------------------------------------- -int CUtlBuffer::ParseToken( characterset_t *pBreaks, char *pTokenBuf, int nMaxLen, bool bParseComments ) -{ - Assert( nMaxLen > 0 ); - pTokenBuf[0] = 0; - - // skip whitespace + comments - while ( true ) - { - if ( !IsValid() ) - return -1; - EatWhiteSpace(); - if ( bParseComments ) - { - if ( !EatCPPComment() ) - break; - } - else - { - break; - } - } - - char c = GetChar(); - - // End of buffer - if ( c == 0 ) - return -1; - - // handle quoted strings specially - if ( c == '\"' ) - { - int nLen = 0; - while( IsValid() ) - { - c = GetChar(); - if ( c == '\"' || !c ) - { - pTokenBuf[nLen] = 0; - return nLen; - } - pTokenBuf[nLen] = c; - if ( ++nLen == nMaxLen ) - { - pTokenBuf[nLen-1] = 0; - return nMaxLen; - } - } - - // In this case, we hit the end of the buffer before hitting the end qoute - pTokenBuf[nLen] = 0; - return nLen; - } - - // parse single characters - if ( IN_CHARACTERSET( *pBreaks, c ) ) - { - pTokenBuf[0] = c; - pTokenBuf[1] = 0; - return 1; - } - - // parse a regular word - int nLen = 0; - while ( true ) - { - pTokenBuf[nLen] = c; - if ( ++nLen == nMaxLen ) - { - pTokenBuf[nLen-1] = 0; - return nMaxLen; - } - c = GetChar(); - if ( !IsValid() ) - break; - - if ( IN_CHARACTERSET( *pBreaks, c ) || c == '\"' || c <= ' ' ) - { - SeekGet( SEEK_CURRENT, -1 ); - break; - } - } - - pTokenBuf[nLen] = 0; - return nLen; -} - - - -//----------------------------------------------------------------------------- -// Serialization -//----------------------------------------------------------------------------- -void CUtlBuffer::Put( const void *pMem, int size ) -{ - if ( size && CheckPut( size ) ) - { - memcpy( &m_Memory[m_Put - m_nOffset], pMem, size ); - m_Put += size; - - AddNullTermination(); - } -} - - -//----------------------------------------------------------------------------- -// Writes a null-terminated string -//----------------------------------------------------------------------------- -void CUtlBuffer::PutString( const char* pString ) -{ - if (!IsText()) - { - if ( pString ) - { - // Not text? append a null at the end. - size_t nLen = Q_strlen( pString ) + 1; - Put( pString, nLen * sizeof(char) ); - return; - } - else - { - PutTypeBin( 0 ); - } - } - else if (pString) - { - int nTabCount = ( m_Flags & AUTO_TABS_DISABLED ) ? 0 : m_nTab; - if ( nTabCount > 0 ) - { - if ( WasLastCharacterCR() ) - { - PutTabs(); - } - - const char* pEndl = strchr( pString, '\n' ); - while ( pEndl ) - { - size_t nSize = (size_t)pEndl - (size_t)pString + sizeof(char); - Put( pString, nSize ); - pString = pEndl + 1; - if ( *pString ) - { - PutTabs(); - pEndl = strchr( pString, '\n' ); - } - else - { - pEndl = NULL; - } - } - } - size_t nLen = Q_strlen( pString ); - if ( nLen ) - { - Put( pString, nLen * sizeof(char) ); - } - } -} - - -//----------------------------------------------------------------------------- -// This version of PutString converts \ to \\ and " to \", etc. -// It also places " at the beginning and end of the string -//----------------------------------------------------------------------------- -inline void CUtlBuffer::PutDelimitedCharInternal( CUtlCharConversion *pConv, char c ) -{ - int l = pConv->GetConversionLength( c ); - if ( l == 0 ) - { - PutChar( c ); - } - else - { - PutChar( pConv->GetEscapeChar() ); - Put( pConv->GetConversionString( c ), l ); - } -} - -void CUtlBuffer::PutDelimitedChar( CUtlCharConversion *pConv, char c ) -{ - if ( !IsText() || !pConv ) - { - PutChar( c ); - return; - } - - PutDelimitedCharInternal( pConv, c ); -} - -void CUtlBuffer::PutDelimitedString( CUtlCharConversion *pConv, const char *pString ) -{ - if ( !IsText() || !pConv ) - { - PutString( pString ); - return; - } - - if ( WasLastCharacterCR() ) - { - PutTabs(); - } - Put( pConv->GetDelimiter(), pConv->GetDelimiterLength() ); - - int nLen = pString ? Q_strlen( pString ) : 0; - for ( int i = 0; i < nLen; ++i ) - { - PutDelimitedCharInternal( pConv, pString[i] ); - } - - if ( WasLastCharacterCR() ) - { - PutTabs(); - } - Put( pConv->GetDelimiter(), pConv->GetDelimiterLength() ); -} - - -void CUtlBuffer::VaPrintf( const char* pFmt, va_list list ) -{ - char temp[2048]; -#ifdef _DEBUG - int nLen = -#endif - Q_vsnprintf( temp, sizeof( temp ), pFmt, list ); - Assert( nLen < 2048 ); - PutString( temp ); -} - -void CUtlBuffer::Printf( const char* pFmt, ... ) -{ - va_list args; - - va_start( args, pFmt ); - VaPrintf( pFmt, args ); - va_end( args ); -} - - -//----------------------------------------------------------------------------- -// Calls the overflow functions -//----------------------------------------------------------------------------- -void CUtlBuffer::SetOverflowFuncs( UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc ) -{ - m_GetOverflowFunc = getFunc; - m_PutOverflowFunc = putFunc; -} - - -//----------------------------------------------------------------------------- -// Calls the overflow functions -//----------------------------------------------------------------------------- -bool CUtlBuffer::OnPutOverflow( int nSize ) -{ - return (this->*m_PutOverflowFunc)( nSize ); -} - -bool CUtlBuffer::OnGetOverflow( int nSize ) -{ - return (this->*m_GetOverflowFunc)( nSize ); -} - - -//----------------------------------------------------------------------------- -// Checks if a put is ok -//----------------------------------------------------------------------------- -bool CUtlBuffer::PutOverflow( int nSize ) -{ - if ( m_Memory.IsExternallyAllocated() ) - { - if ( !IsGrowable() ) - return false; - - m_Memory.ConvertToGrowableMemory( 0 ); - } - - while( Size() < m_Put - m_nOffset + nSize ) - { - m_Memory.Grow(); - } - - return true; -} - -bool CUtlBuffer::GetOverflow( int nSize ) -{ - return false; -} - - -//----------------------------------------------------------------------------- -// Checks if a put is ok -//----------------------------------------------------------------------------- -bool CUtlBuffer::CheckPut( int nSize ) -{ - if ( ( m_Error & PUT_OVERFLOW ) || IsReadOnly() ) - return false; - - if ( ( m_Put < m_nOffset ) || ( m_Memory.NumAllocated() < m_Put - m_nOffset + nSize ) ) - { - if ( !OnPutOverflow( nSize ) ) - { - m_Error |= PUT_OVERFLOW; - return false; - } - } - return true; -} - -void CUtlBuffer::SeekPut( SeekType_t type, int offset ) -{ - int nNextPut = m_Put; - switch( type ) - { - case SEEK_HEAD: - nNextPut = offset; - break; - - case SEEK_CURRENT: - nNextPut += offset; - break; - - case SEEK_TAIL: - nNextPut = m_nMaxPut - offset; - break; - } - - // Force a write of the data - // FIXME: We could make this more optimal potentially by writing out - // the entire buffer if you seek outside the current range - - // NOTE: This call will write and will also seek the file to nNextPut. - OnPutOverflow( -nNextPut-1 ); - m_Put = nNextPut; - - AddNullTermination(); -} - - -void CUtlBuffer::ActivateByteSwapping( bool bActivate ) -{ - m_Byteswap.ActivateByteSwapping( bActivate ); -} - -void CUtlBuffer::SetBigEndian( bool bigEndian ) -{ - m_Byteswap.SetTargetBigEndian( bigEndian ); -} - -bool CUtlBuffer::IsBigEndian( void ) -{ - return m_Byteswap.IsTargetBigEndian(); -} - - -//----------------------------------------------------------------------------- -// null terminate the buffer -//----------------------------------------------------------------------------- -void CUtlBuffer::AddNullTermination( void ) -{ - if ( m_Put > m_nMaxPut ) - { - if ( !IsReadOnly() && ((m_Error & PUT_OVERFLOW) == 0) ) - { - // Add null termination value - if ( CheckPut( 1 ) ) - { - m_Memory[m_Put - m_nOffset] = 0; - } - else - { - // Restore the overflow state, it was valid before... - m_Error &= ~PUT_OVERFLOW; - } - } - m_nMaxPut = m_Put; - } -} - - -//----------------------------------------------------------------------------- -// Converts a buffer from a CRLF buffer to a CR buffer (and back) -// Returns false if no conversion was necessary (and outBuf is left untouched) -// If the conversion occurs, outBuf will be cleared. -//----------------------------------------------------------------------------- -bool CUtlBuffer::ConvertCRLF( CUtlBuffer &outBuf ) -{ - if ( !IsText() || !outBuf.IsText() ) - return false; - - if ( ContainsCRLF() == outBuf.ContainsCRLF() ) - return false; - - int nInCount = TellMaxPut(); - - outBuf.Purge(); - outBuf.EnsureCapacity( nInCount ); - - bool bFromCRLF = ContainsCRLF(); - - // Start reading from the beginning - int nGet = TellGet(); - int nPut = TellPut(); - int nGetDelta = 0; - int nPutDelta = 0; - - const char *pBase = (const char*)Base(); - int nCurrGet = 0; - while ( nCurrGet < nInCount ) - { - const char *pCurr = &pBase[nCurrGet]; - if ( bFromCRLF ) - { - const char *pNext = Q_strnistr( pCurr, "\r\n", nInCount - nCurrGet ); - if ( !pNext ) - { - outBuf.Put( pCurr, nInCount - nCurrGet ); - break; - } - - int nBytes = (size_t)pNext - (size_t)pCurr; - outBuf.Put( pCurr, nBytes ); - outBuf.PutChar( '\n' ); - nCurrGet += nBytes + 2; - if ( nGet >= nCurrGet - 1 ) - { - --nGetDelta; - } - if ( nPut >= nCurrGet - 1 ) - { - --nPutDelta; - } - } - else - { - const char *pNext = Q_strnchr( pCurr, '\n', nInCount - nCurrGet ); - if ( !pNext ) - { - outBuf.Put( pCurr, nInCount - nCurrGet ); - break; - } - - int nBytes = (size_t)pNext - (size_t)pCurr; - outBuf.Put( pCurr, nBytes ); - outBuf.PutChar( '\r' ); - outBuf.PutChar( '\n' ); - nCurrGet += nBytes + 1; - if ( nGet >= nCurrGet ) - { - ++nGetDelta; - } - if ( nPut >= nCurrGet ) - { - ++nPutDelta; - } - } - } - - Assert( nPut + nPutDelta <= outBuf.TellMaxPut() ); - - outBuf.SeekGet( SEEK_HEAD, nGet + nGetDelta ); - outBuf.SeekPut( SEEK_HEAD, nPut + nPutDelta ); - - return true; -} - - -//--------------------------------------------------------------------------- -// Implementation of CUtlInplaceBuffer -//--------------------------------------------------------------------------- - -CUtlInplaceBuffer::CUtlInplaceBuffer( int growSize /* = 0 */, int initSize /* = 0 */, int nFlags /* = 0 */ ) : - CUtlBuffer( growSize, initSize, nFlags ) -{ - NULL; -} - -bool CUtlInplaceBuffer::InplaceGetLinePtr( char **ppszInBufferPtr, int *pnLineLength ) -{ - Assert( IsText() && !ContainsCRLF() ); - - int nLineLen = PeekLineLength(); - if ( nLineLen <= 1 ) - { - SeekGet( SEEK_TAIL, 0 ); - return false; - } - - -- nLineLen; // because it accounts for putting a terminating null-character - - char *pszLine = ( char * ) const_cast< void * >( PeekGet() ); - SeekGet( SEEK_CURRENT, nLineLen ); - - // Set the out args - if ( ppszInBufferPtr ) - *ppszInBufferPtr = pszLine; - - if ( pnLineLength ) - *pnLineLength = nLineLen; - - return true; -} - -char * CUtlInplaceBuffer::InplaceGetLinePtr( void ) -{ - char *pszLine = NULL; - int nLineLen = 0; - - if ( InplaceGetLinePtr( &pszLine, &nLineLen ) ) - { - Assert( nLineLen >= 1 ); - - switch ( pszLine[ nLineLen - 1 ] ) - { - case '\n': - case '\r': - pszLine[ nLineLen - 1 ] = 0; - if ( -- nLineLen ) - { - switch ( pszLine[ nLineLen - 1 ] ) - { - case '\n': - case '\r': - pszLine[ nLineLen - 1 ] = 0; - break; - } - } - break; - - default: - Assert( pszLine[ nLineLen ] == 0 ); - break; - } - } - - return pszLine; -} - diff --git a/Resources/NetHook/tier1/utlbuffer.h b/Resources/NetHook/tier1/utlbuffer.h deleted file mode 100644 index 5b423f1a..00000000 --- a/Resources/NetHook/tier1/utlbuffer.h +++ /dev/null @@ -1,1028 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// Serialization/unserialization buffer -//=============================================================================// - -#ifndef UTLBUFFER_H -#define UTLBUFFER_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlmemory.h" -#include "tier1/byteswap.h" -#include - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -struct characterset_t; - - -//----------------------------------------------------------------------------- -// Description of character conversions for string output -// Here's an example of how to use the macros to define a character conversion -// BEGIN_CHAR_CONVERSION( CStringConversion, '\\' ) -// { '\n', "n" }, -// { '\t', "t" } -// END_CHAR_CONVERSION( CStringConversion, '\\' ) -//----------------------------------------------------------------------------- -class CUtlCharConversion -{ -public: - struct ConversionArray_t - { - char m_nActualChar; - char *m_pReplacementString; - }; - - CUtlCharConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray ); - char GetEscapeChar() const; - const char *GetDelimiter() const; - int GetDelimiterLength() const; - - const char *GetConversionString( char c ) const; - int GetConversionLength( char c ) const; - int MaxConversionLength() const; - - // Finds a conversion for the passed-in string, returns length - virtual char FindConversion( const char *pString, int *pLength ); - -protected: - struct ConversionInfo_t - { - int m_nLength; - char *m_pReplacementString; - }; - - char m_nEscapeChar; - const char *m_pDelimiter; - int m_nDelimiterLength; - int m_nCount; - int m_nMaxConversionLength; - char m_pList[255]; - ConversionInfo_t m_pReplacements[255]; -}; - -#define BEGIN_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \ - static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = { - -#define END_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \ - }; \ - CUtlCharConversion _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name ); - -#define BEGIN_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \ - static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = { - -#define END_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \ - }; \ - _className _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name ); - -//----------------------------------------------------------------------------- -// Character conversions for C strings -//----------------------------------------------------------------------------- -CUtlCharConversion *GetCStringCharConversion(); - -//----------------------------------------------------------------------------- -// Character conversions for quoted strings, with no escape sequences -//----------------------------------------------------------------------------- -CUtlCharConversion *GetNoEscCharConversion(); - - -//----------------------------------------------------------------------------- -// Macro to set overflow functions easily -//----------------------------------------------------------------------------- -#define SetUtlBufferOverflowFuncs( _get, _put ) \ - SetOverflowFuncs( static_cast ( _get ), static_cast ( _put ) ) - - -//----------------------------------------------------------------------------- -// Command parsing.. -//----------------------------------------------------------------------------- -class CUtlBuffer -{ -public: - enum SeekType_t - { - SEEK_HEAD = 0, - SEEK_CURRENT, - SEEK_TAIL - }; - - // flags - enum BufferFlags_t - { - TEXT_BUFFER = 0x1, // Describes how get + put work (as strings, or binary) - EXTERNAL_GROWABLE = 0x2, // This is used w/ external buffers and causes the utlbuf to switch to reallocatable memory if an overflow happens when Putting. - CONTAINS_CRLF = 0x4, // For text buffers only, does this contain \n or \n\r? - READ_ONLY = 0x8, // For external buffers; prevents null termination from happening. - AUTO_TABS_DISABLED = 0x10, // Used to disable/enable push/pop tabs - }; - - // Overflow functions when a get or put overflows - typedef bool (CUtlBuffer::*UtlBufferOverflowFunc_t)( int nSize ); - - // Constructors for growable + external buffers for serialization/unserialization - CUtlBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 ); - CUtlBuffer( const void* pBuffer, int size, int nFlags = 0 ); - // This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param. - CUtlBuffer( const void *pBuffer, int size, bool crap ); - - unsigned char GetFlags() const; - - // NOTE: This will assert if you attempt to recast it in a way that - // is not compatible. The only valid conversion is binary-> text w/CRLF - void SetBufferType( bool bIsText, bool bContainsCRLF ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Attaches the buffer to external memory.... - void SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags = 0 ); - bool IsExternallyAllocated() const; - void AssumeMemory( void *pMemory, int nSize, int nInitialPut, int nFlags = 0 ); - - FORCEINLINE void ActivateByteSwappingIfBigEndian( void ) - { - if ( IsX360() ) - ActivateByteSwapping( true ); - } - - - // Controls endian-ness of binary utlbufs - default matches the current platform - void ActivateByteSwapping( bool bActivate ); - void SetBigEndian( bool bigEndian ); - bool IsBigEndian( void ); - - // Resets the buffer; but doesn't free memory - void Clear(); - - // Clears out the buffer; frees memory - void Purge(); - - // Read stuff out. - // Binary mode: it'll just read the bits directly in, and characters will be - // read for strings until a null character is reached. - // Text mode: it'll parse the file, turning text #s into real numbers. - // GetString will read a string until a space is reached - char GetChar( ); - unsigned char GetUnsignedChar( ); - short GetShort( ); - unsigned short GetUnsignedShort( ); - int GetInt( ); - int GetIntHex( ); - unsigned int GetUnsignedInt( ); - float GetFloat( ); - double GetDouble( ); - void GetString( char* pString, int nMaxChars = 0 ); - void Get( void* pMem, int size ); - void GetLine( char* pLine, int nMaxChars = 0 ); - - // Used for getting objects that have a byteswap datadesc defined - template void GetObjects( T *dest, int count = 1 ); - - // This will get at least 1 byte and up to nSize bytes. - // It will return the number of bytes actually read. - int GetUpTo( void *pMem, int nSize ); - - // This version of GetString converts \" to \\ and " to \, etc. - // It also reads a " at the beginning and end of the string - void GetDelimitedString( CUtlCharConversion *pConv, char *pString, int nMaxChars = 0 ); - char GetDelimitedChar( CUtlCharConversion *pConv ); - - // This will return the # of characters of the string about to be read out - // NOTE: The count will *include* the terminating 0!! - // In binary mode, it's the number of characters until the next 0 - // In text mode, it's the number of characters until the next space. - int PeekStringLength(); - - // This version of PeekStringLength converts \" to \\ and " to \, etc. - // It also reads a " at the beginning and end of the string - // NOTE: The count will *include* the terminating 0!! - // In binary mode, it's the number of characters until the next 0 - // In text mode, it's the number of characters between "s (checking for \") - // Specifying false for bActualSize will return the pre-translated number of characters - // including the delimiters and the escape characters. So, \n counts as 2 characters when bActualSize == false - // and only 1 character when bActualSize == true - int PeekDelimitedStringLength( CUtlCharConversion *pConv, bool bActualSize = true ); - - // Just like scanf, but doesn't work in binary mode - int Scanf( const char* pFmt, ... ); - int VaScanf( const char* pFmt, va_list list ); - - // Eats white space, advances Get index - void EatWhiteSpace(); - - // Eats C++ style comments - bool EatCPPComment(); - - // (For text buffers only) - // Parse a token from the buffer: - // Grab all text that lies between a starting delimiter + ending delimiter - // (skipping whitespace that leads + trails both delimiters). - // If successful, the get index is advanced and the function returns true, - // otherwise the index is not advanced and the function returns false. - bool ParseToken( const char *pStartingDelim, const char *pEndingDelim, char* pString, int nMaxLen ); - - // Advance the get index until after the particular string is found - // Do not eat whitespace before starting. Return false if it failed - // String test is case-insensitive. - bool GetToken( const char *pToken ); - - // Parses the next token, given a set of character breaks to stop at - // Returns the length of the token parsed in bytes (-1 if none parsed) - int ParseToken( characterset_t *pBreaks, char *pTokenBuf, int nMaxLen, bool bParseComments = true ); - - // Write stuff in - // Binary mode: it'll just write the bits directly in, and strings will be - // written with a null terminating character - // Text mode: it'll convert the numbers to text versions - // PutString will not write a terminating character - void PutChar( char c ); - void PutUnsignedChar( unsigned char uc ); - void PutShort( short s ); - void PutUnsignedShort( unsigned short us ); - void PutInt( int i ); - void PutUnsignedInt( unsigned int u ); - void PutFloat( float f ); - void PutDouble( double d ); - void PutString( const char* pString ); - void Put( const void* pMem, int size ); - - // Used for putting objects that have a byteswap datadesc defined - template void PutObjects( T *src, int count = 1 ); - - // This version of PutString converts \ to \\ and " to \", etc. - // It also places " at the beginning and end of the string - void PutDelimitedString( CUtlCharConversion *pConv, const char *pString ); - void PutDelimitedChar( CUtlCharConversion *pConv, char c ); - - // Just like printf, writes a terminating zero in binary mode - void Printf( const char* pFmt, ... ); - void VaPrintf( const char* pFmt, va_list list ); - - // What am I writing (put)/reading (get)? - void* PeekPut( int offset = 0 ); - const void* PeekGet( int offset = 0 ) const; - const void* PeekGet( int nMaxSize, int nOffset ); - - // Where am I writing (put)/reading (get)? - int TellPut( ) const; - int TellGet( ) const; - - // What's the most I've ever written? - int TellMaxPut( ) const; - - // How many bytes remain to be read? - // NOTE: This is not accurate for streaming text files; it overshoots - int GetBytesRemaining() const; - - // Change where I'm writing (put)/reading (get) - void SeekPut( SeekType_t type, int offset ); - void SeekGet( SeekType_t type, int offset ); - - // Buffer base - const void* Base() const; - void* Base(); - - // memory allocation size, does *not* reflect size written or read, - // use TellPut or TellGet for that - int Size() const; - - // Am I a text buffer? - bool IsText() const; - - // Can I grow if I'm externally allocated? - bool IsGrowable() const; - - // Am I valid? (overflow or underflow error), Once invalid it stays invalid - bool IsValid() const; - - // Do I contain carriage return/linefeeds? - bool ContainsCRLF() const; - - // Am I read-only - bool IsReadOnly() const; - - // Converts a buffer from a CRLF buffer to a CR buffer (and back) - // Returns false if no conversion was necessary (and outBuf is left untouched) - // If the conversion occurs, outBuf will be cleared. - bool ConvertCRLF( CUtlBuffer &outBuf ); - - // Push/pop pretty-printing tabs - void PushTab(); - void PopTab(); - - // Temporarily disables pretty print - void EnableTabs( bool bEnable ); - -protected: - // error flags - enum - { - PUT_OVERFLOW = 0x1, - GET_OVERFLOW = 0x2, - MAX_ERROR_FLAG = GET_OVERFLOW, - }; - - void SetOverflowFuncs( UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc ); - - bool OnPutOverflow( int nSize ); - bool OnGetOverflow( int nSize ); - -protected: - // Checks if a get/put is ok - bool CheckPut( int size ); - bool CheckGet( int size ); - - void AddNullTermination( ); - - // Methods to help with pretty-printing - bool WasLastCharacterCR(); - void PutTabs(); - - // Help with delimited stuff - char GetDelimitedCharInternal( CUtlCharConversion *pConv ); - void PutDelimitedCharInternal( CUtlCharConversion *pConv, char c ); - - // Default overflow funcs - bool PutOverflow( int nSize ); - bool GetOverflow( int nSize ); - - // Does the next bytes of the buffer match a pattern? - bool PeekStringMatch( int nOffset, const char *pString, int nLen ); - - // Peek size of line to come, check memory bound - int PeekLineLength(); - - // How much whitespace should I skip? - int PeekWhiteSpace( int nOffset ); - - // Checks if a peek get is ok - bool CheckPeekGet( int nOffset, int nSize ); - - // Call this to peek arbitrarily long into memory. It doesn't fail unless - // it can't read *anything* new - bool CheckArbitraryPeekGet( int nOffset, int &nIncrement ); - - template void GetType( T& dest, const char *pszFmt ); - template void GetTypeBin( T& dest ); - template void GetObject( T *src ); - - template void PutType( T src, const char *pszFmt ); - template void PutTypeBin( T src ); - template void PutObject( T *src ); - - CUtlMemory m_Memory; - int m_Get; - int m_Put; - - unsigned char m_Error; - unsigned char m_Flags; - unsigned char m_Reserved; -#if defined( _X360 ) - unsigned char pad; -#endif - - int m_nTab; - int m_nMaxPut; - int m_nOffset; - - UtlBufferOverflowFunc_t m_GetOverflowFunc; - UtlBufferOverflowFunc_t m_PutOverflowFunc; - - CByteswap m_Byteswap; -}; - - -// Stream style output operators for CUtlBuffer -inline CUtlBuffer &operator<<( CUtlBuffer &b, char v ) -{ - b.PutChar( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned char v ) -{ - b.PutUnsignedChar( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, short v ) -{ - b.PutShort( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned short v ) -{ - b.PutUnsignedShort( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, int v ) -{ - b.PutInt( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned int v ) -{ - b.PutUnsignedInt( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, float v ) -{ - b.PutFloat( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, double v ) -{ - b.PutDouble( v ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, const char *pv ) -{ - b.PutString( pv ); - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, const Vector &v ) -{ - b << v.x << " " << v.y << " " << v.z; - return b; -} - -inline CUtlBuffer &operator<<( CUtlBuffer &b, const Vector2D &v ) -{ - b << v.x << " " << v.y; - return b; -} - - -class CUtlInplaceBuffer : public CUtlBuffer -{ -public: - CUtlInplaceBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 ); - - // - // Routines returning buffer-inplace-pointers - // -public: - // - // Upon success, determines the line length, fills out the pointer to the - // beginning of the line and the line length, advances the "get" pointer - // offset by the line length and returns "true". - // - // If end of file is reached or upon error returns "false". - // - // Note: the returned length of the line is at least one character because the - // trailing newline characters are also included as part of the line. - // - // Note: the pointer returned points into the local memory of this buffer, in - // case the buffer gets relocated or destroyed the pointer becomes invalid. - // - // e.g.: ------------- - // - // char *pszLine; - // int nLineLen; - // while ( pUtlInplaceBuffer->InplaceGetLinePtr( &pszLine, &nLineLen ) ) - // { - // ... - // } - // - // ------------- - // - // @param ppszInBufferPtr on return points into this buffer at start of line - // @param pnLineLength on return holds num bytes accessible via (*ppszInBufferPtr) - // - // @returns true if line was successfully read - // false when EOF is reached or error occurs - // - bool InplaceGetLinePtr( /* out */ char **ppszInBufferPtr, /* out */ int *pnLineLength ); - - // - // Determines the line length, advances the "get" pointer offset by the line length, - // replaces the newline character with null-terminator and returns the initial pointer - // to now null-terminated line. - // - // If end of file is reached or upon error returns NULL. - // - // Note: the pointer returned points into the local memory of this buffer, in - // case the buffer gets relocated or destroyed the pointer becomes invalid. - // - // e.g.: ------------- - // - // while ( char *pszLine = pUtlInplaceBuffer->InplaceGetLinePtr() ) - // { - // ... - // } - // - // ------------- - // - // @returns ptr-to-zero-terminated-line if line was successfully read and buffer modified - // NULL when EOF is reached or error occurs - // - char * InplaceGetLinePtr( void ); -}; - - -//----------------------------------------------------------------------------- -// Where am I reading? -//----------------------------------------------------------------------------- -inline int CUtlBuffer::TellGet( ) const -{ - return m_Get; -} - - -//----------------------------------------------------------------------------- -// How many bytes remain to be read? -//----------------------------------------------------------------------------- -inline int CUtlBuffer::GetBytesRemaining() const -{ - return m_nMaxPut - TellGet(); -} - - -//----------------------------------------------------------------------------- -// What am I reading? -//----------------------------------------------------------------------------- -inline const void* CUtlBuffer::PeekGet( int offset ) const -{ - return &m_Memory[ m_Get + offset - m_nOffset ]; -} - - -//----------------------------------------------------------------------------- -// Unserialization -//----------------------------------------------------------------------------- - -template -inline void CUtlBuffer::GetObject( T *dest ) -{ - if ( CheckGet( sizeof(T) ) ) - { - if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) - { - *dest = *(T *)PeekGet(); - } - else - { - m_Byteswap.SwapFieldsToTargetEndian( dest, (T*)PeekGet() ); - } - m_Get += sizeof(T); - } - else - { - Q_memset( &dest, 0, sizeof(T) ); - } -} - - -template -inline void CUtlBuffer::GetObjects( T *dest, int count ) -{ - for ( int i = 0; i < count; ++i, ++dest ) - { - GetObject( dest ); - } -} - - -template -inline void CUtlBuffer::GetTypeBin( T &dest ) -{ - if ( CheckGet( sizeof(T) ) ) - { - if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) - { - dest = *(T *)PeekGet(); - } - else - { - m_Byteswap.SwapBufferToTargetEndian( &dest, (T*)PeekGet() ); - } - m_Get += sizeof(T); - } - else - { - dest = 0; - } -} - -template <> -inline void CUtlBuffer::GetTypeBin< float >( float &dest ) -{ - if ( CheckGet( sizeof( float ) ) ) - { - unsigned int pData = (unsigned int)PeekGet(); - if ( IsX360() && ( pData & 0x03 ) ) - { - // handle unaligned read - ((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0]; - ((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1]; - ((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2]; - ((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3]; - } - else - { - // aligned read - dest = *(float *)pData; - } - if ( m_Byteswap.IsSwappingBytes() ) - { - m_Byteswap.SwapBufferToTargetEndian< float >( &dest, &dest ); - } - m_Get += sizeof( float ); - } - else - { - dest = 0; - } -} - -template -inline void CUtlBuffer::GetType( T &dest, const char *pszFmt ) -{ - if (!IsText()) - { - GetTypeBin( dest ); - } - else - { - dest = 0; - Scanf( pszFmt, &dest ); - } -} - -inline char CUtlBuffer::GetChar( ) -{ - char c; - GetType( c, "%c" ); - return c; -} - -inline unsigned char CUtlBuffer::GetUnsignedChar( ) -{ - unsigned char c; - GetType( c, "%u" ); - return c; -} - -inline short CUtlBuffer::GetShort( ) -{ - short s; - GetType( s, "%d" ); - return s; -} - -inline unsigned short CUtlBuffer::GetUnsignedShort( ) -{ - unsigned short s; - GetType( s, "%u" ); - return s; -} - -inline int CUtlBuffer::GetInt( ) -{ - int i; - GetType( i, "%d" ); - return i; -} - -inline int CUtlBuffer::GetIntHex( ) -{ - int i; - GetType( i, "%x" ); - return i; -} - -inline unsigned int CUtlBuffer::GetUnsignedInt( ) -{ - unsigned int u; - GetType( u, "%u" ); - return u; -} - -inline float CUtlBuffer::GetFloat( ) -{ - float f; - GetType( f, "%f" ); - return f; -} - -inline double CUtlBuffer::GetDouble( ) -{ - double d; - GetType( d, "%f" ); - return d; -} - - -//----------------------------------------------------------------------------- -// Where am I writing? -//----------------------------------------------------------------------------- -inline unsigned char CUtlBuffer::GetFlags() const -{ - return m_Flags; -} - - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::IsExternallyAllocated() const -{ - return m_Memory.IsExternallyAllocated(); -} - - -//----------------------------------------------------------------------------- -// Where am I writing? -//----------------------------------------------------------------------------- -inline int CUtlBuffer::TellPut( ) const -{ - return m_Put; -} - - -//----------------------------------------------------------------------------- -// What's the most I've ever written? -//----------------------------------------------------------------------------- -inline int CUtlBuffer::TellMaxPut( ) const -{ - return m_nMaxPut; -} - - -//----------------------------------------------------------------------------- -// What am I reading? -//----------------------------------------------------------------------------- -inline void* CUtlBuffer::PeekPut( int offset ) -{ - return &m_Memory[m_Put + offset - m_nOffset]; -} - - -//----------------------------------------------------------------------------- -// Various put methods -//----------------------------------------------------------------------------- - -template -inline void CUtlBuffer::PutObject( T *src ) -{ - if ( CheckPut( sizeof(T) ) ) - { - if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) - { - *(T *)PeekPut() = *src; - } - else - { - m_Byteswap.SwapFieldsToTargetEndian( (T*)PeekPut(), src ); - } - m_Put += sizeof(T); - AddNullTermination(); - } -} - - -template -inline void CUtlBuffer::PutObjects( T *src, int count ) -{ - for ( int i = 0; i < count; ++i, ++src ) - { - PutObject( src ); - } -} - - -template -inline void CUtlBuffer::PutTypeBin( T src ) -{ - if ( CheckPut( sizeof(T) ) ) - { - if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) ) - { - *(T *)PeekPut() = src; - } - else - { - m_Byteswap.SwapBufferToTargetEndian( (T*)PeekPut(), &src ); - } - m_Put += sizeof(T); - AddNullTermination(); - } -} - -template -inline void CUtlBuffer::PutType( T src, const char *pszFmt ) -{ - if (!IsText()) - { - PutTypeBin( src ); - } - else - { - Printf( pszFmt, src ); - } -} - -//----------------------------------------------------------------------------- -// Methods to help with pretty-printing -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::WasLastCharacterCR() -{ - if ( !IsText() || (TellPut() == 0) ) - return false; - return ( *( const char * )PeekPut( -1 ) == '\n' ); -} - -inline void CUtlBuffer::PutTabs() -{ - int nTabCount = ( m_Flags & AUTO_TABS_DISABLED ) ? 0 : m_nTab; - for (int i = nTabCount; --i >= 0; ) - { - PutTypeBin( '\t' ); - } -} - - -//----------------------------------------------------------------------------- -// Push/pop pretty-printing tabs -//----------------------------------------------------------------------------- -inline void CUtlBuffer::PushTab( ) -{ - ++m_nTab; -} - -inline void CUtlBuffer::PopTab() -{ - if ( --m_nTab < 0 ) - { - m_nTab = 0; - } -} - - -//----------------------------------------------------------------------------- -// Temporarily disables pretty print -//----------------------------------------------------------------------------- -inline void CUtlBuffer::EnableTabs( bool bEnable ) -{ - if ( bEnable ) - { - m_Flags &= ~AUTO_TABS_DISABLED; - } - else - { - m_Flags |= AUTO_TABS_DISABLED; - } -} - -inline void CUtlBuffer::PutChar( char c ) -{ - if ( WasLastCharacterCR() ) - { - PutTabs(); - } - - PutTypeBin( c ); -} - -inline void CUtlBuffer::PutUnsignedChar( unsigned char c ) -{ - PutType( c, "%u" ); -} - -inline void CUtlBuffer::PutShort( short s ) -{ - PutType( s, "%d" ); -} - -inline void CUtlBuffer::PutUnsignedShort( unsigned short s ) -{ - PutType( s, "%u" ); -} - -inline void CUtlBuffer::PutInt( int i ) -{ - PutType( i, "%d" ); -} - -inline void CUtlBuffer::PutUnsignedInt( unsigned int u ) -{ - PutType( u, "%u" ); -} - -inline void CUtlBuffer::PutFloat( float f ) -{ - PutType( f, "%f" ); -} - -inline void CUtlBuffer::PutDouble( double d ) -{ - PutType( d, "%f" ); -} - - -//----------------------------------------------------------------------------- -// Am I a text buffer? -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::IsText() const -{ - return (m_Flags & TEXT_BUFFER) != 0; -} - - -//----------------------------------------------------------------------------- -// Can I grow if I'm externally allocated? -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::IsGrowable() const -{ - return (m_Flags & EXTERNAL_GROWABLE) != 0; -} - - -//----------------------------------------------------------------------------- -// Am I valid? (overflow or underflow error), Once invalid it stays invalid -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::IsValid() const -{ - return m_Error == 0; -} - - -//----------------------------------------------------------------------------- -// Do I contain carriage return/linefeeds? -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::ContainsCRLF() const -{ - return IsText() && ((m_Flags & CONTAINS_CRLF) != 0); -} - - -//----------------------------------------------------------------------------- -// Am I read-only -//----------------------------------------------------------------------------- -inline bool CUtlBuffer::IsReadOnly() const -{ - return (m_Flags & READ_ONLY) != 0; -} - - -//----------------------------------------------------------------------------- -// Buffer base and size -//----------------------------------------------------------------------------- -inline const void* CUtlBuffer::Base() const -{ - return m_Memory.Base(); -} - -inline void* CUtlBuffer::Base() -{ - return m_Memory.Base(); -} - -inline int CUtlBuffer::Size() const -{ - return m_Memory.NumAllocated(); -} - - -//----------------------------------------------------------------------------- -// Clears out the buffer; frees memory -//----------------------------------------------------------------------------- -inline void CUtlBuffer::Clear() -{ - m_Get = 0; - m_Put = 0; - m_Error = 0; - m_nOffset = 0; - m_nMaxPut = -1; - AddNullTermination(); -} - -inline void CUtlBuffer::Purge() -{ - m_Get = 0; - m_Put = 0; - m_nOffset = 0; - m_nMaxPut = 0; - m_Error = 0; - m_Memory.Purge(); -} - - -#endif // UTLBUFFER_H - diff --git a/Resources/NetHook/tier1/utlbufferutil.cpp b/Resources/NetHook/tier1/utlbufferutil.cpp deleted file mode 100644 index b89ab554..00000000 --- a/Resources/NetHook/tier1/utlbufferutil.cpp +++ /dev/null @@ -1,559 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// $Header: $ -// $NoKeywords: $ -// -// Serialization buffer -//===========================================================================// - -#pragma warning (disable : 4514) - -#include "tier1/utlbufferutil.h" -#include "tier1/utlbuffer.h" -#include "mathlib/vector.h" -#include "mathlib/vector2d.h" -#include "mathlib/vector4d.h" -#include "mathlib/vmatrix.h" -#include "Color.h" -#include -#include -#include -#include -#include -#include "tier1/utlstring.h" -#include "tier1/strtools.h" -#include "tier1/characterset.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -//----------------------------------------------------------------------------- -// For serialization, set the delimiter rules -//----------------------------------------------------------------------------- -CUtlCharConversion *s_pConv = NULL; -const char *s_pUtlBufferUtilArrayDelim = NULL; -void SetSerializationDelimiter( CUtlCharConversion *pConv ) -{ - s_pConv = pConv; -} - -void SetSerializationArrayDelimiter( const char *pDelimiter ) -{ - s_pUtlBufferUtilArrayDelim = pDelimiter; -} - - -//----------------------------------------------------------------------------- -// Serialize a floating point number in text mode in a readably friendly fashion -//----------------------------------------------------------------------------- -static void SerializeFloat( CUtlBuffer &buf, float f ) -{ - Assert( buf.IsText() ); - - // FIXME: Print this in a way that we never lose precision - char pTemp[256]; - int nLen = Q_snprintf( pTemp, sizeof(pTemp), "%.10f", f ); - while ( nLen > 0 && pTemp[nLen-1] == '0' ) - { - --nLen; - pTemp[nLen] = 0; - } - if ( nLen > 0 && pTemp[nLen-1] == '.' ) - { - --nLen; - pTemp[nLen] = 0; - } - buf.PutString( pTemp ); -} - -static void SerializeFloats( CUtlBuffer &buf, int nCount, const float *pFloats ) -{ - for ( int i = 0; i < nCount; ++i ) - { - SerializeFloat( buf, pFloats[i] ); - if ( i != nCount-1 ) - { - buf.PutChar( ' ' ); - } - } -} - - -//----------------------------------------------------------------------------- -// Serialization methods for basic types -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const bool &src ) -{ - if ( buf.IsText() ) - { - buf.Printf( "%d", src ); - } - else - { - buf.PutChar( src ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, bool &dest ) -{ - if ( buf.IsText() ) - { - int nValue = 0; - int nRetVal = buf.Scanf( "%d", &nValue ); - dest = ( nValue != 0 ); - return (nRetVal == 1) && buf.IsValid(); - } - - dest = ( buf.GetChar( ) != 0 ); - return buf.IsValid(); -} - - -bool Serialize( CUtlBuffer &buf, const int &src ) -{ - if ( buf.IsText() ) - { - buf.Printf( "%d", src ); - } - else - { - buf.PutInt( src ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, int &dest ) -{ - if ( buf.IsText() ) - { - int nRetVal = buf.Scanf( "%d", &dest ); - return (nRetVal == 1) && buf.IsValid(); - } - - dest = buf.GetInt( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const float &src ) -{ - if ( buf.IsText() ) - { - SerializeFloat( buf, src ); - } - else - { - buf.PutFloat( src ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, float &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f", &dest ); - return (nRetVal == 1) && buf.IsValid(); - } - - dest = buf.GetFloat( ); - return buf.IsValid(); -} - - -//----------------------------------------------------------------------------- -// Attribute types related to vector math -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const Vector2D &src ) -{ - if ( buf.IsText() ) - { - SerializeFloats( buf, 2, src.Base() ); - } - else - { - buf.PutFloat( src.x ); - buf.PutFloat( src.y ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, Vector2D &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f %f", &dest.x, &dest.y ); - return (nRetVal == 2) && buf.IsValid(); - } - - dest.x = buf.GetFloat( ); - dest.y = buf.GetFloat( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const Vector &src ) -{ - if ( buf.IsText() ) - { - SerializeFloats( buf, 3, src.Base() ); - } - else - { - buf.PutFloat( src.x ); - buf.PutFloat( src.y ); - buf.PutFloat( src.z ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, Vector &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f %f %f", &dest.x, &dest.y, &dest.z ); - return (nRetVal == 3) && buf.IsValid(); - } - - dest.x = buf.GetFloat( ); - dest.y = buf.GetFloat( ); - dest.z = buf.GetFloat( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const Vector4D &src ) -{ - if ( buf.IsText() ) - { - SerializeFloats( buf, 4, src.Base() ); - } - else - { - buf.PutFloat( src.x ); - buf.PutFloat( src.y ); - buf.PutFloat( src.z ); - buf.PutFloat( src.w ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, Vector4D &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f %f %f %f", &dest.x, &dest.y, &dest.z, &dest.w ); - return (nRetVal == 4) && buf.IsValid(); - } - - dest.x = buf.GetFloat( ); - dest.y = buf.GetFloat( ); - dest.z = buf.GetFloat( ); - dest.w = buf.GetFloat( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const QAngle &src ) -{ - if ( buf.IsText() ) - { - SerializeFloats( buf, 3, src.Base() ); - } - else - { - buf.PutFloat( src.x ); - buf.PutFloat( src.y ); - buf.PutFloat( src.z ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, QAngle &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f %f %f", &dest.x, &dest.y, &dest.z ); - return (nRetVal == 3) && buf.IsValid(); - } - - dest.x = buf.GetFloat( ); - dest.y = buf.GetFloat( ); - dest.z = buf.GetFloat( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const Quaternion &src ) -{ - if ( buf.IsText() ) - { - SerializeFloats( buf, 4, &src.x ); - } - else - { - buf.PutFloat( src.x ); - buf.PutFloat( src.y ); - buf.PutFloat( src.z ); - buf.PutFloat( src.w ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, Quaternion &dest ) -{ - if ( buf.IsText() ) - { - // FIXME: Print this in a way that we never lose precision - int nRetVal = buf.Scanf( "%f %f %f %f", &dest.x, &dest.y, &dest.z, &dest.w ); - return (nRetVal == 4) && buf.IsValid(); - } - - dest.x = buf.GetFloat( ); - dest.y = buf.GetFloat( ); - dest.z = buf.GetFloat( ); - dest.w = buf.GetFloat( ); - return buf.IsValid(); -} - -bool Serialize( CUtlBuffer &buf, const VMatrix &src ) -{ - if ( buf.IsText() ) - { - buf.Printf( "\n" ); - SerializeFloats( buf, 4, src[0] ); - buf.Printf( "\n" ); - SerializeFloats( buf, 4, src[1] ); - buf.Printf( "\n" ); - SerializeFloats( buf, 4, src[2] ); - buf.Printf( "\n" ); - SerializeFloats( buf, 4, src[3] ); - buf.Printf( "\n" ); - } - else - { - buf.Put( &src, sizeof(VMatrix) ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, VMatrix &dest ) -{ - if ( !buf.IsValid() ) - return false; - - if ( buf.IsText() ) - { - int nRetVal = buf.Scanf( "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", - &dest[ 0 ][ 0 ], &dest[ 0 ][ 1 ], &dest[ 0 ][ 2 ], &dest[ 0 ][ 3 ], - &dest[ 1 ][ 0 ], &dest[ 1 ][ 1 ], &dest[ 1 ][ 2 ], &dest[ 1 ][ 3 ], - &dest[ 2 ][ 0 ], &dest[ 2 ][ 1 ], &dest[ 2 ][ 2 ], &dest[ 2 ][ 3 ], - &dest[ 3 ][ 0 ], &dest[ 3 ][ 1 ], &dest[ 3 ][ 2 ], &dest[ 3 ][ 3 ] ); - return (nRetVal == 16); - } - - buf.Get( &dest, sizeof(VMatrix) ); - return true; -} - - -//----------------------------------------------------------------------------- -// Color attribute -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const Color &src ) -{ - if ( buf.IsText() ) - { - buf.Printf( "%d %d %d %d", src[0], src[1], src[2], src[3] ); - } - else - { - buf.PutUnsignedChar( src[0] ); - buf.PutUnsignedChar( src[1] ); - buf.PutUnsignedChar( src[2] ); - buf.PutUnsignedChar( src[3] ); - } - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, Color &dest ) -{ - if ( buf.IsText() ) - { - int r = 0, g = 0, b = 0, a = 255; - int nRetVal = buf.Scanf( "%d %d %d %d", &r, &g, &b, &a ); - dest.SetColor( r, g, b, a ); - return (nRetVal == 4) && buf.IsValid(); - } - - dest[0] = buf.GetUnsignedChar( ); - dest[1] = buf.GetUnsignedChar( ); - dest[2] = buf.GetUnsignedChar( ); - dest[3] = buf.GetUnsignedChar( ); - return buf.IsValid(); -} - -/* -//----------------------------------------------------------------------------- -// Object ID attribute -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const DmObjectId_t &src ) -{ - return g_pDataModel->Serialize( buf, src ); -} - -bool Unserialize( CUtlBuffer &buf, DmObjectId_t &dest ) -{ - return g_pDataModel->Unserialize( buf, &dest ); -} -*/ - -//----------------------------------------------------------------------------- -// Binary buffer attribute -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const CUtlBinaryBlock &src ) -{ - int nLength = src.Length(); - if ( !buf.IsText() ) - { - buf.PutInt( nLength ); - if ( nLength != 0 ) - { - buf.Put( src.Get(), nLength ); - } - return buf.IsValid(); - } - - // Writes out uuencoded binaries - for ( int i = 0; i < nLength; ++i ) - { - if ( (i % 40) == 0 ) - { - buf.PutChar( '\n' ); - } - - char b1 = src[i] & 0xF; - char b2 = src[i] >> 4; - - char c1 = ( b1 <= 9 ) ? b1 + '0' : b1 - 10 + 'A'; - char c2 = ( b2 <= 9 ) ? b2 + '0' : b2 - 10 + 'A'; - - buf.PutChar( c2 ); - buf.PutChar( c1 ); - } - - buf.PutChar( '\n' ); - return buf.IsValid(); -} - -static int CountBinaryBytes( CUtlBuffer &buf, int *pEndGet ) -{ - // This counts the number of bytes in the uuencoded text - int nStartGet = buf.TellGet(); - buf.EatWhiteSpace(); - *pEndGet = buf.TellGet(); - int nByteCount = 0; - while ( buf.IsValid() ) - { - char c1 = buf.GetChar(); - char c2 = buf.GetChar(); - - bool bIsNum1 = ( c1 >= '0' ) && ( c1 <= '9' ); - bool bIsNum2 = ( c2 >= '0' ) && ( c2 <= '9' ); - - bool bIsAlpha1 = (( c1 >= 'A' ) && ( c1 <= 'F' )) || (( c1 >= 'a' ) && ( c1 <= 'f' )); - bool bIsAlpha2 = (( c2 >= 'A' ) && ( c2 <= 'F' )) || (( c2 >= 'a' ) && ( c2 <= 'f' )); - - if ( !(bIsNum1 || bIsAlpha1) || !(bIsNum2 || bIsAlpha2) ) - break; - - buf.EatWhiteSpace(); - *pEndGet = buf.TellGet(); - ++nByteCount; - } - buf.SeekGet( CUtlBuffer::SEEK_HEAD, nStartGet ); - return nByteCount; -} - -inline static unsigned char HexCharToInt( int c1 ) -{ - if (( c1 >= '0' ) && ( c1 <= '9' )) - return c1 - '0'; - - if (( c1 >= 'A' ) && ( c1 <= 'F' )) - return 10 + c1 - 'A'; - - if (( c1 >= 'a' ) && ( c1 <= 'f' )) - return 10 + c1 - 'a'; - - return 0xFF; -} - -bool Unserialize( CUtlBuffer &buf, CUtlBinaryBlock &dest ) -{ - if ( !buf.IsText() ) - { - int nLen = buf.GetInt( ); - dest.SetLength( nLen ); - if ( dest.Length() != 0 ) - { - buf.Get( dest.Get(), dest.Length() ); - } - - if ( nLen != dest.Length() ) - { - buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nLen - dest.Length() ); - return false; - } - - return buf.IsValid(); - } - - int nEndGet; - int nByteCount = CountBinaryBytes( buf, &nEndGet ); - if ( nByteCount < 0 ) - return false; - - buf.EatWhiteSpace(); - int nDest = 0; - dest.SetLength( nByteCount ); - while( buf.TellGet() < nEndGet ) - { - char c1 = buf.GetChar(); - char c2 = buf.GetChar(); - - unsigned char b1 = HexCharToInt( c1 ); - unsigned char b2 = HexCharToInt( c2 ); - if ( b1 == 0xFF || b2 == 0xFF ) - return false; - - dest[ nDest++ ] = b2 | ( b1 << 4 ); - buf.EatWhiteSpace(); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// String attribute -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const CUtlString &src ) -{ - buf.PutDelimitedString( s_pConv, src.Get() ); - return buf.IsValid(); -} - -bool Unserialize( CUtlBuffer &buf, CUtlString &dest ) -{ - int nLen = buf.PeekDelimitedStringLength( s_pConv ); - dest.SetLength( nLen - 1 ); // -1 because the length returned includes space for \0 - buf.GetDelimitedString( s_pConv, dest.Get(), nLen ); - return buf.IsValid(); -} - - - - diff --git a/Resources/NetHook/tier1/utlbufferutil.h b/Resources/NetHook/tier1/utlbufferutil.h deleted file mode 100644 index 2c7ca2c7..00000000 --- a/Resources/NetHook/tier1/utlbufferutil.h +++ /dev/null @@ -1,192 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// Utilities for serialization/unserialization buffer -//=============================================================================// - -#ifndef UTLBUFFERUTIL_H -#define UTLBUFFERUTIL_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlvector.h" -#include "tier1/utlbuffer.h" - - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class Vector2D; -class Vector; -class Vector4D; -class QAngle; -class Quaternion; -class VMatrix; -class Color; -class CUtlBinaryBlock; -class CUtlString; -class CUtlCharConversion; - - -//----------------------------------------------------------------------------- -// For string serialization, set the delimiter rules -//----------------------------------------------------------------------------- -void SetSerializationDelimiter( CUtlCharConversion *pConv ); -void SetSerializationArrayDelimiter( const char *pDelimiter ); - - -//----------------------------------------------------------------------------- -// Standard serialization methods for basic types -//----------------------------------------------------------------------------- -bool Serialize( CUtlBuffer &buf, const bool &src ); -bool Unserialize( CUtlBuffer &buf, bool &dest ); - -bool Serialize( CUtlBuffer &buf, const int &src ); -bool Unserialize( CUtlBuffer &buf, int &dest ); - -bool Serialize( CUtlBuffer &buf, const float &src ); -bool Unserialize( CUtlBuffer &buf, float &dest ); - -bool Serialize( CUtlBuffer &buf, const Vector2D &src ); -bool Unserialize( CUtlBuffer &buf, Vector2D &dest ); - -bool Serialize( CUtlBuffer &buf, const Vector &src ); -bool Unserialize( CUtlBuffer &buf, Vector &dest ); - -bool Serialize( CUtlBuffer &buf, const Vector4D &src ); -bool Unserialize( CUtlBuffer &buf, Vector4D &dest ); - -bool Serialize( CUtlBuffer &buf, const QAngle &src ); -bool Unserialize( CUtlBuffer &buf, QAngle &dest ); - -bool Serialize( CUtlBuffer &buf, const Quaternion &src ); -bool Unserialize( CUtlBuffer &buf, Quaternion &dest ); - -bool Serialize( CUtlBuffer &buf, const VMatrix &src ); -bool Unserialize( CUtlBuffer &buf, VMatrix &dest ); - -bool Serialize( CUtlBuffer &buf, const Color &src ); -bool Unserialize( CUtlBuffer &buf, Color &dest ); - -bool Serialize( CUtlBuffer &buf, const CUtlBinaryBlock &src ); -bool Unserialize( CUtlBuffer &buf, CUtlBinaryBlock &dest ); - -bool Serialize( CUtlBuffer &buf, const CUtlString &src ); -bool Unserialize( CUtlBuffer &buf, CUtlString &dest ); - - -//----------------------------------------------------------------------------- -// You can use this to check if a type serializes on multiple lines -//----------------------------------------------------------------------------- -template< class T > -inline bool SerializesOnMultipleLines() -{ - return false; -} - -template< > -inline bool SerializesOnMultipleLines() -{ - return true; -} - -template< > -inline bool SerializesOnMultipleLines() -{ - return true; -} - - -//----------------------------------------------------------------------------- -// Vector serialization -//----------------------------------------------------------------------------- -template< class T > -bool Serialize( CUtlBuffer &buf, const CUtlVector &src ) -{ - extern const char *s_pUtlBufferUtilArrayDelim; - - int nCount = src.Count(); - - if ( !buf.IsText() ) - { - buf.PutInt( nCount ); - for ( int i = 0; i < nCount; ++i ) - { - ::Serialize( buf, src[i] ); - } - return buf.IsValid(); - } - - if ( !SerializesOnMultipleLines() ) - { - buf.PutChar('\n'); - for ( int i = 0; i < nCount; ++i ) - { - ::Serialize( buf, src[i] ); - if ( s_pUtlBufferUtilArrayDelim && (i != nCount-1) ) - { - buf.PutString( s_pUtlBufferUtilArrayDelim ); - } - buf.PutChar('\n'); - } - } - else - { - for ( int i = 0; i < nCount; ++i ) - { - ::Serialize( buf, src[i] ); - if ( s_pUtlBufferUtilArrayDelim && (i != nCount-1) ) - { - buf.PutString( s_pUtlBufferUtilArrayDelim ); - } - buf.PutChar(' '); - } - } - - return buf.IsValid(); -} - -template< class T > -bool Unserialize( CUtlBuffer &buf, CUtlVector &dest ) -{ - dest.RemoveAll(); - - MEM_ALLOC_CREDIT_FUNCTION(); - - if ( !buf.IsText() ) - { - int nCount = buf.GetInt(); - if ( nCount ) - { - dest.EnsureCapacity( nCount ); - for ( int i = 0; i < nCount; ++i ) - { - VerifyEquals( dest.AddToTail(), i ); - if ( !::Unserialize( buf, dest[i] ) ) - return false; - } - } - return buf.IsValid(); - } - - while ( true ) - { - buf.EatWhiteSpace(); - if ( !buf.IsValid() ) - break; - - int i = dest.AddToTail( ); - if ( ! ::Unserialize( buf, dest[i] ) ) - return false; - } - return true; -} - - -#endif // UTLBUFFERUTIL_H - diff --git a/Resources/NetHook/tier1/utldict.h b/Resources/NetHook/tier1/utldict.h deleted file mode 100644 index d6e777d1..00000000 --- a/Resources/NetHook/tier1/utldict.h +++ /dev/null @@ -1,320 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: A dictionary mapping from symbol to structure -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLDICT_H -#define UTLDICT_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "tier1/utlmap.h" - -// Include this because tons of code was implicitly getting utlsymbol or utlvector via utldict.h -#include "tier1/utlsymbol.h" - -#include "tier0/memdbgon.h" - -enum EDictCompareType -{ - k_eDictCompareTypeCaseSensitive=0, - k_eDictCompareTypeCaseInsensitive=1, - k_eDictCompareTypeFilenames // Slashes and backslashes count as the same character.. -}; - -//----------------------------------------------------------------------------- -// A dictionary mapping from symbol to structure -//----------------------------------------------------------------------------- -template -class CUtlDict -{ -public: - // constructor, destructor - // Left at growSize = 0, the memory will first allocate 1 element and double in size - // at each increment. - CUtlDict( int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0 ); - ~CUtlDict( ); - - void EnsureCapacity( int ); - - // gets particular elements - T& Element( I i ); - const T& Element( I i ) const; - T& operator[]( I i ); - const T& operator[]( I i ) const; - - // gets element names - char *GetElementName( I i ); - char const *GetElementName( I i ) const; - - void SetElementName( I i, char const *pName ); - - // Number of elements - unsigned int Count() const; - - // Checks if a node is valid and in the tree - bool IsValidIndex( I i ) const; - - // Invalid index - static I InvalidIndex(); - - // Insert method (inserts in order) - I Insert( const char *pName, const T &element ); - I Insert( const char *pName ); - - // Find method - I Find( const char *pName ) const; - - // Remove methods - void RemoveAt( I i ); - void Remove( const char *pName ); - void RemoveAll( ); - - // Purge memory - void Purge(); - void PurgeAndDeleteElements(); // Call delete on each element. - - // Iteration methods - I First() const; - I Next( I i ) const; - -protected: - typedef CUtlMap DictElementMap_t; - DictElementMap_t m_Elements; -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template -CUtlDict::CUtlDict( int compareType, int growSize, int initSize ) : m_Elements( growSize, initSize ) -{ - if ( compareType == k_eDictCompareTypeFilenames ) - { - m_Elements.SetLessFunc( CaselessStringLessThanIgnoreSlashes ); - } - else if ( compareType == k_eDictCompareTypeCaseInsensitive ) - { - m_Elements.SetLessFunc( CaselessStringLessThan ); - } - else - { - m_Elements.SetLessFunc( StringLessThan ); - } -} - -template -CUtlDict::~CUtlDict() -{ - Purge(); -} - -template -inline void CUtlDict::EnsureCapacity( int num ) -{ - return m_Elements.EnsureCapacity( num ); -} - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- -template -inline T& CUtlDict::Element( I i ) -{ - return m_Elements[i]; -} - -template -inline const T& CUtlDict::Element( I i ) const -{ - return m_Elements[i]; -} - -//----------------------------------------------------------------------------- -// gets element names -//----------------------------------------------------------------------------- -template -inline char *CUtlDict::GetElementName( I i ) -{ - return (char *)m_Elements.Key( i ); -} - -template -inline char const *CUtlDict::GetElementName( I i ) const -{ - return m_Elements.Key( i ); -} - -template -inline T& CUtlDict::operator[]( I i ) -{ - return Element(i); -} - -template -inline const T & CUtlDict::operator[]( I i ) const -{ - return Element(i); -} - -template -inline void CUtlDict::SetElementName( I i, char const *pName ) -{ - MEM_ALLOC_CREDIT_CLASS(); - // TODO: This makes a copy of the old element - // TODO: This relies on the rb tree putting the most recently - // removed element at the head of the insert list - free( (void *)m_Elements.Key( i ) ); - m_Elements.Reinsert( strdup( pName ), i ); -} - -//----------------------------------------------------------------------------- -// Num elements -//----------------------------------------------------------------------------- -template -inline unsigned int CUtlDict::Count() const -{ - return m_Elements.Count(); -} - - -//----------------------------------------------------------------------------- -// Checks if a node is valid and in the tree -//----------------------------------------------------------------------------- -template -inline bool CUtlDict::IsValidIndex( I i ) const -{ - return m_Elements.IsValidIndex(i); -} - - -//----------------------------------------------------------------------------- -// Invalid index -//----------------------------------------------------------------------------- -template -inline I CUtlDict::InvalidIndex() -{ - return DictElementMap_t::InvalidIndex(); -} - - -//----------------------------------------------------------------------------- -// Delete a node from the tree -//----------------------------------------------------------------------------- -template -void CUtlDict::RemoveAt(I elem) -{ - free( (void *)m_Elements.Key( elem ) ); - m_Elements.RemoveAt(elem); -} - - -//----------------------------------------------------------------------------- -// remove a node in the tree -//----------------------------------------------------------------------------- -template void CUtlDict::Remove( const char *search ) -{ - I node = Find( search ); - if (node != InvalidIndex()) - { - RemoveAt(node); - } -} - - -//----------------------------------------------------------------------------- -// Removes all nodes from the tree -//----------------------------------------------------------------------------- -template -void CUtlDict::RemoveAll() -{ - typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder(); - while ( index != m_Elements.InvalidIndex() ) - { - free( (void *)m_Elements.Key( index ) ); - index = m_Elements.NextInorder( index ); - } - - m_Elements.RemoveAll(); -} - -template -void CUtlDict::Purge() -{ - RemoveAll(); -} - - -template -void CUtlDict::PurgeAndDeleteElements() -{ - // Delete all the elements. - I index = m_Elements.FirstInorder(); - while ( index != m_Elements.InvalidIndex() ) - { - free( (void *)m_Elements.Key( index ) ); - delete m_Elements[index]; - index = m_Elements.NextInorder( index ); - } - - m_Elements.RemoveAll(); -} - - -//----------------------------------------------------------------------------- -// inserts a node into the tree -//----------------------------------------------------------------------------- -template -I CUtlDict::Insert( const char *pName, const T &element ) -{ - MEM_ALLOC_CREDIT_CLASS(); - return m_Elements.Insert( strdup( pName ), element ); -} - -template -I CUtlDict::Insert( const char *pName ) -{ - MEM_ALLOC_CREDIT_CLASS(); - return m_Elements.Insert( strdup( pName ) ); -} - - -//----------------------------------------------------------------------------- -// finds a node in the tree -//----------------------------------------------------------------------------- -template -I CUtlDict::Find( const char *pName ) const -{ - MEM_ALLOC_CREDIT_CLASS(); - if ( pName ) - return m_Elements.Find( pName ); - else - return InvalidIndex(); -} - - -//----------------------------------------------------------------------------- -// Iteration methods -//----------------------------------------------------------------------------- -template -I CUtlDict::First() const -{ - return m_Elements.FirstInorder(); -} - -template -I CUtlDict::Next( I i ) const -{ - return m_Elements.NextInorder(i); -} - -#include "tier0/memdbgoff.h" - -#endif // UTLDICT_H diff --git a/Resources/NetHook/tier1/utlenvelope.h b/Resources/NetHook/tier1/utlenvelope.h deleted file mode 100644 index 58fe0727..00000000 --- a/Resources/NetHook/tier1/utlenvelope.h +++ /dev/null @@ -1,240 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: A class to wrap data for transport over a boundary like a thread -// or window. -// -//============================================================================= - -#include "tier1/utlstring.h" -#include "tier0/basetypes.h" - -#ifndef UTLENVELOPE_H -#define UTLENVELOPE_H - -#if defined( _WIN32 ) -#pragma once -#endif - -//----------------------------------------------------------------------------- - -class CUtlDataEnvelope -{ -public: - CUtlDataEnvelope( const void *pData, int nBytes ); - CUtlDataEnvelope( const CUtlDataEnvelope &from ); - ~CUtlDataEnvelope(); - - CUtlDataEnvelope &operator=( const CUtlDataEnvelope &from ); - - operator void *(); - operator void *() const; - -private: - void Assign( const void *pData, int nBytes ); - void Assign( const CUtlDataEnvelope &from ); - void Purge(); - - // TODO: switch to a reference counted array? - union - { - byte *m_pData; - byte m_data[4]; - }; - int m_nBytes; -}; - - -//----------------------------------------------------------------------------- - -template -class CUtlEnvelope : protected CUtlDataEnvelope -{ -public: - CUtlEnvelope( const T *pData, int nElems = 1 ); - CUtlEnvelope( const CUtlEnvelope &from ); - - CUtlEnvelope &operator=( const CUtlEnvelope &from ); - - operator T *(); - operator T *() const; - - operator void *(); - operator void *() const; -}; - -//----------------------------------------------------------------------------- - -template <> -class CUtlEnvelope -{ -public: - CUtlEnvelope( const char *pData ) - { - m_string = pData; - } - - CUtlEnvelope( const CUtlEnvelope &from ) - { - m_string = from.m_string; - } - - CUtlEnvelope &operator=( const CUtlEnvelope &from ) - { - m_string = from.m_string; - } - - operator char *() - { - return (char *) m_string.Get(); - } - - operator char *() const - { - return (char *) m_string.Get(); - } - - operator void *() - { - return (void *) m_string.Get(); - } - - operator void *() const - { - return (void *) m_string.Get(); - } - -private: - CUtlString m_string; -}; - -//----------------------------------------------------------------------------- - -#include "tier0/memdbgon.h" - -inline void CUtlDataEnvelope::Assign( const void *pData, int nBytes ) -{ - if ( pData ) - { - m_nBytes = nBytes; - if ( m_nBytes > 4 ) - { - m_pData = new byte[nBytes]; - memcpy( m_pData, pData, nBytes ); - } - else - { - memcpy( m_data, pData, nBytes ); - } - } - else - { - m_pData = NULL; - m_nBytes = 0; - } -} - -inline void CUtlDataEnvelope::Assign( const CUtlDataEnvelope &from ) -{ - Assign( from.operator void *(), from.m_nBytes ); -} - -inline void CUtlDataEnvelope::Purge() -{ - if (m_nBytes > 4) - delete [] m_pData; - m_nBytes = 0; -} - -inline CUtlDataEnvelope::CUtlDataEnvelope( const void *pData, int nBytes ) -{ - Assign( pData, nBytes ); -} - -inline CUtlDataEnvelope::CUtlDataEnvelope( const CUtlDataEnvelope &from ) -{ - Assign( from ); -} - -inline CUtlDataEnvelope::~CUtlDataEnvelope() -{ - Purge(); -} - -inline CUtlDataEnvelope &CUtlDataEnvelope::operator=( const CUtlDataEnvelope &from ) -{ - Purge(); - Assign( from ); - return *this; -} - -inline CUtlDataEnvelope::operator void *() -{ - if ( !m_nBytes ) - { - return NULL; - } - - return ( m_nBytes > 4) ? m_pData : m_data; -} - -inline CUtlDataEnvelope::operator void *() const -{ - if ( !m_nBytes ) - { - return NULL; - } - - return ( m_nBytes > 4) ? (void *)m_pData : (void *)m_data; -} - -//----------------------------------------------------------------------------- - -template -inline CUtlEnvelope::CUtlEnvelope( const T *pData, int nElems = 1 ) - : CUtlDataEnvelope( pData, sizeof(T) * nElems ) -{ -} - -template -inline CUtlEnvelope::CUtlEnvelope( const CUtlEnvelope &from ) - : CUtlDataEnvelope( from ) -{ - -} - -template -inline CUtlEnvelope &CUtlEnvelope::operator=( const CUtlEnvelope &from ) -{ - CUtlDataEnvelope::operator=( from ); - return *this; -} - -template -inline CUtlEnvelope::operator T *() -{ - return (T *)CUtlDataEnvelope::operator void *(); -} - -template -inline CUtlEnvelope::operator T *() const -{ - return (T *)( (const_cast *>(this))->operator T *() ); -} - -template -inline CUtlEnvelope::operator void *() -{ - return CUtlDataEnvelope::operator void *(); -} - -template -inline CUtlEnvelope::operator void *() const -{ - return ( (const_cast *>(this))->operator void *() ); -} - -//----------------------------------------------------------------------------- - -#include "tier0/memdbgoff.h" - -#endif // UTLENVELOPE_H diff --git a/Resources/NetHook/tier1/utlfixedmemory.h b/Resources/NetHook/tier1/utlfixedmemory.h deleted file mode 100644 index 3a05c3ef..00000000 --- a/Resources/NetHook/tier1/utlfixedmemory.h +++ /dev/null @@ -1,356 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -// A growable memory class. -//===========================================================================// - -#ifndef UTLFIXEDMEMORY_H -#define UTLFIXEDMEMORY_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "tier0/platform.h" - -#include "tier0/memalloc.h" -#include "tier0/memdbgon.h" - -#pragma warning (disable:4100) -#pragma warning (disable:4514) - -//----------------------------------------------------------------------------- - -#ifdef UTLMEMORY_TRACK -#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlFixedMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) -#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlFixedMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) -#else -#define UTLMEMORY_TRACK_ALLOC() ((void)0) -#define UTLMEMORY_TRACK_FREE() ((void)0) -#endif - - -//----------------------------------------------------------------------------- -// The CUtlFixedMemory class: -// A growable memory class that allocates non-sequential blocks, but is indexed sequentially -//----------------------------------------------------------------------------- -template< class T > -class CUtlFixedMemory -{ -public: - // constructor, destructor - CUtlFixedMemory( int nGrowSize = 0, int nInitSize = 0 ); - ~CUtlFixedMemory(); - - // Set the size by which the memory grows - void Init( int nGrowSize = 0, int nInitSize = 0 ); - - // here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL - T* Base() { return NULL; } - const T* Base() const { return NULL; } - -protected: - struct BlockHeader_t; - -public: - class Iterator_t - { - public: - Iterator_t( BlockHeader_t *p, int i ) : m_pBlockHeader( p ), m_nIndex( i ) {} - BlockHeader_t *m_pBlockHeader; - int m_nIndex; - - bool operator==( const Iterator_t it ) const { return m_pBlockHeader == it.m_pBlockHeader && m_nIndex == it.m_nIndex; } - bool operator!=( const Iterator_t it ) const { return m_pBlockHeader != it.m_pBlockHeader || m_nIndex != it.m_nIndex; } - }; - Iterator_t First() const { return m_pBlocks ? Iterator_t( m_pBlocks, 0 ) : InvalidIterator(); } - Iterator_t Next( const Iterator_t &it ) const - { - Assert( IsValidIterator( it ) ); - if ( !IsValidIterator( it ) ) - return InvalidIterator(); - - BlockHeader_t * RESTRICT pHeader = it.m_pBlockHeader; - if ( it.m_nIndex + 1 < pHeader->m_nBlockSize ) - return Iterator_t( pHeader, it.m_nIndex + 1 ); - - return pHeader->m_pNext ? Iterator_t( pHeader->m_pNext, 0 ) : InvalidIterator(); - } - int GetIndex( const Iterator_t &it ) const - { - Assert( IsValidIterator( it ) ); - if ( !IsValidIterator( it ) ) - return InvalidIndex(); - - return ( int )( HeaderToBlock( it.m_pBlockHeader ) + it.m_nIndex ); - } - bool IsIdxAfter( int i, const Iterator_t &it ) const - { - Assert( IsValidIterator( it ) ); - if ( !IsValidIterator( it ) ) - return false; - - if ( IsInBlock( i, it.m_pBlockHeader ) ) - return i > GetIndex( it ); - - for ( BlockHeader_t * RESTRICT pbh = it.m_pBlockHeader->m_pNext; pbh; pbh = pbh->m_pNext ) - { - if ( IsInBlock( i, pbh ) ) - return true; - } - return false; - } - bool IsValidIterator( const Iterator_t &it ) const { return it.m_pBlockHeader && it.m_nIndex >= 0 && it.m_nIndex < it.m_pBlockHeader->m_nBlockSize; } - Iterator_t InvalidIterator() const { return Iterator_t( NULL, -1 ); } - - // element access - T& operator[]( int i ); - const T& operator[]( int i ) const; - T& Element( int i ); - const T& Element( int i ) const; - - // Can we use this index? - bool IsIdxValid( int i ) const; - static int InvalidIndex() { return 0; } - - // Size - int NumAllocated() const; - int Count() const { return NumAllocated(); } - - // Grows memory by max(num,growsize), and returns the allocation index/ptr - void Grow( int num = 1 ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - -protected: - // Fast swap - WARNING: Swap invalidates all ptr-based indices!!! - void Swap( CUtlFixedMemory< T > &mem ); - - bool IsInBlock( int i, BlockHeader_t *pBlockHeader ) const - { - T *p = ( T* )i; - const T *p0 = HeaderToBlock( pBlockHeader ); - return p >= p0 && p < p0 + pBlockHeader->m_nBlockSize; - } - - struct BlockHeader_t - { - BlockHeader_t *m_pNext; - int m_nBlockSize; - }; - - const T *HeaderToBlock( const BlockHeader_t *pHeader ) const { return ( T* )( pHeader + 1 ); } - const BlockHeader_t *BlockToHeader( const T *pBlock ) const { return ( BlockHeader_t* )( pBlock ) - 1; } - - BlockHeader_t* m_pBlocks; - int m_nAllocationCount; - int m_nGrowSize; -}; - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T > -CUtlFixedMemory::CUtlFixedMemory( int nGrowSize, int nInitAllocationCount ) -: m_pBlocks( 0 ), m_nAllocationCount( 0 ), m_nGrowSize( 0 ) -{ - Init( nGrowSize, nInitAllocationCount ); -} - -template< class T > -CUtlFixedMemory::~CUtlFixedMemory() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -// Fast swap - WARNING: Swap invalidates all ptr-based indices!!! -//----------------------------------------------------------------------------- -template< class T > -void CUtlFixedMemory::Swap( CUtlFixedMemory< T > &mem ) -{ - swap( m_pBlocks, mem.m_pBlocks ); - swap( m_nAllocationCount, mem.m_nAllocationCount ); - swap( m_nGrowSize, mem.m_nGrowSize ); -} - - -//----------------------------------------------------------------------------- -// Set the size by which the memory grows - round up to the next power of 2 -//----------------------------------------------------------------------------- -template< class T > -void CUtlFixedMemory::Init( int nGrowSize /* = 0 */, int nInitSize /* = 0 */ ) -{ - Purge(); - - if ( nGrowSize == 0) - { - // Compute an allocation which is at least as big as a cache line... - nGrowSize = ( 31 + sizeof( T ) ) / sizeof( T ); - } - m_nGrowSize = nGrowSize; - - Grow( nInitSize ); -} - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< class T > -inline T& CUtlFixedMemory::operator[]( int i ) -{ - Assert( IsIdxValid(i) ); - return *( T* )i; -} - -template< class T > -inline const T& CUtlFixedMemory::operator[]( int i ) const -{ - Assert( IsIdxValid(i) ); - return *( T* )i; -} - -template< class T > -inline T& CUtlFixedMemory::Element( int i ) -{ - Assert( IsIdxValid(i) ); - return *( T* )i; -} - -template< class T > -inline const T& CUtlFixedMemory::Element( int i ) const -{ - Assert( IsIdxValid(i) ); - return *( T* )i; -} - - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlFixedMemory::NumAllocated() const -{ - return m_nAllocationCount; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< class T > -inline bool CUtlFixedMemory::IsIdxValid( int i ) const -{ -#ifdef _DEBUG - for ( BlockHeader_t *pbh = m_pBlocks; pbh; pbh = pbh->m_pNext ) - { - if ( IsInBlock( i, pbh ) ) - return true; - } - return false; -#else - return i != InvalidIndex(); -#endif -} - -template< class T > -void CUtlFixedMemory::Grow( int num ) -{ - if ( num <= 0 ) - return; - - int nBlockSize = m_nGrowSize; - if ( nBlockSize == 0 ) - { - if ( m_nAllocationCount ) - { - nBlockSize = m_nAllocationCount; - } - else - { - // Compute an allocation which is at least as big as a cache line... - nBlockSize = ( 31 + sizeof( T ) ) / sizeof( T ); - Assert( nBlockSize ); - } - } - if ( nBlockSize < num ) - { - int n = ( num + nBlockSize -1 ) / nBlockSize; - Assert( n * nBlockSize >= num ); - Assert( ( n - 1 ) * nBlockSize < num ); - nBlockSize *= n; - } - m_nAllocationCount += nBlockSize; - - MEM_ALLOC_CREDIT_CLASS(); - BlockHeader_t * RESTRICT pBlockHeader = ( BlockHeader_t* )malloc( sizeof( BlockHeader_t ) + nBlockSize * sizeof( T ) ); - if ( !pBlockHeader ) - { - Error( "CUtlFixedMemory overflow!\n" ); - } - pBlockHeader->m_pNext = NULL; - pBlockHeader->m_nBlockSize = nBlockSize; - - if ( !m_pBlocks ) - { - m_pBlocks = pBlockHeader; - } - else - { -#if 1 // IsIdxAfter assumes that newly allocated blocks are at the end - BlockHeader_t * RESTRICT pbh = m_pBlocks; - while ( pbh->m_pNext ) - { - pbh = pbh->m_pNext; - } - pbh->m_pNext = pBlockHeader; -#else - pBlockHeader = m_pBlocks; - pBlockHeader->m_pNext = m_pBlocks; -#endif - } -} - - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -template< class T > -inline void CUtlFixedMemory::EnsureCapacity( int num ) -{ - Grow( num - NumAllocated() ); -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T > -void CUtlFixedMemory::Purge() -{ - if ( !m_pBlocks ) - return; - - for ( BlockHeader_t *pbh = m_pBlocks; pbh; ) - { - BlockHeader_t *pFree = pbh; - pbh = pbh->m_pNext; - free( pFree ); - } - m_pBlocks = NULL; - m_nAllocationCount = 0; -} - -#include "tier0/memdbgoff.h" - -#endif // UTLFIXEDMEMORY_H diff --git a/Resources/NetHook/tier1/utlflags.h b/Resources/NetHook/tier1/utlflags.h deleted file mode 100644 index 889cb8a9..00000000 --- a/Resources/NetHook/tier1/utlflags.h +++ /dev/null @@ -1,124 +0,0 @@ -//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: Simple class to make it easier to deal with flags -// -//============================================================================= - -#ifndef UTLFLAGS_H -#define UTLFLAGS_H -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" - - -//----------------------------------------------------------------------------- -// Simple class to make it easier to deal with flags -//----------------------------------------------------------------------------- -template< class T > -class CUtlFlags -{ -public: - CUtlFlags( int nInitialFlags = 0 ); - - // Flag setting - void SetFlag( int nFlagMask ); - void SetFlag( int nFlagMask, bool bEnable ); - - // Flag clearing - void ClearFlag( int nFlagMask ); - void ClearAllFlags(); - bool IsFlagSet( int nFlagMask ) const; - - // Is any flag set? - bool IsAnyFlagSet() const; - -private: - T m_nFlags; -}; - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -template< class T > -CUtlFlags::CUtlFlags( int nInitialFlags ) -{ - // Makes sure we didn't truncate - Assert( nInitialFlags == (T)nInitialFlags ); - - m_nFlags = (T)nInitialFlags; -} - - -//----------------------------------------------------------------------------- -// Set flags -//----------------------------------------------------------------------------- -template< class T > -void CUtlFlags::SetFlag( int nFlagMask ) -{ - // Makes sure we didn't truncate - Assert( nFlagMask == (T)nFlagMask ); - - m_nFlags |= (T)nFlagMask; -} - -template< class T > -void CUtlFlags::SetFlag( int nFlagMask, bool bEnable ) -{ - // Makes sure we didn't truncate - Assert( nFlagMask == (T)nFlagMask ); - - if ( bEnable ) - { - m_nFlags |= (T)nFlagMask; - } - else - { - m_nFlags &= ~((T)nFlagMask); - } -} - - -//----------------------------------------------------------------------------- -// Clear flags -//----------------------------------------------------------------------------- -template< class T > -void CUtlFlags::ClearFlag( int nFlagMask ) -{ - // Makes sure we didn't truncate - Assert( nFlagMask == (T)nFlagMask ); - m_nFlags &= ~((T)nFlagMask); -} - -template< class T > -void CUtlFlags::ClearAllFlags() -{ - m_nFlags = 0; -} - - -//----------------------------------------------------------------------------- -// Is a flag set? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlFlags::IsFlagSet( int nFlagMask ) const -{ - // Makes sure we didn't truncate - Assert( nFlagMask == (T)nFlagMask ); - return ( m_nFlags & nFlagMask ) != 0; -} - - -//----------------------------------------------------------------------------- -// Is any flag set? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlFlags::IsAnyFlagSet() const -{ - return m_nFlags != 0; -} - - -#endif // UTLFLAGS_H diff --git a/Resources/NetHook/tier1/utlhandletable.h b/Resources/NetHook/tier1/utlhandletable.h deleted file mode 100644 index 12bcdafd..00000000 --- a/Resources/NetHook/tier1/utlhandletable.h +++ /dev/null @@ -1,586 +0,0 @@ -//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#ifndef UTLHANDLETABLE_H -#define UTLHANDLETABLE_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include "tier1/utlvector.h" -#include "tier1/utlqueue.h" - - -//----------------------------------------------------------------------------- -// Handles are 32 bits. Invalid handles are all 1s -//----------------------------------------------------------------------------- -typedef unsigned int UtlHandle_t; -#define UTLHANDLE_INVALID ((UtlHandle_t)~0) - - -//----------------------------------------------------------------------------- -// Purpose: This is a table used to allocate handles -// HandleBits specifies the max # of simultaneously allocated handles. -// An extra bit is used for the validity state -// The rest of the 32 bits are used for a serial number -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -class CUtlHandleTable -{ -public: - CUtlHandleTable(); - - // Allocate, deallocate handles - UtlHandle_t AddHandle(); - void RemoveHandle( UtlHandle_t h ); - - // Set/get handle values - void SetHandle( UtlHandle_t h, T *pData ); - T *GetHandle( UtlHandle_t h ) const; - T *GetHandle( UtlHandle_t h, bool checkValidity ) const; - - // Is a handle valid? - bool IsHandleValid( UtlHandle_t h ) const; - - // Iterate over handles; they may not be valid - unsigned int GetValidHandleCount() const; - unsigned int GetHandleCount() const; - UtlHandle_t GetHandleFromIndex( int i ) const; - int GetIndexFromHandle( UtlHandle_t h ) const; - - void MarkHandleInvalid( UtlHandle_t h ); - void MarkHandleValid( UtlHandle_t h ); - -private: - struct HandleType_t - { - HandleType_t( unsigned int i, unsigned int s ) : nIndex( i ), nSerial( s ) - { - Assert( i < ( 1 << HandleBits ) ); - Assert( s < ( 1 << ( 31 - HandleBits ) ) ); - } - unsigned int nIndex : HandleBits; - unsigned int nSerial : 31 - HandleBits; - }; - - struct EntryType_t - { - EntryType_t() : m_nSerial( 0 ), nInvalid( 0 ), m_pData( 0 ) {} - unsigned int m_nSerial : 31; - unsigned int nInvalid : 1; - T *m_pData; - }; - - static unsigned int GetSerialNumber( UtlHandle_t handle ); - static unsigned int GetListIndex( UtlHandle_t handle ); - static UtlHandle_t CreateHandle( unsigned int nSerial, unsigned int nIndex ); - const EntryType_t *GetEntry( UtlHandle_t handle, bool checkValidity ) const; - - unsigned int m_nValidHandles; - CUtlVector< EntryType_t > m_list; - CUtlQueue< int > m_unused; -}; - - -//----------------------------------------------------------------------------- -// Constructor, destructor -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -CUtlHandleTable::CUtlHandleTable() : m_nValidHandles( 0 ) -{ -} - - -//----------------------------------------------------------------------------- -// Allocate, deallocate handles -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -UtlHandle_t CUtlHandleTable::AddHandle() -{ - unsigned int nIndex = ( m_unused.Count() > 0 ) ? m_unused.RemoveAtHead() : m_list.AddToTail(); - - EntryType_t &entry = m_list[ nIndex ]; - entry.nInvalid = 0; - entry.m_pData = NULL; - - ++m_nValidHandles; - - return CreateHandle( entry.m_nSerial, nIndex ); -} - -template< class T, int HandleBits > -void CUtlHandleTable::RemoveHandle( UtlHandle_t handle ) -{ - unsigned int nIndex = GetListIndex( handle ); - Assert( nIndex < ( unsigned int )m_list.Count() ); - if ( nIndex >= ( unsigned int )m_list.Count() ) - return; - - EntryType_t &entry = m_list[ nIndex ]; - ++entry.m_nSerial; // mark old serial# invalid - if ( !entry.nInvalid ) - { - entry.nInvalid = 1; - --m_nValidHandles; - } - entry.m_pData = NULL; - - - // If a handle has been used this many times, then we need to take it out of service, otherwise if the - // serial # wraps around we'll possibly revalidate old handles and they'll start to point at the wrong objects. Unlikely, but possible. - bool bStopUsing = ( entry.m_nSerial >= ( (1 << ( 31 - HandleBits ) ) - 1 ) ); - if ( !bStopUsing ) - { - m_unused.Insert( nIndex ); - } -} - - -//----------------------------------------------------------------------------- -// Set/get handle values -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -void CUtlHandleTable::SetHandle( UtlHandle_t handle, T *pData ) -{ - EntryType_t *entry = const_cast< EntryType_t* >( GetEntry( handle, false ) ); - Assert( entry ); - if ( entry == NULL ) - return; - - // Validate the handle - if ( entry->nInvalid ) - { - ++m_nValidHandles; - entry->nInvalid = 0; - } - entry->m_pData = pData; -} - -template< class T, int HandleBits > -T *CUtlHandleTable::GetHandle( UtlHandle_t handle ) const -{ - const EntryType_t *entry = GetEntry( handle, true ); - return entry ? entry->m_pData : NULL; -} - -template< class T, int HandleBits > -T *CUtlHandleTable::GetHandle( UtlHandle_t handle, bool checkValidity ) const -{ - const EntryType_t *entry = GetEntry( handle, checkValidity ); - return entry ? entry->m_pData : NULL; -} - - -//----------------------------------------------------------------------------- -// Is a handle valid? -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -bool CUtlHandleTable::IsHandleValid( UtlHandle_t handle ) const -{ - if ( handle == UTLHANDLE_INVALID ) - return false; - - unsigned int nIndex = GetListIndex( handle ); - AssertOnce( nIndex < ( unsigned int )m_list.Count() ); - if ( nIndex >= ( unsigned int )m_list.Count() ) - return false; - - const EntryType_t &entry = m_list[ nIndex ]; - if ( entry.m_nSerial != GetSerialNumber( handle ) ) - return false; - - if ( 1 == entry.nInvalid ) - return false; - - return true; -} - - -//----------------------------------------------------------------------------- -// Current max handle -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -unsigned int CUtlHandleTable::GetValidHandleCount() const -{ - return m_nValidHandles; -} - -template< class T, int HandleBits > -unsigned int CUtlHandleTable::GetHandleCount() const -{ - return m_list.Count(); -} - -template< class T, int HandleBits > -UtlHandle_t CUtlHandleTable::GetHandleFromIndex( int i ) const -{ - if ( m_list[i].m_pData ) - return CreateHandle( m_list[i].m_nSerial, i ); - return UTLHANDLE_INVALID; -} - -template< class T, int HandleBits > -int CUtlHandleTable::GetIndexFromHandle( UtlHandle_t h ) const -{ - if ( h == UTLHANDLE_INVALID ) - return -1; - - return GetListIndex( h ); -} - - - -//----------------------------------------------------------------------------- -// Cracking handles into indices + serial numbers -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -unsigned int CUtlHandleTable::GetSerialNumber( UtlHandle_t handle ) -{ - return ( ( HandleType_t* )&handle )->nSerial; -} - -template< class T, int HandleBits > -unsigned int CUtlHandleTable::GetListIndex( UtlHandle_t handle ) -{ - return ( ( HandleType_t* )&handle )->nIndex; -} - -template< class T, int HandleBits > -UtlHandle_t CUtlHandleTable::CreateHandle( unsigned int nSerial, unsigned int nIndex ) -{ - HandleType_t h( nIndex, nSerial ); - return *( UtlHandle_t* )&h; -} - - -//----------------------------------------------------------------------------- -// Looks up a entry by handle -//----------------------------------------------------------------------------- -template< class T, int HandleBits > -const typename CUtlHandleTable::EntryType_t *CUtlHandleTable::GetEntry( UtlHandle_t handle, bool checkValidity ) const -{ - if ( handle == UTLHANDLE_INVALID ) - return NULL; - - unsigned int nIndex = GetListIndex( handle ); - Assert( nIndex < ( unsigned int )m_list.Count() ); - if ( nIndex >= ( unsigned int )m_list.Count() ) - return NULL; - - const EntryType_t &entry = m_list[ nIndex ]; - if ( entry.m_nSerial != GetSerialNumber( handle ) ) - return NULL; - - if ( checkValidity && - ( 1 == entry.nInvalid ) ) - return NULL; - - return &entry; -} - -template< class T, int HandleBits > -void CUtlHandleTable::MarkHandleInvalid( UtlHandle_t handle ) -{ - if ( handle == UTLHANDLE_INVALID ) - return; - - unsigned int nIndex = GetListIndex( handle ); - Assert( nIndex < ( unsigned int )m_list.Count() ); - if ( nIndex >= ( unsigned int )m_list.Count() ) - return; - - EntryType_t &entry = m_list[ nIndex ]; - if ( entry.m_nSerial != GetSerialNumber( handle ) ) - return; - - if ( !entry.nInvalid ) - { - --m_nValidHandles; - entry.nInvalid = 1; - } -} - -template< class T, int HandleBits > -void CUtlHandleTable::MarkHandleValid( UtlHandle_t handle ) -{ - if ( handle == UTLHANDLE_INVALID ) - return; - - unsigned int nIndex = GetListIndex( handle ); - Assert( nIndex < ( unsigned int )m_list.Count() ); - if ( nIndex >= ( unsigned int )m_list.Count() ) - return; - - EntryType_t &entry = m_list[ nIndex ]; - if ( entry.m_nSerial != GetSerialNumber( handle ) ) - return; - - if ( entry.nInvalid ) - { - ++m_nValidHandles; - entry.nInvalid = 0; - } -} - - -//----------------------------------------------------------------------------- -// Handle wrapper. Assumes 2 things -// 1) That class T has a non-static method called GetHandle which returns a UtlHandle_t -// 2) That class T has a static method called GetPtrFromHandle which returns a T* given a UtlHandle_t -// 3) That class T has a static method called IsHandleValid which accepts a UtlHandle_t -//----------------------------------------------------------------------------- -template< class T > -class CUtlHandle -{ -public: - // Constructors - CUtlHandle(); - explicit CUtlHandle( T *pObject ); - CUtlHandle( UtlHandle_t h ); - CUtlHandle( const CUtlHandle &h ); - - // Assignment - void Set( T *pObject ); - void Set( UtlHandle_t h ); - const CUtlHandle &operator=( UtlHandle_t h ); - const CUtlHandle &operator=( T *pObject ); - - // Retrieval - T *Get(); - const T* Get() const; - - // Is the handle valid? - bool IsValid() const; - - // Casting - operator T*(); - operator UtlHandle_t(); - operator bool(); - T* operator->(); - const T* operator->() const; - - // Equality - bool operator==( CUtlHandle h ) const; - bool operator==( T *pObject ) const; - bool operator==( UtlHandle_t h ) const; - bool operator!=( CUtlHandle h ) const; - bool operator!=( T *pObject ) const; - bool operator!=( UtlHandle_t h ) const; - -private: - UtlHandle_t m_handle; -}; - - -//----------------------------------------------------------------------------- -// Constructors -//----------------------------------------------------------------------------- -template< class T > -CUtlHandle::CUtlHandle() : m_handle( UTLHANDLE_INVALID ) -{ -} - -template< class T > -CUtlHandle::CUtlHandle( T *pObject ) -{ - Set( pObject ); -} - -template< class T > -CUtlHandle::CUtlHandle( UtlHandle_t h ) -{ - m_handle = h; -} - -template< class T > -CUtlHandle::CUtlHandle( const CUtlHandle &h ) -{ - m_handle = h.m_handle; -} - - -//----------------------------------------------------------------------------- -// Assignment -//----------------------------------------------------------------------------- -template< class T > -void CUtlHandle::Set( T *pObject ) -{ - // Assumes T has a member function GetHandle - m_handle = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; -} - -template< class T > -void CUtlHandle::Set( UtlHandle_t h ) -{ - m_handle = h; -} - -template< class T > -const CUtlHandle &CUtlHandle::operator=( UtlHandle_t h ) -{ - Set( h ); - return *this; -} - -template< class T > -const CUtlHandle &CUtlHandle::operator=( T *pObject ) -{ - Set( pObject ); - return *this; -} - - -//----------------------------------------------------------------------------- -// Is the handle valid? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlHandle::IsValid() const -{ - // Assumes T has a static member function IsHandleValid - return T::IsHandleValid( m_handle ); -} - - -//----------------------------------------------------------------------------- -// Retrieval -//----------------------------------------------------------------------------- -template< class T > -T *CUtlHandle::Get() -{ - // Assumes T has a static member function GetPtrFromHandle - return T::GetPtrFromHandle( m_handle ); -} - -template< class T > -const T* CUtlHandle::Get() const -{ - // Assumes T has a static member function GetPtrFromHandle - return T::GetPtrFromHandle( m_handle ); -} - - -//----------------------------------------------------------------------------- -// Casting -//----------------------------------------------------------------------------- -template< class T > -CUtlHandle::operator T*() -{ - return Get(); -} - -template< class T > -CUtlHandle::operator UtlHandle_t() -{ - return m_handle; -} - -template< class T > -T* CUtlHandle::operator->() -{ - return Get(); -} - -template< class T > -const T* CUtlHandle::operator->() const -{ - return Get(); -} - -template< class T > -CUtlHandle::operator bool() -{ - return m_handle != UTLHANDLE_INVALID; -} - - -//----------------------------------------------------------------------------- -// Equality -//----------------------------------------------------------------------------- -template< class T > -bool CUtlHandle::operator==( CUtlHandle h ) const -{ - return m_handle == h.m_handle; -} - -template< class T > -bool CUtlHandle::operator==( T *pObject ) const -{ - UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; - return m_handle == h; -} - -template< class T > -bool CUtlHandle::operator==( UtlHandle_t h ) const -{ - return m_handle == h; -} - -template< class T > -bool CUtlHandle::operator!=( CUtlHandle h ) const -{ - return m_handle != h.m_handle; -} - -template< class T > -bool CUtlHandle::operator!=( T *pObject ) const -{ - UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; - return m_handle != h; -} - -template< class T > -bool CUtlHandle::operator!=( UtlHandle_t h ) const -{ - return m_handle != h; -} - - -//----------------------------------------------------------------------------- -// Add this macro to a class definition to hook in handles for it! -//----------------------------------------------------------------------------- -#define DECLARE_HANDLES( _className, _handleBitCount ) \ - public: \ - UtlHandle_t GetHandle() \ - { \ - return m_Handle; \ - } \ - static _className* GetPtrFromHandle( UtlHandle_t h ) \ - { \ - return m_HandleTable.GetHandle( h ); \ - } \ - static bool IsHandleValid( UtlHandle_t h ) \ - { \ - return m_HandleTable.IsHandleValid( h ); \ - } \ - private: \ - UtlHandle_t m_Handle; \ - static CUtlHandleTable< _className, _handleBitCount > m_HandleTable - - -//----------------------------------------------------------------------------- -// Add this macro to a .cpp file to hook in handles for it! -//----------------------------------------------------------------------------- -#define IMPLEMENT_HANDLES( _className, _handleBitCount ) \ - CUtlHandleTable< _className, _handleBitCount > _className::m_HandleTable; - - -//----------------------------------------------------------------------------- -// Add these macro to the class constructor + destructor -//----------------------------------------------------------------------------- -#define CONSTRUCT_HANDLE( ) \ - m_Handle = m_HandleTable.AddHandle(); \ - m_HandleTable.SetHandle( m_Handle, this ) - -#define DESTRUCT_HANDLE() \ - m_HandleTable.RemoveHandle( m_Handle ); \ - m_Handle = UTLHANDLE_INVALID - - - -#endif // UTLHANDLETABLE_H - diff --git a/Resources/NetHook/tier1/utlhash.h b/Resources/NetHook/tier1/utlhash.h deleted file mode 100644 index b7cba7d4..00000000 --- a/Resources/NetHook/tier1/utlhash.h +++ /dev/null @@ -1,936 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -// Serialization/unserialization buffer -//=============================================================================// - -#ifndef UTLHASH_H -#define UTLHASH_H -#pragma once - -#include -#include -#include "utlmemory.h" -#include "utlvector.h" -#include "utllinkedlist.h" -#include "utllinkedlist.h" -#include "commonmacros.h" -#include "generichash.h" - -typedef unsigned int UtlHashHandle_t; - -template -class CUtlHash -{ -public: - // compare and key functions - implemented by the - typedef C CompareFunc_t; - typedef K KeyFunc_t; - - // constructor/deconstructor - CUtlHash( int bucketCount = 0, int growCount = 0, int initCount = 0, - CompareFunc_t compareFunc = 0, KeyFunc_t keyFunc = 0 ); - ~CUtlHash(); - - // invalid handle - static UtlHashHandle_t InvalidHandle( void ) { return ( UtlHashHandle_t )~0; } - bool IsValidHandle( UtlHashHandle_t handle ) const; - - // size - int Count( void ) const; - - // memory - void Purge( void ); - - // insertion methods - UtlHashHandle_t Insert( Data const &src ); - UtlHashHandle_t Insert( Data const &src, bool *pDidInsert ); - UtlHashHandle_t AllocEntryFromKey( Data const &src ); - - // removal methods - void Remove( UtlHashHandle_t handle ); - void RemoveAll(); - - // retrieval methods - UtlHashHandle_t Find( Data const &src ) const; - - Data &Element( UtlHashHandle_t handle ); - Data const &Element( UtlHashHandle_t handle ) const; - Data &operator[]( UtlHashHandle_t handle ); - Data const &operator[]( UtlHashHandle_t handle ) const; - - UtlHashHandle_t GetFirstHandle() const; - UtlHashHandle_t GetNextHandle( UtlHashHandle_t h ) const; - - // debugging!! - void Log( const char *filename ); - -protected: - - int GetBucketIndex( UtlHashHandle_t handle ) const; - int GetKeyDataIndex( UtlHashHandle_t handle ) const; - UtlHashHandle_t BuildHandle( int ndxBucket, int ndxKeyData ) const; - - bool DoFind( Data const &src, unsigned int *pBucket, int *pIndex ) const; - -protected: - - // handle upper 16 bits = bucket index (bucket heads) - // handle lower 16 bits = key index (bucket list) - typedef CUtlVector HashBucketList_t; - CUtlVector m_Buckets; - - CompareFunc_t m_CompareFunc; // function used to handle unique compares on data - KeyFunc_t m_KeyFunc; // function used to generate the key value - - bool m_bPowerOfTwo; // if the bucket value is a power of two, - unsigned int m_ModMask; // use the mod mask to "mod" -}; - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -CUtlHash::CUtlHash( int bucketCount, int growCount, int initCount, - CompareFunc_t compareFunc, KeyFunc_t keyFunc ) : - m_CompareFunc( compareFunc ), - m_KeyFunc( keyFunc ) -{ - m_Buckets.SetSize( bucketCount ); - for( int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++ ) - { - m_Buckets[ndxBucket].SetSize( initCount ); - m_Buckets[ndxBucket].SetGrowSize( growCount ); - } - - // check to see if the bucket count is a power of 2 and set up - // optimizations appropriately - m_bPowerOfTwo = IsPowerOfTwo( bucketCount ); - m_ModMask = m_bPowerOfTwo ? (bucketCount-1) : 0; -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -CUtlHash::~CUtlHash() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline bool CUtlHash::IsValidHandle( UtlHashHandle_t handle ) const -{ - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - // ndxBucket and ndxKeyData can't possibly be less than zero -- take a - // look at the definition of the Get..Index functions for why. However, - // if you override those functions, you will need to override this one - // as well. - if( /*( ndxBucket >= 0 ) && */ ( ndxBucket < m_Buckets.Count() ) ) - { - if( /*( ndxKeyData >= 0 ) && */ ( ndxKeyData < m_Buckets[ndxBucket].Count() ) ) - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline int CUtlHash::Count( void ) const -{ - int count = 0; - - int bucketCount = m_Buckets.Count(); - for( int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++ ) - { - count += m_Buckets[ndxBucket].Count(); - } - - return count; -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline int CUtlHash::GetBucketIndex( UtlHashHandle_t handle ) const -{ - return ( ( ( handle >> 16 ) & 0x0000ffff ) ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline int CUtlHash::GetKeyDataIndex( UtlHashHandle_t handle ) const -{ - return ( handle & 0x0000ffff ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::BuildHandle( int ndxBucket, int ndxKeyData ) const -{ - assert( ( ndxBucket >= 0 ) && ( ndxBucket < 65536 ) ); - assert( ( ndxKeyData >= 0 ) && ( ndxKeyData < 65536 ) ); - - UtlHashHandle_t handle = ndxKeyData; - handle |= ( ndxBucket << 16 ); - - return handle; -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline void CUtlHash::Purge( void ) -{ - int bucketCount = m_Buckets.Count(); - for( int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++ ) - { - m_Buckets[ndxBucket].Purge(); - } -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline bool CUtlHash::DoFind( Data const &src, unsigned int *pBucket, int *pIndex ) const -{ - // generate the data "key" - unsigned int key = m_KeyFunc( src ); - - // hash the "key" - get the correct hash table "bucket" - unsigned int ndxBucket; - if( m_bPowerOfTwo ) - { - *pBucket = ndxBucket = ( key & m_ModMask ); - } - else - { - int bucketCount = m_Buckets.Count(); - *pBucket = ndxBucket = key % bucketCount; - } - - int ndxKeyData; - const CUtlVector &bucket = m_Buckets[ndxBucket]; - int keyDataCount = bucket.Count(); - for( ndxKeyData = 0; ndxKeyData < keyDataCount; ndxKeyData++ ) - { - if( m_CompareFunc( bucket.Element( ndxKeyData ), src ) ) - break; - } - - if( ndxKeyData == keyDataCount ) - return false; - - *pIndex = ndxKeyData; - return true; -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::Find( Data const &src ) const -{ - unsigned int ndxBucket; - int ndxKeyData; - - if ( DoFind( src, &ndxBucket, &ndxKeyData ) ) - { - return ( BuildHandle( ndxBucket, ndxKeyData ) ); - } - return ( InvalidHandle() ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::Insert( Data const &src ) -{ - unsigned int ndxBucket; - int ndxKeyData; - - if ( DoFind( src, &ndxBucket, &ndxKeyData ) ) - { - return ( BuildHandle( ndxBucket, ndxKeyData ) ); - } - - ndxKeyData = m_Buckets[ndxBucket].AddToTail( src ); - - return ( BuildHandle( ndxBucket, ndxKeyData ) ); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::Insert( Data const &src, bool *pDidInsert ) -{ - unsigned int ndxBucket; - int ndxKeyData; - - if ( DoFind( src, &ndxBucket, &ndxKeyData ) ) - { - *pDidInsert = false; - return ( BuildHandle( ndxBucket, ndxKeyData ) ); - } - - *pDidInsert = true; - ndxKeyData = m_Buckets[ndxBucket].AddToTail( src ); - - return ( BuildHandle( ndxBucket, ndxKeyData ) ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::AllocEntryFromKey( Data const &src ) -{ - unsigned int ndxBucket; - int ndxKeyData; - - if ( DoFind( src, &ndxBucket, &ndxKeyData ) ) - { - return ( BuildHandle( ndxBucket, ndxKeyData ) ); - } - - ndxKeyData = m_Buckets[ndxBucket].AddToTail(); - - return ( BuildHandle( ndxBucket, ndxKeyData ) ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline void CUtlHash::Remove( UtlHashHandle_t handle ) -{ - assert( IsValidHandle( handle ) ); - - // check to see if the bucket exists - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - if( m_Buckets[ndxBucket].IsValidIndex( ndxKeyData ) ) - { - m_Buckets[ndxBucket].FastRemove( ndxKeyData ); - } -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline void CUtlHash::RemoveAll() -{ - int bucketCount = m_Buckets.Count(); - for( int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++ ) - { - m_Buckets[ndxBucket].RemoveAll(); - } -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline Data &CUtlHash::Element( UtlHashHandle_t handle ) -{ - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - return ( m_Buckets[ndxBucket].Element( ndxKeyData ) ); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline Data const &CUtlHash::Element( UtlHashHandle_t handle ) const -{ - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - return ( m_Buckets[ndxBucket].Element( ndxKeyData ) ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline Data &CUtlHash::operator[]( UtlHashHandle_t handle ) -{ - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - return ( m_Buckets[ndxBucket].Element( ndxKeyData ) ); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline Data const &CUtlHash::operator[]( UtlHashHandle_t handle ) const -{ - int ndxBucket = GetBucketIndex( handle ); - int ndxKeyData = GetKeyDataIndex( handle ); - - return ( m_Buckets[ndxBucket].Element( ndxKeyData ) ); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline UtlHashHandle_t CUtlHash::GetFirstHandle() const -{ - return GetNextHandle( ( UtlHashHandle_t )-1 ); -} - -template -inline UtlHashHandle_t CUtlHash::GetNextHandle( UtlHashHandle_t handle ) const -{ - ++handle; // start at the first possible handle after the one given - - int bi = GetBucketIndex( handle ); - int ki = GetKeyDataIndex( handle ); - - int nBuckets = m_Buckets.Count(); - for ( ; bi < nBuckets; ++bi ) - { - if ( ki < m_Buckets[ bi ].Count() ) - return BuildHandle( bi, ki ); - - ki = 0; - } - - return InvalidHandle(); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline void CUtlHash::Log( const char *filename ) -{ - FILE *pDebugFp; - pDebugFp = fopen( filename, "w" ); - if( !pDebugFp ) - return; - - int maxBucketSize = 0; - int numBucketsEmpty = 0; - - int bucketCount = m_Buckets.Count(); - fprintf( pDebugFp, "\n%d Buckets\n", bucketCount ); - - for( int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++ ) - { - int count = m_Buckets[ndxBucket].Count(); - - if( count > maxBucketSize ) { maxBucketSize = count; } - if( count == 0 ) - numBucketsEmpty++; - - fprintf( pDebugFp, "Bucket %d: %d\n", ndxBucket, count ); - } - - fprintf( pDebugFp, "\nBucketHeads Used: %d\n", bucketCount - numBucketsEmpty ); - fprintf( pDebugFp, "Max Bucket Size: %d\n", maxBucketSize ); - - fclose( pDebugFp ); -} - -//============================================================================= -// -// Fast Hash -// -// Number of buckets must be a power of 2. -// Key must be 32-bits (unsigned int). -// -typedef int UtlHashFastHandle_t; - -#define UTLHASH_POOL_SCALAR 2 - -class CUtlHashFastNoHash -{ -public: - static int Hash( int key, int bucketMask ) - { - return ( key & bucketMask ); - } -}; - -class CUtlHashFastGenericHash -{ -public: - static int Hash( int key, int bucketMask ) - { - return ( HashIntConventional( key ) & bucketMask ); - } -}; - -template -class CUtlHashFast -{ -public: - - // Constructor/Deconstructor. - CUtlHashFast(); - ~CUtlHashFast(); - - // Memory. - void Purge( void ); - - // Invalid handle. - static UtlHashFastHandle_t InvalidHandle( void ) { return ( UtlHashFastHandle_t )~0; } - - // Initialize. - bool Init( int nBucketCount ); - - // Size. - int Count( void ); - - // Insertion. - UtlHashFastHandle_t Insert( unsigned int uiKey, const Data &data ); - UtlHashFastHandle_t FastInsert( unsigned int uiKey, const Data &data ); - - // Removal. - void Remove( UtlHashFastHandle_t hHash ); - void RemoveAll( void ); - - // Retrieval. - UtlHashFastHandle_t Find( unsigned int uiKey ); - - Data &Element( UtlHashFastHandle_t hHash ); - Data const &Element( UtlHashFastHandle_t hHash ) const; - Data &operator[]( UtlHashFastHandle_t hHash ); - Data const &operator[]( UtlHashFastHandle_t hHash ) const; - -//protected: - - // Templatized for memory tracking purposes - template - struct HashFastData_t_ - { - unsigned int m_uiKey; - HashData m_Data; - }; - - typedef HashFastData_t_ HashFastData_t; - - unsigned int m_uiBucketMask; - CUtlVector m_aBuckets; - CUtlFixedLinkedList m_aDataPool; -}; - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -template CUtlHashFast::CUtlHashFast() -{ - Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Deconstructor -//----------------------------------------------------------------------------- -template CUtlHashFast::~CUtlHashFast() -{ - Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Destroy dynamically allocated hash data. -//----------------------------------------------------------------------------- -template inline void CUtlHashFast::Purge( void ) -{ - m_aBuckets.Purge(); - m_aDataPool.Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Initialize the hash - set bucket count and hash grow amount. -//----------------------------------------------------------------------------- -template bool CUtlHashFast::Init( int nBucketCount ) -{ - // Verify the bucket count is power of 2. - if ( !IsPowerOfTwo( nBucketCount ) ) - return false; - - // Set the bucket size. - m_aBuckets.SetSize( nBucketCount ); - for ( int iBucket = 0; iBucket < nBucketCount; ++iBucket ) - { - m_aBuckets[iBucket] = m_aDataPool.InvalidIndex(); - } - - // Set the mod mask. - m_uiBucketMask = nBucketCount - 1; - - // Calculate the grow size. - int nGrowSize = UTLHASH_POOL_SCALAR * nBucketCount; - m_aDataPool.SetGrowSize( nGrowSize ); - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: Return the number of elements in the hash. -//----------------------------------------------------------------------------- -template inline int CUtlHashFast::Count( void ) -{ - return m_aDataPool.Count(); -} - -//----------------------------------------------------------------------------- -// Purpose: Insert data into the hash table given its key (unsigned int), with -// a check to see if the element already exists within the tree. -//----------------------------------------------------------------------------- -template inline UtlHashFastHandle_t CUtlHashFast::Insert( unsigned int uiKey, const Data &data ) -{ - // Check to see if that key already exists in the buckets (should be unique). - UtlHashFastHandle_t hHash = Find( uiKey ); - if( hHash != InvalidHandle() ) - return hHash; - - return FastInsert( uiKey, data ); -} - -//----------------------------------------------------------------------------- -// Purpose: Insert data into the hash table given its key (unsigned int), -// without a check to see if the element already exists within the tree. -//----------------------------------------------------------------------------- -template inline UtlHashFastHandle_t CUtlHashFast::FastInsert( unsigned int uiKey, const Data &data ) -{ - // Get a new element from the pool. - int iHashData = m_aDataPool.Alloc( true ); - HashFastData_t *pHashData = &m_aDataPool[iHashData]; - if ( !pHashData ) - return InvalidHandle(); - - // Add data to new element. - pHashData->m_uiKey = uiKey; - pHashData->m_Data = data; - - // Link element. - int iBucket = HashFuncs::Hash( uiKey, m_uiBucketMask ); - m_aDataPool.LinkBefore( m_aBuckets[iBucket], iHashData ); - m_aBuckets[iBucket] = iHashData; - - return iHashData; -} - -//----------------------------------------------------------------------------- -// Purpose: Remove a given element from the hash. -//----------------------------------------------------------------------------- -template inline void CUtlHashFast::Remove( UtlHashFastHandle_t hHash ) -{ - int iBucket = HashFuncs::Hash( m_aDataPool[hHash].m_uiKey, m_uiBucketMask ); - if ( m_aBuckets[iBucket] == hHash ) - { - // It is a bucket head. - m_aBuckets[iBucket] = m_aDataPool.Next( hHash ); - } - else - { - // Not a bucket head. - m_aDataPool.Unlink( hHash ); - } - - // Remove the element. - m_aDataPool.Remove( hHash ); -} - -//----------------------------------------------------------------------------- -// Purpose: Remove all elements from the hash -//----------------------------------------------------------------------------- -template inline void CUtlHashFast::RemoveAll( void ) -{ - m_aBuckets.RemoveAll(); - m_aDataPool.RemoveAll(); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template inline UtlHashFastHandle_t CUtlHashFast::Find( unsigned int uiKey ) -{ - // hash the "key" - get the correct hash table "bucket" - int iBucket = HashFuncs::Hash( uiKey, m_uiBucketMask ); - - for ( int iElement = m_aBuckets[iBucket]; iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next( iElement ) ) - { - if ( m_aDataPool[iElement].m_uiKey == uiKey ) - return iElement; - } - - return InvalidHandle(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data &CUtlHashFast::Element( UtlHashFastHandle_t hHash ) -{ - return ( m_aDataPool[hHash].m_Data ); -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data const &CUtlHashFast::Element( UtlHashFastHandle_t hHash ) const -{ - return ( m_aDataPool[hHash].m_Data ); -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data &CUtlHashFast::operator[]( UtlHashFastHandle_t hHash ) -{ - return ( m_aDataPool[hHash].m_Data ); -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data const &CUtlHashFast::operator[]( UtlHashFastHandle_t hHash ) const -{ - return ( m_aDataPool[hHash].m_Data ); -} - -//============================================================================= -// -// Fixed Hash -// -// Number of buckets must be a power of 2. -// Key must be 32-bits (unsigned int). -// -typedef int UtlHashFixedHandle_t; - -template -class CUtlHashFixedGenericHash -{ -public: - static int Hash( int key, int bucketMask ) - { - int hash = HashIntConventional( key ); - if ( NUM_BUCKETS <= USHRT_MAX ) - { - hash ^= ( hash >> 16 ); - } - if ( NUM_BUCKETS <= UCHAR_MAX ) - { - hash ^= ( hash >> 8 ); - } - return ( hash & bucketMask ); - } -}; - -template -class CUtlHashFixed -{ -public: - - // Constructor/Deconstructor. - CUtlHashFixed(); - ~CUtlHashFixed(); - - // Memory. - void Purge( void ); - - // Invalid handle. - static UtlHashFixedHandle_t InvalidHandle( void ) { return ( UtlHashFixedHandle_t )~0; } - - // Size. - int Count( void ); - - // Insertion. - UtlHashFixedHandle_t Insert( unsigned int uiKey, const Data &data ); - UtlHashFixedHandle_t FastInsert( unsigned int uiKey, const Data &data ); - - // Removal. - void Remove( UtlHashFixedHandle_t hHash ); - void RemoveAll( void ); - - // Retrieval. - UtlHashFixedHandle_t Find( unsigned int uiKey ); - - Data &Element( UtlHashFixedHandle_t hHash ); - Data const &Element( UtlHashFixedHandle_t hHash ) const; - Data &operator[]( UtlHashFixedHandle_t hHash ); - Data const &operator[]( UtlHashFixedHandle_t hHash ) const; - - //protected: - - // Templatized for memory tracking purposes - template - struct HashFixedData_t_ - { - unsigned int m_uiKey; - Data_t m_Data; - }; - - typedef HashFixedData_t_ HashFixedData_t; - - enum - { - BUCKET_MASK = NUM_BUCKETS - 1 - }; - CUtlPtrLinkedList m_aBuckets[NUM_BUCKETS]; - int m_nElements; -}; - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -template CUtlHashFixed::CUtlHashFixed() -{ - Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Deconstructor -//----------------------------------------------------------------------------- -template CUtlHashFixed::~CUtlHashFixed() -{ - Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Destroy dynamically allocated hash data. -//----------------------------------------------------------------------------- -template inline void CUtlHashFixed::Purge( void ) -{ - RemoveAll(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return the number of elements in the hash. -//----------------------------------------------------------------------------- -template inline int CUtlHashFixed::Count( void ) -{ - return m_nElements; -} - -//----------------------------------------------------------------------------- -// Purpose: Insert data into the hash table given its key (unsigned int), with -// a check to see if the element already exists within the tree. -//----------------------------------------------------------------------------- -template inline UtlHashFixedHandle_t CUtlHashFixed::Insert( unsigned int uiKey, const Data &data ) -{ - // Check to see if that key already exists in the buckets (should be unique). - UtlHashFixedHandle_t hHash = Find( uiKey ); - if( hHash != InvalidHandle() ) - return hHash; - - return FastInsert( uiKey, data ); -} - -//----------------------------------------------------------------------------- -// Purpose: Insert data into the hash table given its key (unsigned int), -// without a check to see if the element already exists within the tree. -//----------------------------------------------------------------------------- -template inline UtlHashFixedHandle_t CUtlHashFixed::FastInsert( unsigned int uiKey, const Data &data ) -{ - int iBucket = HashFuncs::Hash( uiKey, NUM_BUCKETS - 1 ); - UtlPtrLinkedListIndex_t iElem = m_aBuckets[iBucket].AddToHead(); - - HashFixedData_t *pHashData = &m_aBuckets[iBucket][iElem]; - - Assert( (UtlPtrLinkedListIndex_t)pHashData == iElem ); - - // Add data to new element. - pHashData->m_uiKey = uiKey; - pHashData->m_Data = data; - - m_nElements++; - return (UtlHashFixedHandle_t)pHashData; -} - -//----------------------------------------------------------------------------- -// Purpose: Remove a given element from the hash. -//----------------------------------------------------------------------------- -template inline void CUtlHashFixed::Remove( UtlHashFixedHandle_t hHash ) -{ - HashFixedData_t *pHashData = (HashFixedData_t *)hHash; - Assert( Find(pHashData->m_uiKey) != InvalidHandle() ); - int iBucket = HashFuncs::Hash( pHashData->m_uiKey, NUM_BUCKETS - 1 ); - m_aBuckets[iBucket].Remove( (UtlPtrLinkedListIndex_t)pHashData ); - m_nElements--; -} - -//----------------------------------------------------------------------------- -// Purpose: Remove all elements from the hash -//----------------------------------------------------------------------------- -template inline void CUtlHashFixed::RemoveAll( void ) -{ - for ( int i = 0; i < NUM_BUCKETS; i++ ) - { - m_aBuckets[i].RemoveAll(); - } - m_nElements = 0; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template inline UtlHashFixedHandle_t CUtlHashFixed::Find( unsigned int uiKey ) -{ - int iBucket = HashFuncs::Hash( uiKey, NUM_BUCKETS - 1 ); - CUtlPtrLinkedList &bucket = m_aBuckets[iBucket]; - - for ( UtlPtrLinkedListIndex_t iElement = bucket.Head(); iElement != bucket.InvalidIndex(); iElement = bucket.Next( iElement ) ) - { - if ( bucket[iElement].m_uiKey == uiKey ) - return (UtlHashFixedHandle_t)iElement; - } - - return InvalidHandle(); -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data &CUtlHashFixed::Element( UtlHashFixedHandle_t hHash ) -{ - return ((HashFixedData_t *)hHash)->m_Data; -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data const &CUtlHashFixed::Element( UtlHashFixedHandle_t hHash ) const -{ - return ((HashFixedData_t *)hHash)->m_Data; -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data &CUtlHashFixed::operator[]( UtlHashFixedHandle_t hHash ) -{ - return ((HashFixedData_t *)hHash)->m_Data; -} - -//----------------------------------------------------------------------------- -// Purpose: Return data given a hash handle. -//----------------------------------------------------------------------------- -template inline Data const &CUtlHashFixed::operator[]( UtlHashFixedHandle_t hHash ) const -{ - return ((HashFixedData_t *)hHash)->m_Data; -} - -#endif // UTLHASH_H diff --git a/Resources/NetHook/tier1/utlhashdict.h b/Resources/NetHook/tier1/utlhashdict.h deleted file mode 100644 index 4826b673..00000000 --- a/Resources/NetHook/tier1/utlhashdict.h +++ /dev/null @@ -1,342 +0,0 @@ -//========== Copyright © 2005, Valve Corporation, All rights reserved. ======== -// -// Purpose: -// -//============================================================================= - -#ifndef UTLHASHDICT_H -#define UTLHASHDICT_H - -#if defined( _WIN32 ) -#pragma once -#endif - -#include "tier1/utlhash.h" -#include "tier1/generichash.h" -#include "mathlib/mathlib.h" - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -template -class CUtlHashDict -{ -public: - // constructor, destructor - CUtlHashDict( int bucketCount = 16, int growCount = 0, int initCount = 0 ); - ~CUtlHashDict( ); - - // gets particular elements - T& Element( unsigned i ); - const T& Element( unsigned i ) const; - T& operator[]( unsigned i ); - const T& operator[]( unsigned i ) const; - - // gets element names - char const *GetElementName( unsigned i ) const; - - // Number of elements - int Count() const; - - // Checks if a node is valid and in the tree - bool IsValidIndex( unsigned i ) const; - - // Invalid index - static unsigned InvalidHandle(); - - // Insert method (inserts in order) - unsigned Insert( const char *pName, const T &element ); - unsigned Insert( const char *pName ); - - // Find method - unsigned Find( const char *pName ) const; - - // Remove methods - void RemoveAt( unsigned i ); - void Remove( const char *pName ); - void RemoveAll( ); - - // Purge memory - void Purge(); - void PurgeAndDeleteElements(); // Call delete on each element. - - // Iteration methods - unsigned First() const; - unsigned Next( unsigned i ) const; - -protected: - struct Entry_t - { - const char *pszSymbol; - T value; - }; - - template - class CCompare - { - public: - CCompare( int ignored ) {} - - bool operator()( const Entry_t &entry1, const Entry_t &entry2 ) const - { - return !( ( bCaseInsensitive ) ? stricmp( entry1.pszSymbol, entry2.pszSymbol ) : strcmp( entry1.pszSymbol, entry2.pszSymbol ) ); - } - }; - - template - class CHash - { - public: - CHash( int ignored ) {} - - unsigned operator()( const Entry_t &entry ) const - { - return !( ( bCaseInsensitive ) ? HashStringCaseless( entry.pszSymbol ) : HashString( entry.pszSymbol ) ); - } - }; - - typedef CUtlHash, CHash > CHashTable; - CHashTable m_Elements; - int m_nCount; -}; - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template -CUtlHashDict::CUtlHashDict( int bucketCount = 16, int growCount = 0, int initCount = 0 ) : - m_Elements( SmallestPowerOfTwoGreaterOrEqual(bucketCount), growCount, initCount ) -{ - Assert( SmallestPowerOfTwoGreaterOrEqual(bucketCount) <= 0xffff ); -} - -template -CUtlHashDict::~CUtlHashDict() -{ - Purge(); -} - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- -template -inline T& CUtlHashDict::Element( unsigned i ) -{ - return m_Elements[i].value; -} - -template -inline const T& CUtlHashDict::Element( unsigned i ) const -{ - return m_Elements[i].value; -} - -//----------------------------------------------------------------------------- -// gets element names -//----------------------------------------------------------------------------- -template -inline char const *CUtlHashDict::GetElementName( unsigned i ) const -{ - return m_Elements[i].pszSymbol; -} - -template -inline T& CUtlHashDict::operator[]( unsigned i ) -{ - return m_Elements[i].value; -} - -template -inline const T & CUtlHashDict::operator[]( unsigned i ) const -{ - return m_Elements[i].value; -} - -//----------------------------------------------------------------------------- -// Num elements -//----------------------------------------------------------------------------- -template -inline int CUtlHashDict::Count() const -{ - Assert( m_nCount == m_Elements.Count() ); - return m_nCount; -} - - -//----------------------------------------------------------------------------- -// Checks if a node is valid and in the tree -//----------------------------------------------------------------------------- -template -inline bool CUtlHashDict::IsValidIndex( unsigned i ) const -{ - return m_Elements.IsValidHandle(i); -} - - -//----------------------------------------------------------------------------- -// Invalid index -//----------------------------------------------------------------------------- -template -inline unsigned CUtlHashDict::InvalidHandle() -{ - return CHashTable::InvalidHandle(); -} - - -//----------------------------------------------------------------------------- -// Delete a node from the tree -//----------------------------------------------------------------------------- -template -void CUtlHashDict::RemoveAt(unsigned elem) -{ - if ( bDupeStrings ) - { - free( (void *)m_Elements[elem].pszSymbol ); - } - m_Elements.Remove(elem); - m_nCount--; -} - - -//----------------------------------------------------------------------------- -// remove a node in the tree -//----------------------------------------------------------------------------- -template void CUtlHashDict::Remove( const char *search ) -{ - unsigned node = Find( search ); - if (node != InvalidHandle()) - { - RemoveAt(node); - } -} - - -//----------------------------------------------------------------------------- -// Removes all nodes from the tree -//----------------------------------------------------------------------------- -template -void CUtlHashDict::RemoveAll() -{ - if ( bDupeStrings ) - { - typename UtlHashHandle_t index = m_Elements.GetFirstHandle(); - while ( index != m_Elements.InvalidHandle() ) - { - free( (void *)m_Elements[index].pszSymbol ); - index = m_Elements.GetNextHandle( index ); - } - } - - m_Elements.RemoveAll(); - m_nCount = 0; -} - -template -void CUtlHashDict::Purge() -{ - if ( bDupeStrings ) - { - typename UtlHashHandle_t index = m_Elements.GetFirstHandle(); - while ( index != m_Elements.InvalidHandle() ) - { - free( (void *)m_Elements[index].pszSymbol ); - index = m_Elements.GetNextHandle( index ); - } - } - - m_Elements.Purge(); - m_nCount = 0; -} - - -template -void CUtlHashDict::PurgeAndDeleteElements() -{ - // Delete all the elements. - unsigned index = m_Elements.GetFirstHandle(); - while ( index != m_Elements.InvalidHandle() ) - { - if ( bDupeStrings ) - { - free( (void *)m_Elements[index].pszSymbol ); - } - delete m_Elements[index].value; - index = m_Elements.GetNextHandle( index ); - } - - m_Elements.RemoveAll(); - m_nCount = 0; -} - - -//----------------------------------------------------------------------------- -// inserts a node into the tree -//----------------------------------------------------------------------------- -template -unsigned CUtlHashDict::Insert( const char *pName, const T &element ) -{ - MEM_ALLOC_CREDIT_CLASS(); - m_nCount++; - Entry_t entry = - { - (bDupeStrings) ? strdup( pName ) : pName, - element - }; - bool bInserted; - unsigned result = m_Elements.Insert( entry, &bInserted ); - if ( bDupeStrings && !bInserted ) - { - free( (void *)entry.pszSymbol ); - } - return result; -} - -template -unsigned CUtlHashDict::Insert( const char *pName ) -{ - MEM_ALLOC_CREDIT_CLASS(); - m_nCount++; - Entry_t entry = - { - (bDupeStrings) ? strdup( pName ) : pName - }; - bool bInserted; - unsigned result = m_Elements.Insert( entry, &bInserted ); - if ( bDupeStrings && !bInserted ) - { - free( (void *)entry.pszSymbol ); - } - return result; -} - - -//----------------------------------------------------------------------------- -// finds a node in the tree -//----------------------------------------------------------------------------- -template -unsigned CUtlHashDict::Find( const char *pName ) const -{ - MEM_ALLOC_CREDIT_CLASS(); - if ( pName ) - return m_Elements.Find( *((Entry_t *)&pName) ); - else - return InvalidHandle(); -} - - -//----------------------------------------------------------------------------- -// Iteration methods -//----------------------------------------------------------------------------- -template -unsigned CUtlHashDict::First() const -{ - return m_Elements.GetFirstHandle(); -} - -template -unsigned CUtlHashDict::Next( unsigned i ) const -{ - return m_Elements.GetNextHandle(i); -} - -#endif // UTLHASHDICT_H diff --git a/Resources/NetHook/tier1/utlintrusivelist.h b/Resources/NetHook/tier1/utlintrusivelist.h deleted file mode 100644 index a09ac7bb..00000000 --- a/Resources/NetHook/tier1/utlintrusivelist.h +++ /dev/null @@ -1,772 +0,0 @@ -//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======// -// -// Purpose: Intrusive linked list templates, both for singly and doubly linked lists -// -// $Revision: $ -// $NoKeywords: $ -//===========================================================================// - -#ifndef UTILINTRUSIVELIST_H -#define UTILINTRUSIVELIST_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "basetypes.h" -#include "utlmemory.h" -#include "tier0/dbg.h" - - -// -// These templates are used for intrusive linked list classes. Intrusive linked list templates -// force the structs and classes contained within them to have their own m_pNext, (optionally), -// m_pPrev, and other fileds contained within. All memory management is up to the caller and -// their classes. No data will ever be copied. Nodes can only exist on one list at a time, because -// of only having on m_Next field, and manipulating the list while walking it requires that care on -// the part of the caller. All accessing and searching functions work by passing and returning -// pointers. -// -// -// -// naming and field conventions: -// functions referring to a DList are for doubly linked lists. nodes must have m_pHead and -// m_pPrev pointer fields. -// Functions using Priority require an m_Priority field, which must be comparable. -// -// Some functions are meanto for use with lists which maintain both a head and tail pointer -// in order to support fast adding to the end. - - -/// validates that the doubly linked list has the proper structure, pointer-wise - -namespace IntrusiveList -{ -#ifdef SUPERSLOW_DEBUG_VERSION - template inline void ValidateDList(T *head) - { - if (head) - { - Assert(head->m_pPrev==0); - } - while(head) - { - if (head->m_pNext) - { - Assert(head->m_pNext->m_pPrev==head); - } - if (head->m_pPrev) - { - Assert(head->m_pPrev->m_pNext==head); - } - head=head->m_pNext; - } - } -#else - template inline void ValidateDList(T * /*head*/) - { - } -#endif - - - -// move a node in a doubly linked list backwards one step. - template inline void MoveDNodeBackwards( T *which, T * &head) - { - if (which->m_pPrev) - { - T *p=which->m_pPrev; - T *pp=p->m_pPrev; - T *n=which->m_pNext; - Assert(p->m_pNext == which); - if (n) - { - Assert(n->m_pPrev==which); - n->m_pPrev=p; - } - if (pp) - { - Assert(pp->m_pNext==p); - pp->m_pNext=which; - } - else - { - head=which; // this node is the new root! - } - which->m_pNext=p; - which->m_pPrev=pp; - p->m_pNext=n; - p->m_pPrev=which; - } - ValidateDList(head); - } - - - - // removes node 'which' from doubly linked list with 'head' - template inline void RemoveFromDList(T * &head, T *which) - { - if (which->m_pPrev) - { - Assert(which->m_pPrev->m_pNext==which); - which->m_pPrev->m_pNext=which->m_pNext; - if (which->m_pNext) - { - Assert(which->m_pNext->m_pPrev==which); - which->m_pNext->m_pPrev=which->m_pPrev; - } - } - else - { - if (head==which) - { - head=which->m_pNext; - if (head) - { - Assert(head->m_pPrev==which); - head->m_pPrev=0; - } - } - } - which->m_pNext=which->m_pPrev=0; - ValidateDList(head); - - } - - //checks to see if node is in doubly linked list - template bool OnDList(T const *head, T const *which) - { - return (head==which) || (which->m_pNext !=0) || (which->m_pPrev !=0); - } - - // add a node to the end of a singly linked list - template void AddToDTail(T * & head, T * node) - { - node->m_pNext=0; - if (! head) - { - head=node; - } - else - { - T *ptr=head; - while(ptr->m_pNext) - { - ptr=ptr->m_pNext; - } - ptr->m_pNext=node; - node->m_pPrev=ptr; // - } - } - - // add a node to end of doubly linked list. - template inline void AddToDHead(T * &head, T *which) - { - which->m_pNext=head; - if (head) - { - head->m_pPrev=which; - } - which->m_pPrev=0; - head=which; - ValidateDList(head); - } - - // add a node to front of doubly linked list which maintains a tail ptr - template inline void AddToDHeadWithTailPtr(T * &head, T *which, T * &tailptr) - { - which->m_pNext=head; - if (head) - { - head->m_pPrev=which; - } - else - { - tailptr=which; - } - which->m_pPrev=0; - head=which; - ValidateDList(head); - } - - // add a node to end of doubly linked list which maintains a tail ptr - template inline void AddToDTailWithTailPtr(T * &head, T *which, T * & tailptr) - { - if (! tailptr) - { - Assert(! head); - which->m_pPrev=which->m_pNext=0; - tailptr=head=which; - } - else - { - which->m_pNext=0; - which->m_pPrev=tailptr; - tailptr->m_pNext=which; - tailptr=which; - } - } - - // Remove a node from a dlist , maintaining the tail ptr. node is not 'delete' d - template inline void RemoveFromDListWithTailPtr(T * &head, T *which, T * & tailptr) - { - if (which==tailptr) - { - tailptr=which->m_pPrev; - } - if (which->m_pPrev) - { - Assert(which->m_pPrev->m_pNext==which); - which->m_pPrev->m_pNext=which->m_pNext; - if (which->m_pNext) - { - Assert(which->m_pNext->m_pPrev==which); - which->m_pNext->m_pPrev=which->m_pPrev; - } - } - else - { - if (head==which) - { - head=which->m_pNext; - if (head) - { - Assert(head->m_pPrev==which); - head->m_pPrev=0; - } - } - } - which->m_pNext=which->m_pPrev=0; - ValidateDList(head); - - } - - // this function removes a node, and delete's the node - template inline void DeleteFromDListWithTailPtr(T * &head, T *which, T * & tailptr) - { - T *tmp=which; - if (which==tailptr) - { - tailptr=which->m_pPrev; - } - if (which->m_pPrev) - { - Assert(which->m_pPrev->m_pNext==which); - which->m_pPrev->m_pNext=which->m_pNext; - if (which->m_pNext) - { - Assert(which->m_pNext->m_pPrev==which); - which->m_pNext->m_pPrev=which->m_pPrev; - } - } - else - { - if (head==which) - { - head=which->m_pNext; - if (head) - { - Assert(head->m_pPrev==which); - head->m_pPrev=0; - } - } - } - which->m_pNext=which->m_pPrev=0; - delete tmp; - ValidateDList(head); - } - - // Add a node to a d-list, keeping the highest priority nodes first. This is a simple - // linear search to insert, NOT a O(logn) heap. - template inline void AddToDPriority(T * &head, T *which) - { - T* prevnode=0; - for(T *curnode=head;curnode;curnode=curnode->m_pNext) - { - if (which->m_Priority>=curnode->m_Priority) - break; - prevnode=curnode; - } - // now, we have either run out of list, or we have found an - // element to add this one before - if (! prevnode) - { - AddToDHead(head,which); - } - else - { - which->m_pNext=prevnode->m_pNext; - prevnode->m_pNext=which; - which->m_pPrev=prevnode; - if (which->m_pNext) - which->m_pNext->m_pPrev=which; - } - } - - // same as AddToDPriority, except with reverse order - template inline void AddToDPriorityLowestFirst(T * &head, T *which) - { - T* prevnode=0; - for(T *curnode=head;curnode;curnode=curnode->m_pNext) - { - if (which->m_Priority<=curnode->m_Priority) - break; - prevnode=curnode; - } - // now, we have either run out of list, or we have found an - // element to add this one before - if (! prevnode) - { - AddToDHead(head,which); - } - else - { - which->m_pNext=prevnode->m_pNext; - prevnode->m_pNext=which; - which->m_pPrev=prevnode; - if (which->m_pNext) - which->m_pNext->m_pPrev=which; - } - } - - - // return a pointer to the last node in a singly-linked (or doubly) list - template T * LastNode(T * head) - { - if (head) - { - while(head->m_pNext) - { - head=head->m_pNext; - } - } - return head; - } - - - // Remove from a singly linked list. no delete called. - template void RemoveFromList(T * & head, V *which) - { - if (head==which) - { - head=which->m_pNext; - } - else - { - for(T * i=head; i; i=i->m_pNext) - { - if (i->m_pNext==which) - { - i->m_pNext=which->m_pNext; - return; - } - } - } - } - - // same as RemoveFromList, but 'delete' is called. - template void DeleteFromList(T * & head, V *which) - { - T *tmp; - if (head==which) - { - tmp=which->m_pNext; - delete(head); - head=tmp; - } - else - { - for(T * i=head; i; i=i->m_pNext) - { - if (i->m_pNext==which) - { - tmp=which->m_pNext; - delete(which); - i->m_pNext=tmp; - return; - } - } - } - } - - // find the position in a list of a node. -1 if not found. Linear search. - // nodes must have comparison functions - template int PositionInList(T *head, V *node) - { - int pos=0; - while(head) - { - if (head==node) return pos; - head=head->m_pNext; - pos++; - } - return -1; - } - - // find the Nth node in a list. null if index too high. - template T *NthNode(T * head, int idx) - { - while(idx && head) - { - idx--; - head=head->m_pNext; - } - return head; - } - - //Add a node to the head of a singly-linked - // Note that the head var passed to this will be modified. - template static inline void AddToHead(T * & head, V * node) - { - node->m_pNext=head; - head=node; - } - - //Add a node to the tail of a singly-linked. Not fast - // Note that the head var passed to this will be modified. - template static inline void AddToTail(T * & head, V * node) - { - node->m_pNext = NULL; - if ( ! head ) - head = node; - else - { - T *pLastNode = head; - while( pLastNode->m_pNext ) - pLastNode = pLastNode->m_pNext; - pLastNode->m_pNext = node; - } - } - - //Add a node to the head of a singly-linked list, maintaining a tail pointer - template static inline void AddToHead(T * & head, T * &tail,V * node) - { - if (! head) - { - tail=node; - } - node->m_pNext=head; - head=node; - } - - - - // return the node in head before in a singly linked list. returns null if head is empty, n is - // null, or if n is the first node. not fast. - template static inline T * PrevNode(T *head, T *node) - { - for(T *i=head;i;i=i->m_pNext) - { - if (i->m_pNext == node) - break; - } - return i; - } - - - // add a node to the end of a singly linked list. Not fast. - template void AddToEnd(T * & head, V * node) - { - node->m_pNext=0; - if (! head) - { - head=node; - } - else - { - T *ptr=head; - while(ptr->m_pNext) - { - ptr=ptr->m_pNext; - } - ptr->m_pNext=node; - } - } - - // add a node to the end of a singly linked list, maintaining a tail pointer. - // the head and tail pointer can be modified by this routine. - template void AddToEndWithTail(T * & head, T * & tail,V * node) - { - Assert((head && tail) || ((!head) && (!tail))); - node->m_pNext=0; - if (! head) - { - head=tail=node; - } - else - { - tail->m_pNext=node; - tail=node; - } - } - - // Add a node to a singly linked list, sorting by the m_Name field - template void AddSortedByName(T * & head, T * node) - { - if ( (! head) || // empty list? - (stricmp(node->m_Name,head->m_Name)==-1)) // or we should be first? - { - node->m_pNext=head; // make us head - head=node; - } - else - { - for(T *t=head;t->m_pNext;t=t->m_pNext) // find the node we should be before - if (stricmp(t->m_pNext->m_Name,node->m_Name)>=0) - break; - node->m_pNext=t->m_pNext; - t->m_pNext=node; - } - } - - // count # of elements in list - template int ListLength(T *head) - { - int len=0; - while(head) - { - len++; - head=head->m_pNext; - } - return len; - } - - // this will kill a list if the list is of objects which automatically - // remove themselves from the list when delete is called - template void KillList(T * & head) - { - while(head) - { - delete head; - } - } - - - // this will kill all elements in a list if - // the elements are of a type which does NOT remove itself from - // the list when the destructor is called. - template void DeleteList(T * & head) - { - while (head) - { - T* tmp=head->m_pNext; - delete head; - head=tmp; - } - } - - // find a named node in any list which has both a Next field and a Name field. - template static inline T * FindNamedNode(T * head, char const *name) - { - for(;head && stricmp(head->m_Name,name); head=head->m_pNext) - { - } - return head; - } - - template static inline T * FindNamedNodeCaseSensitive(T * head, char const *name) - { - for(;head && strcmp(head->m_Name,name); head=head->m_pNext) - { - } - return head; - } - - // find data in a singly linked list, using equality match on any field - // usage: FindNodeByField(listptr,data,&list::fieldname) - template static inline T * FindNodeByField(T * head, U data, U V::*field) - { - while(head) - { - if (data==(*head).*field) - return head; - head=head->m_pNext; - } - return 0; - } - - // find a node and its predecessor, matching on equality of a given field. - // usage: FindNodeByFieldWithPrev(listptr,data,&list::fieldname, prevptr) - template static inline T * FindNodeByFieldWithPrev(T * head, U data, U V::*field, T * & prev) - { - prev=0; - for(T *i=head; i; i=i->m_pNext) - { - if(data==(*i).*field) - return i; - prev=i; - } - prev=0; - return 0; - } - - - /// sort a list. comparefn should return 0 if the items are equal, 1 if A goes first, and -1 if A goes last. - // NOT fast. - template void SortList(T * &head, int (*comparefn)(T * a, T * b)) - { - int didswap=1; - while(didswap) - { - didswap=0; - T *prev=0; - for(T *i=head;i && i->m_pNext; i=i->m_pNext) - { - /// compare i and i+1 - int rslt=(*comparefn)(i,i->m_pNext); - if (rslt==-1) - { - /// need to swap - didswap=1; - T *newfirst=i->m_pNext; - if (prev) - { - prev->m_pNext=newfirst; - i->m_pNext=newfirst->m_pNext; - newfirst->m_pNext=i; - } - else - { - head=i->m_pNext; - i->m_pNext=newfirst->m_pNext; - newfirst->m_pNext=i; - } - i=newfirst; - } - prev=i; - } - } - } - - // sort a doubly linked list. NOt fast. - template void SortDList(T * & head, int (*comparefn)(T * a, T * b)) - { - SortList(head,comparefn); - /// now, regen prev ptrs - T *prev=0; - for(T *i=head;i;i=i->m_pNext) - { - i->m_pPrev=prev; - prev=i; - } - } - - // reverse a singly linked list. not recommended for anything other than valve programming - // interview :-) - template T *ReversedList( T * head ) - { - T * pNewHead=NULL; - while( head ) - { - T *pNext=head->m_pNext; -#ifdef INTERVIEW_QUESTION - head->m_pNext=pNewHead; - pNewHead = head; -#else - AddToHead( pNewHead, head ); -#endif - head = pNext; - } - return pNewHead; - } -}; - -// singly linked list -template class CUtlIntrusiveList -{ -public: - T *m_pHead; - - FORCEINLINE CUtlIntrusiveList(void) - { - m_pHead = NULL; - } - - FORCEINLINE void AddToHead( T * node ) - { - IntrusiveList::AddToHead( m_pHead, node ); - } - - FORCEINLINE void AddToTail( T * node ) - { - IntrusiveList::AddToTail( m_pHead, node ); - } - - void RemoveNode(T *which) - { - IntrusiveList::RemoveFromList( m_pHead, which ); - } - - // this will kill a list if the list is of objects which automatically - // remove themselves from the list when delete is called - void KillList( void ) - { - while(m_pHead) - { - delete m_pHead; - } - } - - - // return the node in head before in a singly linked list. returns null if head is empty, n is - // null, or if n is the first node. not fast. Fast for dlists - T * PrevNode(T *node) - { - return IntrusiveList::PrevNode( m_pHead, node ); - } - - int NthNode( int n ) - { - return NthNode( m_pHead, n ); - } - - // this will kill all elements in a list if - // the elements are of a type which does NOT remove itself from - // the list when the destructor is called. - void Purge( void ) - { - while (m_pHead) - { - T* tmp=m_pHead->m_pNext; - delete m_pHead; - m_pHead=tmp; - } - } - - int Count( void ) - { - return IntrusiveList::ListLength( m_pHead ); - } - -}; - -// doubly linked list -template class CUtlIntrusiveDList : public CUtlIntrusiveList -{ -public: - - FORCEINLINE void AddToHead( T * node ) - { - IntrusiveList::AddToDHead( CUtlIntrusiveList::m_pHead, node ); - } - FORCEINLINE void AddToTail( T * node ) - { - IntrusiveList::AddToDTail( CUtlIntrusiveList::m_pHead, node ); - } - - void RemoveNode(T *which) - { - IntrusiveList::RemoveFromDList( CUtlIntrusiveList::m_pHead, which ); - } - - T * PrevNode(T *node) - { - return ( node )?node->m_Prev:NULL; - } - -}; - - - - -#endif diff --git a/Resources/NetHook/tier1/utllinkedlist.h b/Resources/NetHook/tier1/utllinkedlist.h deleted file mode 100644 index de87cebf..00000000 --- a/Resources/NetHook/tier1/utllinkedlist.h +++ /dev/null @@ -1,1018 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Linked list container class -// -// $Revision: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLLINKEDLIST_H -#define UTLLINKEDLIST_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/basetypes.h" -#include "utlmemory.h" -#include "utlfixedmemory.h" -#include "utlblockmemory.h" -#include "tier0/dbg.h" - - -// This is a useful macro to iterate from head to tail in a linked list. -#define FOR_EACH_LL( listName, iteratorName ) \ - for( int iteratorName=listName.Head(); iteratorName != listName.InvalidIndex(); iteratorName = listName.Next( iteratorName ) ) - -//----------------------------------------------------------------------------- -// class CUtlLinkedList: -// description: -// A lovely index-based linked list! T is the class type, I is the index -// type, which usually should be an unsigned short or smaller. However, -// you must avoid using 16- or 8-bit arithmetic on PowerPC architectures; -// therefore you should not use UtlLinkedListElem_t::I as the type of -// a local variable... ever. PowerPC integer arithmetic must be 32- or -// 64-bit only; otherwise performance plummets. -//----------------------------------------------------------------------------- - -template -struct UtlLinkedListElem_t -{ - T m_Element; - I m_Previous; - I m_Next; - -private: - // No copy constructor for these... - UtlLinkedListElem_t( const UtlLinkedListElem_t& ); -}; - - -// Class S is the storage type; the type you can use to save off indices in -// persistent memory. Class I is the iterator type, which is what should be used -// in local scopes. I defaults to be S, but be aware that on the 360, 16-bit -// arithmetic is catastrophically slow. Therefore you should try to save shorts -// in memory, but always operate on 32's or 64's in local scope. -// The ideal parameter order would be TSMI (you are more likely to override M than I) -// but since M depends on I we can't have the defaults in that order, alas. -template , I > > -class CUtlLinkedList -{ -public: - typedef T ElemType_t; - typedef S IndexType_t; // should really be called IndexStorageType_t, but that would be a huge change -typedef I IndexLocalType_t; - typedef M MemoryAllocator_t; - - // constructor, destructor - CUtlLinkedList( int growSize = 0, int initSize = 0 ); - ~CUtlLinkedList(); - - // gets particular elements - T& Element( I i ); - T const& Element( I i ) const; - T& operator[]( I i ); - T const& operator[]( I i ) const; - - // Make sure we have a particular amount of memory - void EnsureCapacity( int num ); - - void SetGrowSize( int growSize ); - - // Memory deallocation - void Purge(); - - // Delete all the elements then call Purge. - void PurgeAndDeleteElements(); - - // Insertion methods.... - I InsertBefore( I before ); - I InsertAfter( I after ); - I AddToHead( ); - I AddToTail( ); - - I InsertBefore( I before, T const& src ); - I InsertAfter( I after, T const& src ); - I AddToHead( T const& src ); - I AddToTail( T const& src ); - - // Find an element and return its index or InvalidIndex() if it couldn't be found. - I Find( const T &src ) const; - - // Look for the element. If it exists, remove it and return true. Otherwise, return false. - bool FindAndRemove( const T &src ); - - // Removal methods - void Remove( I elem ); - void RemoveAll(); - - // Allocation/deallocation methods - // If multilist == true, then list list may contain many - // non-connected lists, and IsInList and Head + Tail are meaningless... - I Alloc( bool multilist = false ); - void Free( I elem ); - - // list modification - void LinkBefore( I before, I elem ); - void LinkAfter( I after, I elem ); - void Unlink( I elem ); - void LinkToHead( I elem ); - void LinkToTail( I elem ); - - // invalid index - inline static S InvalidIndex() { return ( S )M::InvalidIndex(); } - inline static size_t ElementSize() { return sizeof( ListElem_t ); } - - // list statistics - int Count() const; - I MaxElementIndex() const; - - // Traversing the list - I Head() const; - I Tail() const; - I Previous( I i ) const; - I Next( I i ) const; - - // Are nodes in the list or valid? - bool IsValidIndex( I i ) const; - bool IsInList( I i ) const; - -protected: - - // What the linked list element looks like - typedef UtlLinkedListElem_t ListElem_t; - - // constructs the class - I AllocInternal( bool multilist = false ); - void ConstructList(); - - // Gets at the list element.... - ListElem_t& InternalElement( I i ) { return m_Memory[i]; } - ListElem_t const& InternalElement( I i ) const { return m_Memory[i]; } - - // copy constructors not allowed - CUtlLinkedList( CUtlLinkedList const& list ) { Assert(0); } - - M m_Memory; - I m_Head; - I m_Tail; - I m_FirstFree; - I m_ElementCount; // The number actually in the list - typename M::Iterator_t m_LastAlloc; // the last index allocated - - // For debugging purposes; - // it's in release builds so this can be used in libraries correctly - ListElem_t *m_pElements; - - FORCEINLINE M const &Memory( void ) const - { - return m_Memory; - } - - void ResetDbgInfo() - { - m_pElements = m_Memory.Base(); - } -}; - - -// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice -template < class T > -class CUtlFixedLinkedList : public CUtlLinkedList< T, int, true, int, CUtlFixedMemory< UtlLinkedListElem_t< T, int > > > -{ -public: - CUtlFixedLinkedList( int growSize = 0, int initSize = 0 ) - : CUtlLinkedList< T, int, true, int, CUtlFixedMemory< UtlLinkedListElem_t< T, int > > >( growSize, initSize ) {} - - bool IsValidIndex( int i ) const - { - if ( !Memory().IsIdxValid( i ) ) - return false; - -#ifdef _DEBUG // it's safe to skip this here, since the only way to get indices after m_LastAlloc is to use MaxElementIndex - if ( Memory().IsIdxAfter( i, this->m_LastAlloc ) ) - { - Assert( 0 ); - return false; // don't read values that have been allocated, but not constructed - } -#endif - - return ( Memory()[ i ].m_Previous != i ) || ( Memory()[ i ].m_Next == i ); - } - -private: - int MaxElementIndex() const { Assert( 0 ); return InvalidIndex(); } // fixedmemory containers don't support iteration from 0..maxelements-1 - void ResetDbgInfo() {} -}; - -// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice -template < class T, class I = unsigned short > -class CUtlBlockLinkedList : public CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > > -{ -public: - CUtlBlockLinkedList( int growSize = 0, int initSize = 0 ) - : CUtlLinkedList< T, I, true, I, CUtlBlockMemory< UtlLinkedListElem_t< T, I >, I > >( growSize, initSize ) {} -protected: - void ResetDbgInfo() {} -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template -CUtlLinkedList::CUtlLinkedList( int growSize, int initSize ) : - m_Memory( growSize, initSize ), m_LastAlloc( m_Memory.InvalidIterator() ) -{ - // Prevent signed non-int datatypes - COMPILE_TIME_ASSERT( sizeof(S) == 4 || ( ( (S)-1 ) > 0 ) ); - ConstructList(); - ResetDbgInfo(); -} - -template -CUtlLinkedList::~CUtlLinkedList( ) -{ - RemoveAll(); -} - -template -void CUtlLinkedList::ConstructList() -{ - m_Head = InvalidIndex(); - m_Tail = InvalidIndex(); - m_FirstFree = InvalidIndex(); - m_ElementCount = 0; -} - - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- - -template -inline T& CUtlLinkedList::Element( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline T const& CUtlLinkedList::Element( I i ) const -{ - return m_Memory[i].m_Element; -} - -template -inline T& CUtlLinkedList::operator[]( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline T const& CUtlLinkedList::operator[]( I i ) const -{ - return m_Memory[i].m_Element; -} - -//----------------------------------------------------------------------------- -// list statistics -//----------------------------------------------------------------------------- - -template -inline int CUtlLinkedList::Count() const -{ - return m_ElementCount; -} - -template -inline I CUtlLinkedList::MaxElementIndex() const -{ - return m_Memory.NumAllocated(); -} - - -//----------------------------------------------------------------------------- -// Traversing the list -//----------------------------------------------------------------------------- - -template -inline I CUtlLinkedList::Head() const -{ - return m_Head; -} - -template -inline I CUtlLinkedList::Tail() const -{ - return m_Tail; -} - -template -inline I CUtlLinkedList::Previous( I i ) const -{ - Assert( IsValidIndex(i) ); - return InternalElement(i).m_Previous; -} - -template -inline I CUtlLinkedList::Next( I i ) const -{ - Assert( IsValidIndex(i) ); - return InternalElement(i).m_Next; -} - - -//----------------------------------------------------------------------------- -// Are nodes in the list or valid? -//----------------------------------------------------------------------------- - -template -inline bool CUtlLinkedList::IsValidIndex( I i ) const -{ - if ( !m_Memory.IsIdxValid( i ) ) - return false; - - if ( m_Memory.IsIdxAfter( i, m_LastAlloc ) ) - return false; // don't read values that have been allocated, but not constructed - - return ( m_Memory[ i ].m_Previous != i ) || ( m_Memory[ i ].m_Next == i ); -} - -template -inline bool CUtlLinkedList::IsInList( I i ) const -{ - if ( !m_Memory.IsIdxValid( i ) || m_Memory.IsIdxAfter( i, m_LastAlloc ) ) - return false; // don't read values that have been allocated, but not constructed - - return Previous( i ) != i; -} - -/* -template -inline bool CUtlFixedLinkedList::IsInList( int i ) const -{ - return m_Memory.IsIdxValid( i ) && (Previous( i ) != i); -} -*/ - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- - -template< class T, class S, bool ML, class I, class M > -void CUtlLinkedList::EnsureCapacity( int num ) -{ - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - -template< class T, class S, bool ML, class I, class M > -void CUtlLinkedList::SetGrowSize( int growSize ) -{ - RemoveAll(); - m_Memory.Init( growSize ); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Deallocate memory -//----------------------------------------------------------------------------- - -template -void CUtlLinkedList::Purge() -{ - RemoveAll(); - - m_Memory.Purge(); - m_FirstFree = InvalidIndex(); - - //Routing "m_LastAlloc = m_Memory.InvalidIterator();" through a local const to sidestep an internal compiler error on 360 builds - const typename M::Iterator_t scInvalidIterator = m_Memory.InvalidIterator(); - m_LastAlloc = scInvalidIterator; - ResetDbgInfo(); -} - - -template -void CUtlLinkedList::PurgeAndDeleteElements() -{ - int iNext; - for( int i=Head(); i != InvalidIndex(); i=iNext ) - { - iNext = Next(i); - delete Element(i); - } - - Purge(); -} - - -//----------------------------------------------------------------------------- -// Node allocation/deallocation -//----------------------------------------------------------------------------- -template -I CUtlLinkedList::AllocInternal( bool multilist ) RESTRICT -{ - Assert( !multilist || ML ); - I elem; - if ( m_FirstFree == InvalidIndex() ) - { - Assert( m_Memory.IsValidIterator( m_LastAlloc ) || m_ElementCount == 0 ); - typename M::Iterator_t it = m_Memory.IsValidIterator( m_LastAlloc ) ? m_Memory.Next( m_LastAlloc ) : m_Memory.First(); - if ( !m_Memory.IsValidIterator( it ) ) - { - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.Grow(); - - it = m_Memory.IsValidIterator( m_LastAlloc ) ? m_Memory.Next( m_LastAlloc ) : m_Memory.First(); - - Assert( m_Memory.IsValidIterator( it ) ); - if ( !m_Memory.IsValidIterator( it ) ) - { - Error( "CUtlLinkedList overflow!\n" ); - } - } - m_LastAlloc = it; - elem = m_Memory.GetIndex( m_LastAlloc ); - } - else - { - elem = m_FirstFree; - m_FirstFree = InternalElement( m_FirstFree ).m_Next; - } - - if ( !multilist ) - { - InternalElement( elem ).m_Next = elem; - InternalElement( elem ).m_Previous = elem; - } - else - { - InternalElement( elem ).m_Next = InvalidIndex(); - InternalElement( elem ).m_Previous = InvalidIndex(); - } - - ResetDbgInfo(); - - return elem; -} - -template -I CUtlLinkedList::Alloc( bool multilist ) -{ - I elem = AllocInternal( multilist ); - Construct( &Element(elem) ); - - return elem; -} - -template -void CUtlLinkedList::Free( I elem ) -{ - Assert( IsValidIndex(elem) ); - Unlink(elem); - - ListElem_t &internalElem = InternalElement(elem); - Destruct( &internalElem.m_Element ); - internalElem.m_Next = m_FirstFree; - m_FirstFree = elem; -} - -//----------------------------------------------------------------------------- -// Insertion methods; allocates and links (uses default constructor) -//----------------------------------------------------------------------------- - -template -I CUtlLinkedList::InsertBefore( I before ) -{ - // Make a new node - I newNode = AllocInternal(); - - // Link it in - LinkBefore( before, newNode ); - - // Construct the data - Construct( &Element(newNode) ); - - return newNode; -} - -template -I CUtlLinkedList::InsertAfter( I after ) -{ - // Make a new node - I newNode = AllocInternal(); - - // Link it in - LinkAfter( after, newNode ); - - // Construct the data - Construct( &Element(newNode) ); - - return newNode; -} - -template -inline I CUtlLinkedList::AddToHead( ) -{ - return InsertAfter( InvalidIndex() ); -} - -template -inline I CUtlLinkedList::AddToTail( ) -{ - return InsertBefore( InvalidIndex() ); -} - - -//----------------------------------------------------------------------------- -// Insertion methods; allocates and links (uses copy constructor) -//----------------------------------------------------------------------------- - -template -I CUtlLinkedList::InsertBefore( I before, T const& src ) -{ - // Make a new node - I newNode = AllocInternal(); - - // Link it in - LinkBefore( before, newNode ); - - // Construct the data - CopyConstruct( &Element(newNode), src ); - - return newNode; -} - -template -I CUtlLinkedList::InsertAfter( I after, T const& src ) -{ - // Make a new node - I newNode = AllocInternal(); - - // Link it in - LinkAfter( after, newNode ); - - // Construct the data - CopyConstruct( &Element(newNode), src ); - - return newNode; -} - -template -inline I CUtlLinkedList::AddToHead( T const& src ) -{ - return InsertAfter( InvalidIndex(), src ); -} - -template -inline I CUtlLinkedList::AddToTail( T const& src ) -{ - return InsertBefore( InvalidIndex(), src ); -} - - -//----------------------------------------------------------------------------- -// Removal methods -//----------------------------------------------------------------------------- - -template -I CUtlLinkedList::Find( const T &src ) const -{ - for ( I i=Head(); i != InvalidIndex(); i = Next( i ) ) - { - if ( Element( i ) == src ) - return i; - } - return InvalidIndex(); -} - - -template -bool CUtlLinkedList::FindAndRemove( const T &src ) -{ - I i = Find( src ); - if ( i == InvalidIndex() ) - { - return false; - } - else - { - Remove( i ); - return true; - } -} - - -template -void CUtlLinkedList::Remove( I elem ) -{ - Free( elem ); -} - -template -void CUtlLinkedList::RemoveAll() -{ - // Have to do some convoluted stuff to invoke the destructor on all - // valid elements for the multilist case (since we don't have all elements - // connected to each other in a list). - - if ( m_LastAlloc == m_Memory.InvalidIterator() ) - { - Assert( m_Head == InvalidIndex() ); - Assert( m_Tail == InvalidIndex() ); - Assert( m_FirstFree == InvalidIndex() ); - Assert( m_ElementCount == 0 ); - return; - } - - if ( ML ) - { - for ( typename M::Iterator_t it = m_Memory.First(); it != m_Memory.InvalidIterator(); it = m_Memory.Next( it ) ) - { - I i = m_Memory.GetIndex( it ); - if ( IsValidIndex( i ) ) // skip elements already in the free list - { - ListElem_t &internalElem = InternalElement( i ); - Destruct( &internalElem.m_Element ); - internalElem.m_Previous = i; - internalElem.m_Next = m_FirstFree; - m_FirstFree = i; - } - - if ( it == m_LastAlloc ) - break; // don't destruct elements that haven't ever been constructed - } - } - else - { - I i = Head(); - I next; - while ( i != InvalidIndex() ) - { - next = Next( i ); - ListElem_t &internalElem = InternalElement( i ); - Destruct( &internalElem.m_Element ); - internalElem.m_Previous = i; - internalElem.m_Next = next == InvalidIndex() ? m_FirstFree : next; - i = next; - } - if ( Head() != InvalidIndex() ) - { - m_FirstFree = Head(); - } - } - - // Clear everything else out - m_Head = InvalidIndex(); - m_Tail = InvalidIndex(); - m_ElementCount = 0; -} - - -//----------------------------------------------------------------------------- -// list modification -//----------------------------------------------------------------------------- - -template -void CUtlLinkedList::LinkBefore( I before, I elem ) -{ - Assert( IsValidIndex(elem) ); - - // Unlink it if it's in the list at the moment - Unlink(elem); - - ListElem_t * RESTRICT pNewElem = &InternalElement(elem); - - // The element *after* our newly linked one is the one we linked before. - pNewElem->m_Next = before; - - S newElem_mPrevious; // we need to hang on to this for the compairson against InvalidIndex() - // below; otherwise we get a a load-hit-store on pNewElem->m_Previous, even - // with RESTRICT - if (before == InvalidIndex()) - { - // In this case, we're linking to the end of the list, so reset the tail - newElem_mPrevious = m_Tail; - pNewElem->m_Previous = m_Tail; - m_Tail = elem; - } - else - { - // Here, we're not linking to the end. Set the prev pointer to point to - // the element we're linking. - Assert( IsInList(before) ); - ListElem_t * RESTRICT beforeElem = &InternalElement(before); - pNewElem->m_Previous = newElem_mPrevious = beforeElem->m_Previous; - beforeElem->m_Previous = elem; - } - - // Reset the head if we linked to the head of the list - if (newElem_mPrevious == InvalidIndex()) - m_Head = elem; - else - InternalElement(newElem_mPrevious).m_Next = elem; - - // one more element baby - ++m_ElementCount; -} - -template -void CUtlLinkedList::LinkAfter( I after, I elem ) -{ - Assert( IsValidIndex(elem) ); - - // Unlink it if it's in the list at the moment - if ( IsInList(elem) ) - Unlink(elem); - - ListElem_t& newElem = InternalElement(elem); - - // The element *before* our newly linked one is the one we linked after - newElem.m_Previous = after; - if (after == InvalidIndex()) - { - // In this case, we're linking to the head of the list, reset the head - newElem.m_Next = m_Head; - m_Head = elem; - } - else - { - // Here, we're not linking to the end. Set the next pointer to point to - // the element we're linking. - Assert( IsInList(after) ); - ListElem_t& afterElem = InternalElement(after); - newElem.m_Next = afterElem.m_Next; - afterElem.m_Next = elem; - } - - // Reset the tail if we linked to the tail of the list - if (newElem.m_Next == InvalidIndex()) - m_Tail = elem; - else - InternalElement(newElem.m_Next).m_Previous = elem; - - // one more element baby - ++m_ElementCount; -} - -template -void CUtlLinkedList::Unlink( I elem ) -{ - Assert( IsValidIndex(elem) ); - if (IsInList(elem)) - { - ListElem_t * RESTRICT pOldElem = &m_Memory[ elem ]; - - // If we're the first guy, reset the head - // otherwise, make our previous node's next pointer = our next - if ( pOldElem->m_Previous != InvalidIndex() ) - { - m_Memory[ pOldElem->m_Previous ].m_Next = pOldElem->m_Next; - } - else - { - m_Head = pOldElem->m_Next; - } - - // If we're the last guy, reset the tail - // otherwise, make our next node's prev pointer = our prev - if ( pOldElem->m_Next != InvalidIndex() ) - { - m_Memory[ pOldElem->m_Next ].m_Previous = pOldElem->m_Previous; - } - else - { - m_Tail = pOldElem->m_Previous; - } - - // This marks this node as not in the list, - // but not in the free list either - pOldElem->m_Previous = pOldElem->m_Next = elem; - - // One less puppy - --m_ElementCount; - } -} - -template -inline void CUtlLinkedList::LinkToHead( I elem ) -{ - LinkAfter( InvalidIndex(), elem ); -} - -template -inline void CUtlLinkedList::LinkToTail( I elem ) -{ - LinkBefore( InvalidIndex(), elem ); -} - - -//----------------------------------------------------------------------------- -// Class to drop in to replace a CUtlLinkedList that needs to be more memory agressive -//----------------------------------------------------------------------------- - -DECLARE_POINTER_HANDLE( UtlPtrLinkedListIndex_t ); // to enforce correct usage - -template < typename T > -class CUtlPtrLinkedList -{ -public: - CUtlPtrLinkedList() - : m_pFirst( NULL ), - m_nElems( 0 ) - { - COMPILE_TIME_ASSERT( sizeof(IndexType_t) == sizeof(Node_t *) ); - } - - ~CUtlPtrLinkedList() - { - RemoveAll(); - } - - typedef UtlPtrLinkedListIndex_t IndexType_t; - - T &operator[]( IndexType_t i ) - { - return (( Node_t * )i)->elem; - } - - const T &operator[]( IndexType_t i ) const - { - return (( Node_t * )i)->elem; - } - - IndexType_t AddToTail() - { - return DoInsertBefore( (IndexType_t)m_pFirst, NULL ); - } - - IndexType_t AddToTail( T const& src ) - { - return DoInsertBefore( (IndexType_t)m_pFirst, &src ); - } - - IndexType_t AddToHead() - { - IndexType_t result = DoInsertBefore( (IndexType_t)m_pFirst, NULL ); - m_pFirst = ((Node_t *)result); - return result; - } - - IndexType_t AddToHead( T const& src ) - { - IndexType_t result = DoInsertBefore( (IndexType_t)m_pFirst, &src ); - m_pFirst = ((Node_t *)result); - return result; - } - - IndexType_t InsertBefore( IndexType_t before ) - { - return DoInsertBefore( before, NULL ); - } - - IndexType_t InsertAfter( IndexType_t after ) - { - Node_t *pBefore = ((Node_t *)after)->next; - return DoInsertBefore( pBefore, NULL ); - } - - IndexType_t InsertBefore( IndexType_t before, T const& src ) - { - return DoInsertBefore( before, &src ); - } - - IndexType_t InsertAfter( IndexType_t after, T const& src ) - { - Node_t *pBefore = ((Node_t *)after)->next; - return DoInsertBefore( pBefore, &src ); - } - - void Remove( IndexType_t elem ) - { - Node_t *p = (Node_t *)elem; - - if ( p->pNext == p ) - { - m_pFirst = NULL; - } - else - { - if ( m_pFirst == p ) - { - m_pFirst = p->pNext; - } - p->pNext->pPrev = p->pPrev; - p->pPrev->pNext = p->pNext; - } - - delete p; - m_nElems--; - } - - void RemoveAll() - { - Node_t *p = m_pFirst; - if ( p ) - { - do - { - Node_t *pNext = p->pNext; - delete p; - p = pNext; - } while( p != m_pFirst ); - } - - m_pFirst = NULL; - m_nElems = 0; - } - - int Count() const - { - return m_nElems; - } - - IndexType_t Head() const - { - return (IndexType_t)m_pFirst; - } - - IndexType_t Next( IndexType_t i ) const - { - Node_t *p = ((Node_t *)i)->pNext; - if ( p != m_pFirst ) - { - return (IndexType_t)p; - } - return NULL; - } - - bool IsValidIndex( IndexType_t i ) const - { - Node_t *p = ((Node_t *)i); - return ( p && p->pNext && p->pPrev ); - } - - inline static IndexType_t InvalidIndex() - { - return NULL; - } -private: - - struct Node_t - { - Node_t() {} - Node_t( const T &elem ) : elem( elem ) {} - - T elem; - Node_t *pPrev, *pNext; - }; - - Node_t *AllocNode( const T *pCopyFrom ) - { - MEM_ALLOC_CREDIT_CLASS(); - Node_t *p; - - if ( !pCopyFrom ) - { - p = new Node_t; - } - else - { - p = new Node_t( *pCopyFrom ); - } - - return p; - } - - IndexType_t DoInsertBefore( IndexType_t before, const T *pCopyFrom ) - { - Node_t *p = AllocNode( pCopyFrom ); - Node_t *pBefore = (Node_t *)before; - if ( pBefore ) - { - p->pNext = pBefore; - p->pPrev = pBefore->pPrev; - pBefore->pPrev = p; - p->pPrev->pNext = p; - } - else - { - Assert( !m_pFirst ); - m_pFirst = p->pNext = p->pPrev = p; - } - - m_nElems++; - return (IndexType_t)p; - } - - Node_t *m_pFirst; - unsigned m_nElems; -}; - -//----------------------------------------------------------------------------- - -#endif // UTLLINKEDLIST_H diff --git a/Resources/NetHook/tier1/utlmap.h b/Resources/NetHook/tier1/utlmap.h deleted file mode 100644 index 6f933c81..00000000 --- a/Resources/NetHook/tier1/utlmap.h +++ /dev/null @@ -1,203 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLMAP_H -#define UTLMAP_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include "utlrbtree.h" - -//----------------------------------------------------------------------------- -// -// Purpose: An associative container. Pretty much identical to std::map. -// -//----------------------------------------------------------------------------- - -// This is a useful macro to iterate from start to end in order in a map -#define FOR_EACH_MAP( mapName, iteratorName ) \ - for ( int iteratorName = mapName.FirstInorder(); iteratorName != mapName.InvalidIndex(); iteratorName = mapName.NextInorder( iteratorName ) ) - -// faster iteration, but in an unspecified order -#define FOR_EACH_MAP_FAST( mapName, iteratorName ) \ - for ( int iteratorName = 0; iteratorName < mapName.MaxElement(); ++iteratorName ) if ( !mapName.IsValidIndex( iteratorName ) ) continue; else - -template -class CUtlMap -{ -public: - typedef K KeyType_t; - typedef T ElemType_t; - typedef I IndexType_t; - - // Less func typedef - // Returns true if the first parameter is "less" than the second - typedef bool (*LessFunc_t)( const KeyType_t &, const KeyType_t & ); - - // constructor, destructor - // Left at growSize = 0, the memory will first allocate 1 element and double in size - // at each increment. - // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below - CUtlMap( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 ) - : m_Tree( growSize, initSize, CKeyLess( lessfunc ) ) - { - } - - CUtlMap( LessFunc_t lessfunc ) - : m_Tree( CKeyLess( lessfunc ) ) - { - } - - void EnsureCapacity( int num ) { m_Tree.EnsureCapacity( num ); } - - // gets particular elements - ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; } - const ElemType_t & Element( IndexType_t i ) const { return m_Tree.Element( i ).elem; } - ElemType_t & operator[]( IndexType_t i ) { return m_Tree.Element( i ).elem; } - const ElemType_t & operator[]( IndexType_t i ) const { return m_Tree.Element( i ).elem; } - KeyType_t & Key( IndexType_t i ) { return m_Tree.Element( i ).key; } - const KeyType_t & Key( IndexType_t i ) const { return m_Tree.Element( i ).key; } - - - // Num elements - unsigned int Count() const { return m_Tree.Count(); } - - // Max "size" of the vector - IndexType_t MaxElement() const { return m_Tree.MaxElement(); } - - // Checks if a node is valid and in the map - bool IsValidIndex( IndexType_t i ) const { return m_Tree.IsValidIndex( i ); } - - // Checks if the map as a whole is valid - bool IsValid() const { return m_Tree.IsValid(); } - - // Invalid index - static IndexType_t InvalidIndex() { return CTree::InvalidIndex(); } - - // Sets the less func - void SetLessFunc( LessFunc_t func ) - { - m_Tree.SetLessFunc( CKeyLess( func ) ); - } - - // Insert method (inserts in order) - IndexType_t Insert( const KeyType_t &key, const ElemType_t &insert ) - { - Node_t node; - node.key = key; - node.elem = insert; - return m_Tree.Insert( node ); - } - - IndexType_t Insert( const KeyType_t &key ) - { - Node_t node; - node.key = key; - return m_Tree.Insert( node ); - } - - // Find method - IndexType_t Find( const KeyType_t &key ) const - { - Node_t dummyNode; - dummyNode.key = key; - return m_Tree.Find( dummyNode ); - } - - // Remove methods - void RemoveAt( IndexType_t i ) { m_Tree.RemoveAt( i ); } - bool Remove( const KeyType_t &key ) - { - Node_t dummyNode; - dummyNode.key = key; - return m_Tree.Remove( dummyNode ); - } - - void RemoveAll( ) { m_Tree.RemoveAll(); } - void Purge( ) { m_Tree.Purge(); } - - // Iteration - IndexType_t FirstInorder() const { return m_Tree.FirstInorder(); } - IndexType_t NextInorder( IndexType_t i ) const { return m_Tree.NextInorder( i ); } - IndexType_t PrevInorder( IndexType_t i ) const { return m_Tree.PrevInorder( i ); } - IndexType_t LastInorder() const { return m_Tree.LastInorder(); } - - // If you change the search key, this can be used to reinsert the - // element into the map. - void Reinsert( const KeyType_t &key, IndexType_t i ) - { - m_Tree[i].key = key; - m_Tree.Reinsert(i); - } - - IndexType_t InsertOrReplace( const KeyType_t &key, const ElemType_t &insert ) - { - IndexType_t i = Find( key ); - if ( i != InvalidIndex() ) - { - Element( i ) = insert; - return i; - } - - return Insert( key, insert ); - } - - void Swap( CUtlMap< K, T, I > &that ) - { - m_Tree.Swap( that.m_Tree ); - } - - - struct Node_t - { - Node_t() - { - } - - Node_t( const Node_t &from ) - : key( from.key ), - elem( from.elem ) - { - } - - KeyType_t key; - ElemType_t elem; - }; - - class CKeyLess - { - public: - CKeyLess( LessFunc_t lessFunc ) : m_LessFunc(lessFunc) {} - - bool operator!() const - { - return !m_LessFunc; - } - - bool operator()( const Node_t &left, const Node_t &right ) const - { - return m_LessFunc( left.key, right.key ); - } - - LessFunc_t m_LessFunc; - }; - - typedef CUtlRBTree CTree; - - CTree *AccessTree() { return &m_Tree; } - -protected: - CTree m_Tree; -}; - -//----------------------------------------------------------------------------- - -#endif // UTLMAP_H diff --git a/Resources/NetHook/tier1/utlmemory.h b/Resources/NetHook/tier1/utlmemory.h deleted file mode 100644 index 299ce546..00000000 --- a/Resources/NetHook/tier1/utlmemory.h +++ /dev/null @@ -1,925 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -// -// A growable memory class. -//===========================================================================// - -#ifndef UTLMEMORY_H -#define UTLMEMORY_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" -#include -#include "tier0/platform.h" - -#include "tier0/memalloc.h" -#include "tier0/memdbgon.h" - -#pragma warning (disable:4100) -#pragma warning (disable:4514) - - -//----------------------------------------------------------------------------- - - -#ifdef UTLMEMORY_TRACK -#define UTLMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 ) -#define UTLMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlMemory", 0, m_nAllocationCount * sizeof(T), m_nAllocationCount * sizeof(T), 0 ) -#else -#define UTLMEMORY_TRACK_ALLOC() ((void)0) -#define UTLMEMORY_TRACK_FREE() ((void)0) -#endif - - -//----------------------------------------------------------------------------- -// The CUtlMemory class: -// A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T, class I = int > -class CUtlMemory -{ -public: - // constructor, destructor - CUtlMemory( int nGrowSize = 0, int nInitSize = 0 ); - CUtlMemory( T* pMemory, int numElements ); - CUtlMemory( const T* pMemory, int numElements ); - ~CUtlMemory(); - - // Set the size by which the memory grows - void Init( int nGrowSize = 0, int nInitSize = 0 ); - - class Iterator_t - { - public: - Iterator_t( I i ) : index( i ) {} - I index; - - bool operator==( const Iterator_t it ) const { return index == it.index; } - bool operator!=( const Iterator_t it ) const { return index != it.index; } - }; - Iterator_t First() const { return Iterator_t( IsIdxValid( 0 ) ? 0 : InvalidIndex() ); } - Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( IsIdxValid( it.index + 1 ) ? it.index + 1 : InvalidIndex() ); } - I GetIndex( const Iterator_t &it ) const { return it.index; } - bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; } - bool IsValidIterator( const Iterator_t &it ) const { return IsIdxValid( it.index ); } - Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); } - - // element access - T& operator[]( I i ); - const T& operator[]( I i ) const; - T& Element( I i ); - const T& Element( I i ) const; - - // Can we use this index? - bool IsIdxValid( I i ) const; - static I InvalidIndex() { return ( I )-1; } - - // Gets the base address (can change when adding elements!) - T* Base(); - const T* Base() const; - - // Attaches the buffer to external memory.... - void SetExternalBuffer( T* pMemory, int numElements ); - void SetExternalBuffer( const T* pMemory, int numElements ); - void AssumeMemory( T *pMemory, int nSize ); - - // Fast swap - void Swap( CUtlMemory< T, I > &mem ); - - // Switches the buffer from an external memory buffer to a reallocatable buffer - // Will copy the current contents of the external buffer to the reallocatable buffer - void ConvertToGrowableMemory( int nGrowSize ); - - // Size - int NumAllocated() const; - int Count() const; - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow( int num = 1 ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - - // Purge all but the given number of elements - void Purge( int numElements ); - - // is the memory externally allocated? - bool IsExternallyAllocated() const; - - // is the memory read only? - bool IsReadOnly() const; - - // Set the size by which the memory grows - void SetGrowSize( int size ); - -protected: - void ValidateGrowSize() - { -#ifdef _X360 - if ( m_nGrowSize && m_nGrowSize != EXTERNAL_BUFFER_MARKER ) - { - // Max grow size at 128 bytes on XBOX - const int MAX_GROW = 128; - if ( m_nGrowSize * sizeof(T) > MAX_GROW ) - { - m_nGrowSize = max( 1, MAX_GROW / sizeof(T) ); - } - } -#endif - } - - enum - { - EXTERNAL_BUFFER_MARKER = -1, - EXTERNAL_CONST_BUFFER_MARKER = -2, - }; - - T* m_pMemory; - int m_nAllocationCount; - int m_nGrowSize; -}; - - -//----------------------------------------------------------------------------- -// The CUtlMemory class: -// A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T, size_t SIZE, class I = int > -class CUtlMemoryFixedGrowable : public CUtlMemory< T, I > -{ - typedef CUtlMemory< T, I > BaseClass; - -public: - CUtlMemoryFixedGrowable( int nGrowSize = 0, int nInitSize = SIZE ) : BaseClass( m_pFixedMemory, SIZE ) - { - Assert( nInitSize == 0 || nInitSize == SIZE ); - m_nMallocGrowSize = nGrowSize; - } - - void Grow( int nCount = 1 ) - { - if ( IsExternallyAllocated() ) - { - ConvertToGrowableMemory( m_nMallocGrowSize ); - } - BaseClass::Grow( nCount ); - } - - void EnsureCapacity( int num ) - { - if ( CUtlMemory::m_nAllocationCount >= num ) - return; - - if ( IsExternallyAllocated() ) - { - // Can't grow a buffer whose memory was externally allocated - ConvertToGrowableMemory( m_nMallocGrowSize ); - } - - BaseClass::EnsureCapacity( num ); - } - -private: - int m_nMallocGrowSize; - T m_pFixedMemory[ SIZE ]; -}; - -//----------------------------------------------------------------------------- -// The CUtlMemoryFixed class: -// A fixed memory class -//----------------------------------------------------------------------------- -template< typename T, size_t SIZE, int nAlignment = 0 > -class CUtlMemoryFixed -{ -public: - // constructor, destructor - CUtlMemoryFixed( int nGrowSize = 0, int nInitSize = 0 ) { Assert( nInitSize == 0 || nInitSize == SIZE ); } - CUtlMemoryFixed( T* pMemory, int numElements ) { Assert( 0 ); } - - // Can we use this index? - bool IsIdxValid( int i ) const { return (i >= 0) && (i < SIZE); } - static int InvalidIndex() { return -1; } - - // Gets the base address - T* Base() { if ( nAlignment == 0 ) return (T*)(&m_Memory[0]); else return (T*)AlignValue( &m_Memory[0], nAlignment ); } - const T* Base() const { if ( nAlignment == 0 ) return (T*)(&m_Memory[0]); else return (T*)AlignValue( &m_Memory[0], nAlignment ); } - - // element access - T& operator[]( int i ) { Assert( IsIdxValid(i) ); return Base()[i]; } - const T& operator[]( int i ) const { Assert( IsIdxValid(i) ); return Base()[i]; } - T& Element( int i ) { Assert( IsIdxValid(i) ); return Base()[i]; } - const T& Element( int i ) const { Assert( IsIdxValid(i) ); return Base()[i]; } - - // Attaches the buffer to external memory.... - void SetExternalBuffer( T* pMemory, int numElements ) { Assert( 0 ); } - - // Size - int NumAllocated() const { return SIZE; } - int Count() const { return SIZE; } - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow( int num = 1 ) { Assert( 0 ); } - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ) { Assert( num <= SIZE ); } - - // Memory deallocation - void Purge() {} - - // Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryFixed) - void Purge( int numElements ) { Assert( 0 ); } - - // is the memory externally allocated? - bool IsExternallyAllocated() const { return false; } - - // Set the size by which the memory grows - void SetGrowSize( int size ) {} - - class Iterator_t - { - public: - Iterator_t( int i ) : index( i ) {} - int index; - bool operator==( const Iterator_t it ) const { return index == it.index; } - bool operator!=( const Iterator_t it ) const { return index != it.index; } - }; - Iterator_t First() const { return Iterator_t( IsIdxValid( 0 ) ? 0 : InvalidIndex() ); } - Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( IsIdxValid( it.index + 1 ) ? it.index + 1 : InvalidIndex() ); } - int GetIndex( const Iterator_t &it ) const { return it.index; } - bool IsIdxAfter( int i, const Iterator_t &it ) const { return i > it.index; } - bool IsValidIterator( const Iterator_t &it ) const { return IsIdxValid( it.index ); } - Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); } - -private: - char m_Memory[ SIZE*sizeof(T) + nAlignment ]; -}; - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T, class I > -CUtlMemory::CUtlMemory( int nGrowSize, int nInitAllocationCount ) : m_pMemory(0), - m_nAllocationCount( nInitAllocationCount ), m_nGrowSize( nGrowSize ) -{ - ValidateGrowSize(); - Assert( nGrowSize >= 0 ); - if (m_nAllocationCount) - { - UTLMEMORY_TRACK_ALLOC(); - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - } -} - -template< class T, class I > -CUtlMemory::CUtlMemory( T* pMemory, int numElements ) : m_pMemory(pMemory), - m_nAllocationCount( numElements ) -{ - // Special marker indicating externally supplied modifyable memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - -template< class T, class I > -CUtlMemory::CUtlMemory( const T* pMemory, int numElements ) : m_pMemory( (T*)pMemory ), - m_nAllocationCount( numElements ) -{ - // Special marker indicating externally supplied modifyable memory - m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER; -} - -template< class T, class I > -CUtlMemory::~CUtlMemory() -{ - Purge(); -} - -template< class T, class I > -void CUtlMemory::Init( int nGrowSize /*= 0*/, int nInitSize /*= 0*/ ) -{ - Purge(); - - m_nGrowSize = nGrowSize; - m_nAllocationCount = nInitSize; - ValidateGrowSize(); - Assert( nGrowSize >= 0 ); - if (m_nAllocationCount) - { - UTLMEMORY_TRACK_ALLOC(); - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - } -} - -//----------------------------------------------------------------------------- -// Fast swap -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlMemory::Swap( CUtlMemory &mem ) -{ - swap( m_nGrowSize, mem.m_nGrowSize ); - swap( m_pMemory, mem.m_pMemory ); - swap( m_nAllocationCount, mem.m_nAllocationCount ); -} - - -//----------------------------------------------------------------------------- -// Switches the buffer from an external memory buffer to a reallocatable buffer -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlMemory::ConvertToGrowableMemory( int nGrowSize ) -{ - if ( !IsExternallyAllocated() ) - return; - - m_nGrowSize = nGrowSize; - if (m_nAllocationCount) - { - UTLMEMORY_TRACK_ALLOC(); - MEM_ALLOC_CREDIT_CLASS(); - - int nNumBytes = m_nAllocationCount * sizeof(T); - T *pMemory = (T*)malloc( nNumBytes ); - memcpy( pMemory, m_pMemory, nNumBytes ); - m_pMemory = pMemory; - } - else - { - m_pMemory = NULL; - } -} - - -//----------------------------------------------------------------------------- -// Attaches the buffer to external memory.... -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlMemory::SetExternalBuffer( T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - m_pMemory = pMemory; - m_nAllocationCount = numElements; - - // Indicate that we don't own the memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - -template< class T, class I > -void CUtlMemory::SetExternalBuffer( const T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - m_pMemory = const_cast( pMemory ); - m_nAllocationCount = numElements; - - // Indicate that we don't own the memory - m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER; -} - -template< class T, class I > -void CUtlMemory::AssumeMemory( T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - // Simply take the pointer but don't mark us as external - m_pMemory = pMemory; - m_nAllocationCount = numElements; -} - - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< class T, class I > -inline T& CUtlMemory::operator[]( I i ) -{ - Assert( !IsReadOnly() ); - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T, class I > -inline const T& CUtlMemory::operator[]( I i ) const -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T, class I > -inline T& CUtlMemory::Element( I i ) -{ - Assert( !IsReadOnly() ); - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T, class I > -inline const T& CUtlMemory::Element( I i ) const -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - - -//----------------------------------------------------------------------------- -// is the memory externally allocated? -//----------------------------------------------------------------------------- -template< class T, class I > -bool CUtlMemory::IsExternallyAllocated() const -{ - return (m_nGrowSize < 0); -} - - -//----------------------------------------------------------------------------- -// is the memory read only? -//----------------------------------------------------------------------------- -template< class T, class I > -bool CUtlMemory::IsReadOnly() const -{ - return (m_nGrowSize == EXTERNAL_CONST_BUFFER_MARKER); -} - - -template< class T, class I > -void CUtlMemory::SetGrowSize( int nSize ) -{ - Assert( !IsExternallyAllocated() ); - Assert( nSize >= 0 ); - m_nGrowSize = nSize; - ValidateGrowSize(); -} - - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- -template< class T, class I > -inline T* CUtlMemory::Base() -{ - Assert( !IsReadOnly() ); - return m_pMemory; -} - -template< class T, class I > -inline const T *CUtlMemory::Base() const -{ - return m_pMemory; -} - - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- -template< class T, class I > -inline int CUtlMemory::NumAllocated() const -{ - return m_nAllocationCount; -} - -template< class T, class I > -inline int CUtlMemory::Count() const -{ - return m_nAllocationCount; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< class T, class I > -inline bool CUtlMemory::IsIdxValid( I i ) const -{ - return ( ((int) i) >= 0 ) && ( ((int) i) < m_nAllocationCount ); -} - -//----------------------------------------------------------------------------- -// Grows the memory -//----------------------------------------------------------------------------- -inline int UtlMemory_CalcNewAllocationCount( int nAllocationCount, int nGrowSize, int nNewSize, int nBytesItem ) -{ - if ( nGrowSize ) - { - nAllocationCount = ((1 + ((nNewSize - 1) / nGrowSize)) * nGrowSize); - } - else - { - if ( !nAllocationCount ) - { - // Compute an allocation which is at least as big as a cache line... - nAllocationCount = (31 + nBytesItem) / nBytesItem; - } - - while (nAllocationCount < nNewSize) - { -#ifndef _X360 - nAllocationCount *= 2; -#else - int nNewAllocationCount = ( nAllocationCount * 9) / 8; // 12.5 % - if ( nNewAllocationCount > nAllocationCount ) - nAllocationCount = nNewAllocationCount; - else - nAllocationCount *= 2; -#endif - } - } - - return nAllocationCount; -} - -template< class T, class I > -void CUtlMemory::Grow( int num ) -{ - Assert( num > 0 ); - - if ( IsExternallyAllocated() ) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - // Make sure we have at least numallocated + num allocations. - // Use the grow rules specified for this memory (in m_nGrowSize) - int nAllocationRequested = m_nAllocationCount + num; - - UTLMEMORY_TRACK_FREE(); - - m_nAllocationCount = UtlMemory_CalcNewAllocationCount( m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T) ); - - // if m_nAllocationRequested wraps index type I, recalculate - if ( ( int )( I )m_nAllocationCount < nAllocationRequested ) - { - if ( ( int )( I )m_nAllocationCount == 0 && ( int )( I )( m_nAllocationCount - 1 ) >= nAllocationRequested ) - { - --m_nAllocationCount; // deal w/ the common case of m_nAllocationCount == MAX_USHORT + 1 - } - else - { - if ( ( int )( I )nAllocationRequested != nAllocationRequested ) - { - // we've been asked to grow memory to a size s.t. the index type can't address the requested amount of memory - Assert( 0 ); - return; - } - while ( ( int )( I )m_nAllocationCount < nAllocationRequested ) - { - m_nAllocationCount = ( m_nAllocationCount + nAllocationRequested ) / 2; - } - } - } - - UTLMEMORY_TRACK_ALLOC(); - - if (m_pMemory) - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)realloc( m_pMemory, m_nAllocationCount * sizeof(T) ); - Assert( m_pMemory ); - } - else - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - Assert( m_pMemory ); - } -} - - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -template< class T, class I > -inline void CUtlMemory::EnsureCapacity( int num ) -{ - if (m_nAllocationCount >= num) - return; - - if ( IsExternallyAllocated() ) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - UTLMEMORY_TRACK_FREE(); - - m_nAllocationCount = num; - - UTLMEMORY_TRACK_ALLOC(); - - if (m_pMemory) - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)realloc( m_pMemory, m_nAllocationCount * sizeof(T) ); - } - else - { - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - } -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlMemory::Purge() -{ - if ( !IsExternallyAllocated() ) - { - if (m_pMemory) - { - UTLMEMORY_TRACK_FREE(); - free( (void*)m_pMemory ); - m_pMemory = 0; - } - m_nAllocationCount = 0; - } -} - -template< class T, class I > -void CUtlMemory::Purge( int numElements ) -{ - Assert( numElements >= 0 ); - - if( numElements > m_nAllocationCount ) - { - // Ensure this isn't a grow request in disguise. - Assert( numElements <= m_nAllocationCount ); - return; - } - - // If we have zero elements, simply do a purge: - if( numElements == 0 ) - { - Purge(); - return; - } - - if ( IsExternallyAllocated() ) - { - // Can't shrink a buffer whose memory was externally allocated, fail silently like purge - return; - } - - // If the number of elements is the same as the allocation count, we are done. - if( numElements == m_nAllocationCount ) - { - return; - } - - - if( !m_pMemory ) - { - // Allocation count is non zero, but memory is null. - Assert( m_pMemory ); - return; - } - - UTLMEMORY_TRACK_FREE(); - - m_nAllocationCount = numElements; - - UTLMEMORY_TRACK_ALLOC(); - - // Allocation count > 0, shrink it down. - MEM_ALLOC_CREDIT_CLASS(); - m_pMemory = (T*)realloc( m_pMemory, m_nAllocationCount * sizeof(T) ); -} - -//----------------------------------------------------------------------------- -// The CUtlMemory class: -// A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -class CUtlMemoryAligned : public CUtlMemory -{ -public: - // constructor, destructor - CUtlMemoryAligned( int nGrowSize = 0, int nInitSize = 0 ); - CUtlMemoryAligned( T* pMemory, int numElements ); - CUtlMemoryAligned( const T* pMemory, int numElements ); - ~CUtlMemoryAligned(); - - // Attaches the buffer to external memory.... - void SetExternalBuffer( T* pMemory, int numElements ); - void SetExternalBuffer( const T* pMemory, int numElements ); - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow( int num = 1 ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - - // Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryAligned) - void Purge( int numElements ) { Assert( 0 ); } - -private: - void *Align( const void *pAddr ); -}; - - -//----------------------------------------------------------------------------- -// Aligns a pointer -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -void *CUtlMemoryAligned::Align( const void *pAddr ) -{ - size_t nAlignmentMask = nAlignment - 1; - return (void*)( ((size_t)pAddr + nAlignmentMask) & (~nAlignmentMask) ); -} - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -CUtlMemoryAligned::CUtlMemoryAligned( int nGrowSize, int nInitAllocationCount ) -{ - CUtlMemory::m_pMemory = 0; - CUtlMemory::m_nAllocationCount = nInitAllocationCount; - CUtlMemory::m_nGrowSize = nGrowSize; - ValidateGrowSize(); - - // Alignment must be a power of two - COMPILE_TIME_ASSERT( (nAlignment & (nAlignment-1)) == 0 ); - Assert( (nGrowSize >= 0) && (nGrowSize != CUtlMemory::EXTERNAL_BUFFER_MARKER) ); - if ( CUtlMemory::m_nAllocationCount ) - { - UTLMEMORY_TRACK_ALLOC(); - MEM_ALLOC_CREDIT_CLASS(); - CUtlMemory::m_pMemory = (T*)_aligned_malloc( nInitAllocationCount * sizeof(T), nAlignment ); - } -} - -template< class T, int nAlignment > -CUtlMemoryAligned::CUtlMemoryAligned( T* pMemory, int numElements ) -{ - // Special marker indicating externally supplied memory - CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_BUFFER_MARKER; - - CUtlMemory::m_pMemory = (T*)Align( pMemory ); - CUtlMemory::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory ) / sizeof(T); -} - -template< class T, int nAlignment > -CUtlMemoryAligned::CUtlMemoryAligned( const T* pMemory, int numElements ) -{ - // Special marker indicating externally supplied memory - CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_CONST_BUFFER_MARKER; - - CUtlMemory::m_pMemory = (T*)Align( pMemory ); - CUtlMemory::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory ) / sizeof(T); -} - -template< class T, int nAlignment > -CUtlMemoryAligned::~CUtlMemoryAligned() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -// Attaches the buffer to external memory.... -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -void CUtlMemoryAligned::SetExternalBuffer( T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - CUtlMemory::m_pMemory = (T*)Align( pMemory ); - CUtlMemory::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory ) / sizeof(T); - - // Indicate that we don't own the memory - CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_BUFFER_MARKER; -} - -template< class T, int nAlignment > -void CUtlMemoryAligned::SetExternalBuffer( const T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - CUtlMemory::m_pMemory = (T*)Align( pMemory ); - CUtlMemory::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory::m_pMemory ) / sizeof(T); - - // Indicate that we don't own the memory - CUtlMemory::m_nGrowSize = CUtlMemory::EXTERNAL_CONST_BUFFER_MARKER; -} - - -//----------------------------------------------------------------------------- -// Grows the memory -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -void CUtlMemoryAligned::Grow( int num ) -{ - Assert( num > 0 ); - - if ( IsExternallyAllocated() ) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - UTLMEMORY_TRACK_FREE(); - - // Make sure we have at least numallocated + num allocations. - // Use the grow rules specified for this memory (in m_nGrowSize) - int nAllocationRequested = CUtlMemory::m_nAllocationCount + num; - - CUtlMemory::m_nAllocationCount = UtlMemory_CalcNewAllocationCount( CUtlMemory::m_nAllocationCount, CUtlMemory::m_nGrowSize, nAllocationRequested, sizeof(T) ); - - UTLMEMORY_TRACK_ALLOC(); - - if ( CUtlMemory::m_pMemory ) - { - MEM_ALLOC_CREDIT_CLASS(); - CUtlMemory::m_pMemory = (T*)_aligned_realloc( CUtlMemory::m_pMemory, CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment ); - Assert( CUtlMemory::m_pMemory ); - } - else - { - MEM_ALLOC_CREDIT_CLASS(); - CUtlMemory::m_pMemory = (T*)_aligned_malloc( CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment ); - Assert( CUtlMemory::m_pMemory ); - } -} - - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -inline void CUtlMemoryAligned::EnsureCapacity( int num ) -{ - if ( CUtlMemory::m_nAllocationCount >= num ) - return; - - if ( IsExternallyAllocated() ) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - UTLMEMORY_TRACK_FREE(); - - CUtlMemory::m_nAllocationCount = num; - - UTLMEMORY_TRACK_ALLOC(); - - if ( CUtlMemory::m_pMemory ) - { - MEM_ALLOC_CREDIT_CLASS(); - CUtlMemory::m_pMemory = (T*)_aligned_realloc( CUtlMemory::m_pMemory, CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment ); - } - else - { - MEM_ALLOC_CREDIT_CLASS(); - CUtlMemory::m_pMemory = (T*)_aligned_malloc( CUtlMemory::m_nAllocationCount * sizeof(T), nAlignment ); - } -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T, int nAlignment > -void CUtlMemoryAligned::Purge() -{ - if ( !IsExternallyAllocated() ) - { - if ( CUtlMemory::m_pMemory ) - { - UTLMEMORY_TRACK_FREE(); - _aligned_free( CUtlMemory::m_pMemory ); - CUtlMemory::m_pMemory = 0; - } - CUtlMemory::m_nAllocationCount = 0; - } -} - -#include "tier0/memdbgoff.h" - -#endif // UTLMEMORY_H diff --git a/Resources/NetHook/tier1/utlmultilist.h b/Resources/NetHook/tier1/utlmultilist.h deleted file mode 100644 index c4436fc3..00000000 --- a/Resources/NetHook/tier1/utlmultilist.h +++ /dev/null @@ -1,725 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Multiple linked list container class -// -// $Revision: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLMULTILIST_H -#define UTLMULTILIST_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "utllinkedlist.h" - -// memdbgon must be the last include file in a .h file!!! -#include "tier0/memdbgon.h" - - -// This is a useful macro to iterate from head to tail in a linked list. -#define FOR_EACH_LL( listName, iteratorName ) \ - for( int iteratorName=listName.Head(); iteratorName != listName.InvalidIndex(); iteratorName = listName.Next( iteratorName ) ) - -//----------------------------------------------------------------------------- -// class CUtlMultiList: -// description: -// A lovely index-based linked list! T is the class type, I is the index -// type, which usually should be an unsigned short or smaller. -// This list can contain multiple lists -//----------------------------------------------------------------------------- -template -class CUtlMultiList -{ -public: - typedef I ListHandle_t; - - // constructor, destructor - CUtlMultiList( int growSize = 0, int initSize = 0 ); - CUtlMultiList( void *pMemory, int memsize ); - ~CUtlMultiList( ); - - // gets particular elements - T& Element( I i ); - T const& Element( I i ) const; - T& operator[]( I i ); - T const& operator[]( I i ) const; - - // Make sure we have a particular amount of memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - - // List Creation/deletion - ListHandle_t CreateList(); - void DestroyList( ListHandle_t list ); - bool IsValidList( ListHandle_t list ) const; - - // Insertion methods (call default constructor).... - I InsertBefore( ListHandle_t list, I before ); - I InsertAfter( ListHandle_t list, I after ); - I AddToHead( ListHandle_t list ); - I AddToTail( ListHandle_t list ); - - // Insertion methods (call copy constructor).... - I InsertBefore( ListHandle_t list, I before, T const& src ); - I InsertAfter( ListHandle_t list, I after, T const& src ); - I AddToHead( ListHandle_t list, T const& src ); - I AddToTail( ListHandle_t list, T const& src ); - - // Removal methods - void Remove( ListHandle_t list, I elem ); - - // Removes all items in a single list - void RemoveAll( ListHandle_t list ); - - // Removes all items in all lists - void RemoveAll(); - - // Allocation/deallocation methods - // NOTE: To free, it must *not* be in a list! - I Alloc( ); - void Free( I elem ); - - // list modification - void LinkBefore( ListHandle_t list, I before, I elem ); - void LinkAfter( ListHandle_t list, I after, I elem ); - void Unlink( ListHandle_t list, I elem ); - void LinkToHead( ListHandle_t list, I elem ); - void LinkToTail( ListHandle_t list, I elem ); - - // invalid index - static I InvalidIndex() { return (I)~0; } - static size_t ElementSize() { return sizeof(ListElem_t); } - - // list statistics - int Count( ListHandle_t list ) const; - int TotalCount( ) const; - I MaxElementIndex() const; - - // Traversing the list - I Head( ListHandle_t list ) const; - I Tail( ListHandle_t list ) const; - I Previous( I element ) const; - I Next( I element ) const; - - // Are nodes in a list or valid? - bool IsValidIndex( I i ) const; - bool IsInList( I i ) const; - -protected: - // What the linked list element looks like - struct ListElem_t - { - T m_Element; - I m_Previous; - I m_Next; - }; - - struct List_t - { - I m_Head; - I m_Tail; - I m_Count; - }; - - // constructs the class - void ConstructList( ); - - // Gets at the list element.... - ListElem_t& InternalElement( I i ) { return m_Memory[i]; } - ListElem_t const& InternalElement( I i ) const { return m_Memory[i]; } - - // A test for debug mode only... - bool IsElementInList( ListHandle_t list, I elem ) const; - - // copy constructors not allowed - CUtlMultiList( CUtlMultiList const& list ) { Assert(0); } - - CUtlMemory m_Memory; - CUtlLinkedList m_List; - I* m_pElementList; - - I m_FirstFree; - I m_TotalElements; - I m_MaxElementIndex; // The number allocated - - void ResetDbgInfo() - { - m_pElements = m_Memory.Base(); - -#ifdef _DEBUG - // Allocate space for the element list (which list is each element in) - if (m_Memory.NumAllocated() > 0) - { - if (!m_pElementList) - { - m_pElementList = (I*)malloc( m_Memory.NumAllocated() * sizeof(I) ); - } - else - { - m_pElementList = (I*)realloc( m_pElementList, m_Memory.NumAllocated() * sizeof(I) ); - } - } -#endif - } - - // For debugging purposes; - // it's in release builds so this can be used in libraries correctly - ListElem_t *m_pElements; -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template -CUtlMultiList::CUtlMultiList( int growSize, int initSize ) : - m_Memory(growSize, initSize), m_pElementList(0) -{ - ConstructList(); -} - -template -CUtlMultiList::CUtlMultiList( void* pMemory, int memsize ) : - m_Memory((ListElem_t *)pMemory, memsize/sizeof(ListElem_t)), m_pElementList(0) -{ - ConstructList(); -} - -template -CUtlMultiList::~CUtlMultiList( ) -{ - RemoveAll(); - if (m_pElementList) - free(m_pElementList); -} - -template -void CUtlMultiList::ConstructList( ) -{ - m_FirstFree = InvalidIndex(); - m_TotalElements = 0; - m_MaxElementIndex = 0; - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- -template -inline T& CUtlMultiList::Element( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline T const& CUtlMultiList::Element( I i ) const -{ - return m_Memory[i].m_Element; -} - -template -inline T& CUtlMultiList::operator[]( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline T const& CUtlMultiList::operator[]( I i ) const -{ - return m_Memory[i].m_Element; -} - - -//----------------------------------------------------------------------------- -// list creation/destruction -//----------------------------------------------------------------------------- -template -typename CUtlMultiList::ListHandle_t CUtlMultiList::CreateList() -{ - ListHandle_t l = m_List.AddToTail(); - m_List[l].m_Head = m_List[l].m_Tail = InvalidIndex(); - m_List[l].m_Count = 0; - return l; -} - -template -void CUtlMultiList::DestroyList( ListHandle_t list ) -{ - Assert( IsValidList(list) ); - RemoveAll( list ); - m_List.Remove(list); -} - -template -bool CUtlMultiList::IsValidList( ListHandle_t list ) const -{ - return m_List.IsValidIndex(list); -} - - -//----------------------------------------------------------------------------- -// list statistics -//----------------------------------------------------------------------------- -template -inline int CUtlMultiList::TotalCount() const -{ - return m_TotalElements; -} - -template -inline int CUtlMultiList::Count( ListHandle_t list ) const -{ - Assert( IsValidList(list) ); - return m_List[list].m_Count; -} - -template -inline I CUtlMultiList::MaxElementIndex() const -{ - return m_MaxElementIndex; -} - - -//----------------------------------------------------------------------------- -// Traversing the list -//----------------------------------------------------------------------------- -template -inline I CUtlMultiList::Head(ListHandle_t list) const -{ - Assert( IsValidList(list) ); - return m_List[list].m_Head; -} - -template -inline I CUtlMultiList::Tail(ListHandle_t list) const -{ - Assert( IsValidList(list) ); - return m_List[list].m_Tail; -} - -template -inline I CUtlMultiList::Previous( I i ) const -{ - Assert( IsValidIndex(i) ); - return InternalElement(i).m_Previous; -} - -template -inline I CUtlMultiList::Next( I i ) const -{ - Assert( IsValidIndex(i) ); - return InternalElement(i).m_Next; -} - - -//----------------------------------------------------------------------------- -// Are nodes in the list or valid? -//----------------------------------------------------------------------------- -template -inline bool CUtlMultiList::IsValidIndex( I i ) const -{ - return (i < m_MaxElementIndex) && (i >= 0) && - ((m_Memory[i].m_Previous != i) || (m_Memory[i].m_Next == i)); -} - -template -inline bool CUtlMultiList::IsInList( I i ) const -{ - return (i < m_MaxElementIndex) && (i >= 0) && (Previous(i) != i); -} - - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlMultiList::EnsureCapacity( int num ) -{ - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Deallocate memory -//----------------------------------------------------------------------------- -template -void CUtlMultiList::Purge() -{ - RemoveAll(); - m_List.Purge(); - m_Memory.Purge( ); - m_List.Purge(); - m_FirstFree = InvalidIndex(); - m_TotalElements = 0; - m_MaxElementIndex = 0; - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Node allocation/deallocation -//----------------------------------------------------------------------------- -template -I CUtlMultiList::Alloc( ) -{ - I elem; - if (m_FirstFree == InvalidIndex()) - { - // Nothing in the free list; add. - // Since nothing is in the free list, m_TotalElements == total # of elements - // the list knows about. - if (m_MaxElementIndex == m_Memory.NumAllocated()) - { - m_Memory.Grow(); - ResetDbgInfo(); - } - - elem = (I)m_MaxElementIndex; - ++m_MaxElementIndex; - } - else - { - elem = m_FirstFree; - m_FirstFree = InternalElement(m_FirstFree).m_Next; - } - - // Mark the element as not being in a list - InternalElement(elem).m_Next = InternalElement(elem).m_Previous = elem; - - ++m_TotalElements; - - Construct( &Element(elem) ); - - return elem; -} - -template -void CUtlMultiList::Free( I elem ) -{ - Assert( IsValidIndex(elem) && !IsInList(elem) ); - Destruct( &Element(elem) ); - InternalElement(elem).m_Next = m_FirstFree; - m_FirstFree = elem; - --m_TotalElements; -} - - -//----------------------------------------------------------------------------- -// A test for debug mode only... -//----------------------------------------------------------------------------- -template -inline bool CUtlMultiList::IsElementInList( ListHandle_t list, I elem ) const -{ - if (!m_pElementList) - return true; - - return m_pElementList[elem] == list; -} - - -//----------------------------------------------------------------------------- -// list modification -//----------------------------------------------------------------------------- -template -void CUtlMultiList::LinkBefore( ListHandle_t list, I before, I elem ) -{ - Assert( IsValidIndex(elem) && IsValidList(list) ); - - // Unlink it if it's in the list at the moment - Unlink(list, elem); - - ListElem_t& newElem = InternalElement(elem); - - // The element *after* our newly linked one is the one we linked before. - newElem.m_Next = before; - - if (before == InvalidIndex()) - { - // In this case, we're linking to the end of the list, so reset the tail - newElem.m_Previous = m_List[list].m_Tail; - m_List[list].m_Tail = elem; - } - else - { - // Here, we're not linking to the end. Set the prev pointer to point to - // the element we're linking. - Assert( IsInList(before) ); - ListElem_t& beforeElem = InternalElement(before); - newElem.m_Previous = beforeElem.m_Previous; - beforeElem.m_Previous = elem; - } - - // Reset the head if we linked to the head of the list - if (newElem.m_Previous == InvalidIndex()) - m_List[list].m_Head = elem; - else - InternalElement(newElem.m_Previous).m_Next = elem; - - // one more element baby - ++m_List[list].m_Count; - - // Store the element into the list - if (m_pElementList) - m_pElementList[elem] = list; -} - -template -void CUtlMultiList::LinkAfter( ListHandle_t list, I after, I elem ) -{ - Assert( IsValidIndex(elem) ); - - // Unlink it if it's in the list at the moment - Unlink(list, elem); - - ListElem_t& newElem = InternalElement(elem); - - // The element *before* our newly linked one is the one we linked after - newElem.m_Previous = after; - if (after == InvalidIndex()) - { - // In this case, we're linking to the head of the list, reset the head - newElem.m_Next = m_List[list].m_Head; - m_List[list].m_Head = elem; - } - else - { - // Here, we're not linking to the end. Set the next pointer to point to - // the element we're linking. - Assert( IsInList(after) ); - ListElem_t& afterElem = InternalElement(after); - newElem.m_Next = afterElem.m_Next; - afterElem.m_Next = elem; - } - - // Reset the tail if we linked to the tail of the list - if (newElem.m_Next == InvalidIndex()) - m_List[list].m_Tail = elem; - else - InternalElement(newElem.m_Next).m_Previous = elem; - - // one more element baby - ++m_List[list].m_Count; - - // Store the element into the list - if (m_pElementList) - m_pElementList[elem] = list; -} - -template -void CUtlMultiList::Unlink( ListHandle_t list, I elem ) -{ - Assert( IsValidIndex(elem) && IsValidList(list) ); - - if (IsInList(elem)) - { - // Make sure the element is in the right list - Assert( IsElementInList( list, elem ) ); - ListElem_t& oldElem = InternalElement(elem); - - // If we're the first guy, reset the head - // otherwise, make our previous node's next pointer = our next - if (oldElem.m_Previous != InvalidIndex()) - InternalElement(oldElem.m_Previous).m_Next = oldElem.m_Next; - else - m_List[list].m_Head = oldElem.m_Next; - - // If we're the last guy, reset the tail - // otherwise, make our next node's prev pointer = our prev - if (oldElem.m_Next != InvalidIndex()) - InternalElement(oldElem.m_Next).m_Previous = oldElem.m_Previous; - else - m_List[list].m_Tail = oldElem.m_Previous; - - // This marks this node as not in the list, - // but not in the free list either - oldElem.m_Previous = oldElem.m_Next = elem; - - // One less puppy - --m_List[list].m_Count; - - // Store the element into the list - if (m_pElementList) - m_pElementList[elem] = m_List.InvalidIndex(); - } -} - -template -inline void CUtlMultiList::LinkToHead( ListHandle_t list, I elem ) -{ - LinkAfter( list, InvalidIndex(), elem ); -} - -template -inline void CUtlMultiList::LinkToTail( ListHandle_t list, I elem ) -{ - LinkBefore( list, InvalidIndex(), elem ); -} - - -//----------------------------------------------------------------------------- -// Insertion methods; allocates and links (uses default constructor) -//----------------------------------------------------------------------------- -template -I CUtlMultiList::InsertBefore( ListHandle_t list, I before ) -{ - // Make a new node - I newNode = Alloc(); - - // Link it in - LinkBefore( list, before, newNode ); - - // Construct the data - Construct( &Element(newNode) ); - - return newNode; -} - -template -I CUtlMultiList::InsertAfter( ListHandle_t list, I after ) -{ - // Make a new node - I newNode = Alloc(); - - // Link it in - LinkAfter( list, after, newNode ); - - // Construct the data - Construct( &Element(newNode) ); - - return newNode; -} - -template -inline I CUtlMultiList::AddToHead( ListHandle_t list ) -{ - return InsertAfter( list, InvalidIndex() ); -} - -template -inline I CUtlMultiList::AddToTail( ListHandle_t list ) -{ - return InsertBefore( list, InvalidIndex() ); -} - - -//----------------------------------------------------------------------------- -// Insertion methods; allocates and links (uses copy constructor) -//----------------------------------------------------------------------------- -template -I CUtlMultiList::InsertBefore( ListHandle_t list, I before, T const& src ) -{ - // Make a new node - I newNode = Alloc(); - - // Link it in - LinkBefore( list, before, newNode ); - - // Construct the data - CopyConstruct( &Element(newNode), src ); - - return newNode; -} - -template -I CUtlMultiList::InsertAfter( ListHandle_t list, I after, T const& src ) -{ - // Make a new node - I newNode = Alloc(); - - // Link it in - LinkAfter( list, after, newNode ); - - // Construct the data - CopyConstruct( &Element(newNode), src ); - - return newNode; -} - -template -inline I CUtlMultiList::AddToHead( ListHandle_t list, T const& src ) -{ - return InsertAfter( list, InvalidIndex(), src ); -} - -template -inline I CUtlMultiList::AddToTail( ListHandle_t list, T const& src ) -{ - return InsertBefore( list, InvalidIndex(), src ); -} - - -//----------------------------------------------------------------------------- -// Removal methods -//----------------------------------------------------------------------------- -template -void CUtlMultiList::Remove( ListHandle_t list, I elem ) -{ - if (IsInList(elem)) - Unlink(list, elem); - Free( elem ); -} - -// Removes all items in a single list -template -void CUtlMultiList::RemoveAll( ListHandle_t list ) -{ - Assert( IsValidList(list) ); - I i = Head(list); - I next; - while( i != InvalidIndex() ) - { - next = Next(i); - Remove(list, i); - i = next; - } -} - - -template -void CUtlMultiList::RemoveAll() -{ - if (m_MaxElementIndex == 0) - return; - - // Put everything into the free list - I prev = InvalidIndex(); - for (int i = (int)m_MaxElementIndex; --i >= 0; ) - { - // Invoke the destructor - if (IsValidIndex((I)i)) - Destruct( &Element((I)i) ); - - // next points to the next free list item - InternalElement((I)i).m_Next = prev; - - // Indicates it's in the free list - InternalElement((I)i).m_Previous = (I)i; - prev = (I)i; - } - - // First free points to the first element - m_FirstFree = 0; - - // Clear everything else out - for (I list = m_List.Head(); list != m_List.InvalidIndex(); list = m_List.Next(list) ) - { - m_List[list].m_Head = InvalidIndex(); - m_List[list].m_Tail = InvalidIndex(); - m_List[list].m_Count = 0; - } - - m_TotalElements = 0; -} - - -#include "tier0/memdbgoff.h" - -#endif // UTLMULTILIST_H diff --git a/Resources/NetHook/tier1/utlntree.h b/Resources/NetHook/tier1/utlntree.h deleted file mode 100644 index 1d937eb2..00000000 --- a/Resources/NetHook/tier1/utlntree.h +++ /dev/null @@ -1,624 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: N-way tree container class -// -// $Revision: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLNTREE_H -#define UTLNTREE_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "basetypes.h" -#include "utlmemory.h" -#include "tier0/dbg.h" - - -#define INVALID_NTREE_IDX ((I)~0) - -//----------------------------------------------------------------------------- -// class CUtlNTree: -// description: -// A lovely index-based linked list! T is the class type, I is the index -// type, which usually should be an unsigned short or smaller. -//----------------------------------------------------------------------------- -template -class CUtlNTree -{ -public: - typedef T ElemType_t; - typedef I IndexType_t; - - // constructor, destructor - CUtlNTree( int growSize = 0, int initSize = 0 ); - CUtlNTree( void *pMemory, int memsize ); - ~CUtlNTree( ); - - // gets particular elements - T& Element( I i ); - const T& Element( I i ) const; - T& operator[]( I i ); - const T& operator[]( I i ) const; - - // Make sure we have a particular amount of memory - void EnsureCapacity( int num ); - - // Clears the tree, doesn't deallocate memory - void RemoveAll(); - - // Memory deallocation - void Purge(); - - // Allocation/deallocation methods - I Alloc( ); - void Free( I elem ); - void FreeSubTree( I elem ); - - // list modification - void SetRoot( I root ); - void LinkChildBefore( I parent, I before, I elem ); - void LinkChildAfter( I parent, I after, I elem ); - void Unlink( I elem ); - - // Alloc + link combined - I InsertChildBefore( I parent, I before ); - I InsertChildAfter( I parent, I after ); - I InsertChildBefore( I parent, I before, const T &elem ); - I InsertChildAfter( I parent, I after, const T &elem ); - - // Unlink + free combined - void Remove( I elem ); - void RemoveSubTree( I elem ); - - // invalid index - inline static I InvalidIndex() { return INVALID_NTREE_IDX; } - inline static size_t ElementSize() { return sizeof(Node_t); } - - // list statistics - int Count() const; - I MaxElementIndex() const; - - // Traversing the list - I Root() const; - I FirstChild( I i ) const; - I PrevSibling( I i ) const; - I NextSibling( I i ) const; - I Parent( I i ) const; - - // Are nodes in the list or valid? - bool IsValidIndex( I i ) const; - bool IsInTree( I i ) const; - -protected: - // What the linked list element looks like - struct Node_t - { - T m_Element; - I m_Parent; - I m_FirstChild; - I m_PrevSibling; - I m_NextSibling; - - private: - // No copy constructor for these... - Node_t( const Node_t& ); - }; - - // constructs the class - void ConstructList(); - - // Allocates the element, doesn't call the constructor - I AllocInternal(); - - // Gets at the node element.... - Node_t& InternalNode( I i ) { return m_Memory[i]; } - const Node_t& InternalNode( I i ) const { return m_Memory[i]; } - - void ResetDbgInfo() - { - m_pElements = m_Memory.Base(); - } - - // copy constructors not allowed - CUtlNTree( CUtlNTree const& tree ) { Assert(0); } - - CUtlMemory m_Memory; - I m_Root; - I m_FirstFree; - I m_ElementCount; // The number actually in the tree - I m_MaxElementIndex; // The max index we've ever assigned - - // For debugging purposes; - // it's in release builds so this can be used in libraries correctly - Node_t *m_pElements; -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template -CUtlNTree::CUtlNTree( int growSize, int initSize ) : - m_Memory(growSize, initSize) -{ - ConstructList(); - ResetDbgInfo(); -} - -template -CUtlNTree::CUtlNTree( void* pMemory, int memsize ) : - m_Memory((ListElem_t *)pMemory, memsize/sizeof(ListElem_t)) -{ - ConstructList(); - ResetDbgInfo(); -} - -template -CUtlNTree::~CUtlNTree( ) -{ - RemoveAll(); -} - -template -void CUtlNTree::ConstructList() -{ - m_Root = InvalidIndex(); - m_FirstFree = InvalidIndex(); - m_ElementCount = m_MaxElementIndex = 0; -} - - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- -template -inline T& CUtlNTree::Element( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline const T& CUtlNTree::Element( I i ) const -{ - return m_Memory[i].m_Element; -} - -template -inline T& CUtlNTree::operator[]( I i ) -{ - return m_Memory[i].m_Element; -} - -template -inline const T& CUtlNTree::operator[]( I i ) const -{ - return m_Memory[i].m_Element; -} - - -//----------------------------------------------------------------------------- -// list statistics -//----------------------------------------------------------------------------- -template -inline int CUtlNTree::Count() const -{ - return m_ElementCount; -} - -template -inline I CUtlNTree::MaxElementIndex() const -{ - return m_MaxElementIndex; -} - - -//----------------------------------------------------------------------------- -// Traversing the list -//----------------------------------------------------------------------------- -template -inline I CUtlNTree::Root() const -{ - return m_Root; -} - -template -inline I CUtlNTree::FirstChild( I i ) const -{ - Assert( IsInTree(i) ); - return InternalNode(i).m_FirstChild; -} - -template -inline I CUtlNTree::PrevSibling( I i ) const -{ - Assert( IsInTree(i) ); - return InternalNode(i).m_PrevSibling; -} - -template -inline I CUtlNTree::NextSibling( I i ) const -{ - Assert( IsInTree(i) ); - return InternalNode(i).m_NextSibling; -} - -template -inline I CUtlNTree::Parent( I i ) const -{ - Assert( IsInTree(i) ); - return InternalNode(i).m_Parent; -} - - -//----------------------------------------------------------------------------- -// Are nodes in the list or valid? -//----------------------------------------------------------------------------- -template -inline bool CUtlNTree::IsValidIndex( I i ) const -{ - return (i < m_MaxElementIndex) && (i >= 0); -} - -template -inline bool CUtlNTree::IsInTree( I i ) const -{ - return (i < m_MaxElementIndex) && (i >= 0) && (InternalNode(i).m_PrevSibling != i); -} - - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- -template< class T, class I > -void CUtlNTree::EnsureCapacity( int num ) -{ - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Deallocate memory -//----------------------------------------------------------------------------- -template -void CUtlNTree::Purge() -{ - RemoveAll(); - m_Memory.Purge( ); - m_FirstFree = InvalidIndex(); - m_MaxElementIndex = 0; - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Node allocation/deallocation -//----------------------------------------------------------------------------- -template -I CUtlNTree::AllocInternal( ) -{ - I elem; - if ( m_FirstFree == INVALID_NTREE_IDX ) - { - // Nothing in the free list; add. - // Since nothing is in the free list, m_MaxElementIndex == total # of elements - // the list knows about. - if ((int)m_MaxElementIndex == m_Memory.NumAllocated()) - { - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.Grow(); - } - - Assert( m_MaxElementIndex != INVALID_NTREE_IDX ); - - elem = (I)m_MaxElementIndex; - ++m_MaxElementIndex; - - if ( elem == InvalidIndex() ) - { - Error("CUtlNTree overflow!\n"); - } - } - else - { - elem = m_FirstFree; - m_FirstFree = InternalNode( m_FirstFree ).m_NextSibling; - } - - Node_t &node = InternalNode( elem ); - node.m_NextSibling = node.m_PrevSibling = node.m_Parent = node.m_FirstChild = INVALID_NTREE_IDX; - ResetDbgInfo(); - - // one more element baby - ++m_ElementCount; - - return elem; -} - -template -I CUtlNTree::Alloc( ) -{ - I elem = AllocInternal(); - Construct( &Element(elem) ); - return elem; -} - -template -void CUtlNTree::Free( I elem ) -{ - Assert( IsInTree( elem ) ); - Unlink( elem ); - - // If there's children, this will result in leaks. Use FreeSubTree instead. - Assert( FirstChild( elem ) == INVALID_NTREE_IDX ); - - Node_t &node = InternalNode( elem ); - Destruct( &node.m_Element ); - node.m_NextSibling = m_FirstFree; - node.m_PrevSibling = elem; // Marks it as being in the free list - node.m_Parent = node.m_FirstChild = INVALID_NTREE_IDX; - m_FirstFree = elem; - - // one less element baby - --m_ElementCount; -} - -template -void CUtlNTree::FreeSubTree( I elem ) -{ - Assert( IsValidIndex( elem ) ); - - I child = FirstChild( elem ); - while ( child != INVALID_NTREE_IDX ) - { - I next = NextSibling( child ); - FreeSubTree( child ); - child = next; - } - - Free( elem ); -} - - -//----------------------------------------------------------------------------- -// Clears the tree -//----------------------------------------------------------------------------- -template -void CUtlNTree::RemoveAll() -{ - if ( m_MaxElementIndex == 0 ) - return; - - // Put everything into the free list (even unlinked things ) - I prev = InvalidIndex(); - for (int i = (int)m_MaxElementIndex; --i >= 0; prev = (I)i ) - { - Node_t &node = InternalNode( i ); - if ( IsInTree( i ) ) - { - Destruct( &node.m_Element ); - } - - node.m_NextSibling = prev; - node.m_PrevSibling = (I)i; // Marks it as being in the free list - node.m_Parent = node.m_FirstChild = INVALID_NTREE_IDX; - } - - // First free points to the first element - m_FirstFree = 0; - - // Clear everything else out - m_Root = INVALID_NTREE_IDX; - m_ElementCount = 0; -} - - -//----------------------------------------------------------------------------- -// list modification -//----------------------------------------------------------------------------- -template -void CUtlNTree::SetRoot( I root ) -{ - // Resetting the root while it's got stuff in it is bad... - Assert( m_Root == InvalidIndex() ); - m_Root = root; -} - - -//----------------------------------------------------------------------------- -// Links a node after a particular node -//----------------------------------------------------------------------------- -template -void CUtlNTree::LinkChildAfter( I parent, I after, I elem ) -{ - Assert( IsInTree(elem) ); - - // Unlink it if it's in the list at the moment - Unlink(elem); - - Node_t& newElem = InternalNode(elem); - newElem.m_Parent = parent; - newElem.m_PrevSibling = after; - if ( after != INVALID_NTREE_IDX ) - { - Node_t& prevSiblingNode = InternalNode( after ); - newElem.m_NextSibling = prevSiblingNode.m_NextSibling; - prevSiblingNode.m_NextSibling = elem; - } - else - { - if ( parent != INVALID_NTREE_IDX ) - { - Node_t& parentNode = InternalNode( parent ); - newElem.m_NextSibling = parentNode.m_FirstChild; - parentNode.m_FirstChild = elem; - } - else - { - newElem.m_NextSibling = m_Root; - if ( m_Root != INVALID_NTREE_IDX ) - { - Node_t& rootNode = InternalNode( m_Root ); - rootNode.m_PrevSibling = elem; - } - m_Root = elem; - } - } - - if ( newElem.m_NextSibling != INVALID_NTREE_IDX ) - { - Node_t& nextSiblingNode = InternalNode( newElem.m_NextSibling ); - nextSiblingNode.m_PrevSibling = elem; - } -} - - -//----------------------------------------------------------------------------- -// Links a node before a particular node -//----------------------------------------------------------------------------- -template -void CUtlNTree::LinkChildBefore( I parent, I before, I elem ) -{ - Assert( IsValidIndex(elem) ); - - if ( before != INVALID_NTREE_IDX ) - { - LinkChildAfter( parent, InternalNode( before ).m_PrevSibling, elem ); - return; - } - - // NOTE: I made the choice to do an O(n) operation here - // instead of store more data per node (LastChild). - // This might not be the right choice. Revisit if we get perf problems. - I after; - if ( parent != INVALID_NTREE_IDX ) - { - after = InternalNode( parent ).m_FirstChild; - } - else - { - after = m_Root; - } - - if ( after == INVALID_NTREE_IDX ) - { - LinkChildAfter( parent, after, elem ); - return; - } - - I next = InternalNode( after ).m_NextSibling; - while ( next != InvalidIndex() ) - { - after = next; - next = InternalNode( next ).m_NextSibling; - } - - LinkChildAfter( parent, after, elem ); -} - - -//----------------------------------------------------------------------------- -// Unlinks a node from the tree -//----------------------------------------------------------------------------- -template -void CUtlNTree::Unlink( I elem ) -{ - Assert( IsInTree(elem) ); - - Node_t *pOldNode = &InternalNode( elem ); - - // If we're the first guy, reset the head - // otherwise, make our previous node's next pointer = our next - if ( pOldNode->m_PrevSibling != INVALID_NTREE_IDX ) - { - InternalNode( pOldNode->m_PrevSibling ).m_NextSibling = pOldNode->m_NextSibling; - } - else - { - if ( pOldNode->m_Parent != INVALID_NTREE_IDX ) - { - InternalNode( pOldNode->m_Parent ).m_FirstChild = pOldNode->m_NextSibling; - } - else if ( m_Root == elem ) - { - m_Root = pOldNode->m_NextSibling; - } - } - - // If we're the last guy, reset the tail - // otherwise, make our next node's prev pointer = our prev - if ( pOldNode->m_NextSibling != INVALID_NTREE_IDX ) - { - InternalNode( pOldNode->m_NextSibling ).m_PrevSibling = pOldNode->m_PrevSibling; - } - - // Unlink everything except children - pOldNode->m_Parent = pOldNode->m_PrevSibling = pOldNode->m_NextSibling = INVALID_NTREE_IDX; -} - - -//----------------------------------------------------------------------------- -// Alloc + link combined -//----------------------------------------------------------------------------- -template -I CUtlNTree::InsertChildBefore( I parent, I before ) -{ - I elem = AllocInternal(); - Construct( &Element( elem ) ); - LinkChildBefore( parent, before, elem ); - return elem; -} - -template -I CUtlNTree::InsertChildAfter( I parent, I after ) -{ - I elem = AllocInternal(); - Construct( &Element( elem ) ); - LinkChildAfter( parent, after, elem ); - return elem; -} - -template -I CUtlNTree::InsertChildBefore( I parent, I before, const T &data ) -{ - I elem = AllocInternal(); - CopyConstruct( &Element( elem ), data ); - LinkChildBefore( parent, before, elem ); - return elem; -} - -template -I CUtlNTree::InsertChildAfter( I parent, I after, const T &data ) -{ - I elem = AllocInternal(); - CopyConstruct( &Element( elem ), data ); - LinkChildAfter( parent, after, elem ); - return elem; -} - - -//----------------------------------------------------------------------------- -// Unlink + free combined -//----------------------------------------------------------------------------- -template -void CUtlNTree::Remove( I elem ) -{ - Unlink( elem ); - Free( elem ); -} - -template -void CUtlNTree::RemoveSubTree( I elem ) -{ - UnlinkSubTree( elem ); - Free( elem ); -} - - -#endif // UTLNTREE_H diff --git a/Resources/NetHook/tier1/utlobjectreference.h b/Resources/NetHook/tier1/utlobjectreference.h deleted file mode 100644 index 6b09b04c..00000000 --- a/Resources/NetHook/tier1/utlobjectreference.h +++ /dev/null @@ -1,165 +0,0 @@ -//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======// -// -// $Revision: $ -// $NoKeywords: $ -//===========================================================================// - -#ifndef UTLOBJECTREFERENCE_H -#define UTLOBJECTREFERENCE_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier1/utlintrusivelist.h" -#include "mathlib/mathlib.h" - - -// Purpose: class for keeping track of all the references that exist to an object. When the object -// being referenced is freed, all of the references pointing at it will become null. -// -// To Use: -// Add a DECLARE_REFERENCED_CLASS to the class that you want to use CutlReferences with. -// Replace pointers to that class with CUtlReferences. -// Check these references for null in appropriate places. -// -// NOTE : You can still happily use pointers instead of references where you want to - these -// pointers will not magically become null like references would, but if you know no one is going -// to delete the underlying object during a partcular section of code, it doesn't -// matter. Basically, CUtlReferences don't rely on every use of an object using one. - - - - -template class CUtlReference -{ -public: - FORCEINLINE CUtlReference(void) - { - m_pNext = m_pPrev = NULL; - m_pObject = NULL; - } - - FORCEINLINE CUtlReference(T *pObj) - { - m_pNext = m_pPrev = NULL; - AddRef( pObj ); - } - - FORCEINLINE ~CUtlReference(void) - { - KillRef(); - } - - FORCEINLINE void Set(T *pObj) - { - if ( m_pObject != pObj ) - { - KillRef(); - AddRef( pObj ); - } - } - - FORCEINLINE T * operator()(void) const - { - return m_pObject; - } - - FORCEINLINE operator T*() - { - return m_pObject; - } - - FORCEINLINE operator const T*() const - { - return m_pObject; - } - - FORCEINLINE T* operator->() - { - return m_pObject; - } - - FORCEINLINE const T* operator->() const - { - return m_pObject; - } - - FORCEINLINE CUtlReference &operator=( const CUtlReference& otherRef ) - { - Set( otherRef.m_pObject ); - return *this; - } - - FORCEINLINE CUtlReference &operator=( T *pObj ) - { - Set( pObj ); - return *this; - } - - - FORCEINLINE bool operator==( const CUtlReference& o ) const - { - return ( o.m_pObject == m_pObject ); - } - -public: - CUtlReference *m_pNext; - CUtlReference *m_pPrev; - - T *m_pObject; - - FORCEINLINE void AddRef( T *pObj ) - { - m_pObject = pObj; - if ( pObj ) - { - pObj->m_References.AddToHead( this ); - } - } - - FORCEINLINE void KillRef(void) - { - if ( m_pObject ) - { - m_pObject->m_References.RemoveNode( this ); - m_pObject = NULL; - } - } - -}; - -template class CUtlReferenceList : public CUtlIntrusiveDList< CUtlReference > -{ -public: - ~CUtlReferenceList( void ) - { - CUtlReference *i = CUtlIntrusiveDList >::m_pHead; - while( i ) - { - CUtlReference *n = i->m_pNext; - i->m_pNext = NULL; - i->m_pPrev = NULL; - i->m_pObject = NULL; - i = n; - } - CUtlIntrusiveDList >::m_pHead = NULL; - } -}; - - -//----------------------------------------------------------------------------- -// Put this macro in classes that are referenced by CUtlReference -//----------------------------------------------------------------------------- -#define DECLARE_REFERENCED_CLASS( _className ) \ - private: \ - CUtlReferenceList< _className > m_References; \ - template friend class CUtlReference; - - -#endif - - - - - diff --git a/Resources/NetHook/tier1/utlpriorityqueue.h b/Resources/NetHook/tier1/utlpriorityqueue.h deleted file mode 100644 index 98486a6c..00000000 --- a/Resources/NetHook/tier1/utlpriorityqueue.h +++ /dev/null @@ -1,198 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLPRIORITYQUEUE_H -#define UTLPRIORITYQUEUE_H -#ifdef _WIN32 -#pragma once -#endif - -#include "utlvector.h" - -// T is the type stored in the queue, it must include the priority -// The head of the list contains the element with GREATEST priority -// configure the LessFunc_t to get the desired queue order -template< class T > -class CUtlPriorityQueue -{ -public: - // Less func typedef - // Returns true if the first parameter is "less priority" than the second - // Items that are "less priority" sort toward the tail of the queue - typedef bool (*LessFunc_t)( T const&, T const& ); - - typedef T ElemType_t; - - // constructor: lessfunc is required, but may be set after the constructor with - // SetLessFunc - CUtlPriorityQueue( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 ); - CUtlPriorityQueue( T *pMemory, int numElements, LessFunc_t lessfunc = 0 ); - - // gets particular elements - inline T const& ElementAtHead() const { return m_heap.Element(0); } - - inline bool IsValidIndex(int index) { return m_heap.IsValidIndex(index); } - - // O(lgn) to rebalance the heap - void RemoveAtHead(); - void RemoveAt( int index ); - - // O(lgn) to rebalance heap - void Insert( T const &element ); - // Sets the less func - void SetLessFunc( LessFunc_t func ); - - // Returns the count of elements in the queue - inline int Count() const { return m_heap.Count(); } - - // doesn't deallocate memory - void RemoveAll() { m_heap.RemoveAll(); } - - // Memory deallocation - void Purge() { m_heap.Purge(); } - - inline const T & Element( int index ) const { return m_heap.Element(index); } - -protected: - CUtlVector m_heap; - - void Swap( int index1, int index2 ); - - // Used for sorting. - LessFunc_t m_LessFunc; -}; - -template< class T > -inline CUtlPriorityQueue::CUtlPriorityQueue( int growSize, int initSize, LessFunc_t lessfunc ) : - m_heap(growSize, initSize), m_LessFunc(lessfunc) -{ -} - -template< class T > -inline CUtlPriorityQueue::CUtlPriorityQueue( T *pMemory, int numElements, LessFunc_t lessfunc ) : - m_heap(pMemory, numElements), m_LessFunc(lessfunc) -{ -} - -template -void CUtlPriorityQueue::RemoveAtHead() -{ - m_heap.FastRemove( 0 ); - int index = 0; - - int count = Count(); - if ( !count ) - return; - - int half = count/2; - int larger = index; - while ( index < half ) - { - int child = ((index+1) * 2) - 1; // if we wasted an element, this math would be more compact (1 based array) - if ( child < count ) - { - // Item has been filtered down to its proper place, terminate. - if ( m_LessFunc( m_heap[index], m_heap[child] ) ) - { - // mark the potential swap and check the other child - larger = child; - } - } - // go to sibling - child++; - if ( child < count ) - { - // If this child is larger, swap it instead - if ( m_LessFunc( m_heap[larger], m_heap[child] ) ) - larger = child; - } - - if ( larger == index ) - break; - - // swap with the larger child - Swap( index, larger ); - index = larger; - } -} - - -template -void CUtlPriorityQueue::RemoveAt( int index ) -{ - Assert(m_heap.IsValidIndex(index)); - m_heap.FastRemove( index ); - - int count = Count(); - if ( !count ) - return; - - int half = count/2; - int larger = index; - while ( index < half ) - { - int child = ((index+1) * 2) - 1; // if we wasted an element, this math would be more compact (1 based array) - if ( child < count ) - { - // Item has been filtered down to its proper place, terminate. - if ( m_LessFunc( m_heap[index], m_heap[child] ) ) - { - // mark the potential swap and check the other child - larger = child; - } - } - // go to sibling - child++; - if ( child < count ) - { - // If this child is larger, swap it instead - if ( m_LessFunc( m_heap[larger], m_heap[child] ) ) - larger = child; - } - - if ( larger == index ) - break; - - // swap with the larger child - Swap( index, larger ); - index = larger; - } -} - -template -void CUtlPriorityQueue::Insert( T const &element ) -{ - int index = m_heap.AddToTail(); - m_heap[index] = element; - - while ( index != 0 ) - { - int parent = ((index+1) / 2) - 1; - if ( m_LessFunc( m_heap[index], m_heap[parent] ) ) - break; - - // swap with parent and repeat - Swap( parent, index ); - index = parent; - } -} - -template -void CUtlPriorityQueue::Swap( int index1, int index2 ) -{ - T tmp = m_heap[index1]; - m_heap[index1] = m_heap[index2]; - m_heap[index2] = tmp; -} - -template -void CUtlPriorityQueue::SetLessFunc( LessFunc_t lessfunc ) -{ - m_LessFunc = lessfunc; -} - -#endif // UTLPRIORITYQUEUE_H diff --git a/Resources/NetHook/tier1/utlqueue.h b/Resources/NetHook/tier1/utlqueue.h deleted file mode 100644 index a148560e..00000000 --- a/Resources/NetHook/tier1/utlqueue.h +++ /dev/null @@ -1,114 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLQUEUE_H -#define UTLQUEUE_H -#ifdef _WIN32 -#pragma once -#endif - -#include "utlvector.h" - -// T is the type stored in the stack -template< class T > -class CUtlQueue -{ -public: - - // constructor: lessfunc is required, but may be set after the constructor with - // SetLessFunc - CUtlQueue( int growSize = 0, int initSize = 0 ); - CUtlQueue( T *pMemory, int numElements ); - - // return the item from the front of the queue and delete it - T const& RemoveAtHead(); - // return the item from the end of the queue and delete it - T const& RemoveAtTail(); - - // return item at the front of the queue - T const& Head(); - // return item at the end of the queue - T const& Tail(); - - // put a new item on the stack - void Insert( T const &element ); - - // checks if an element of this value already exists on the stack, returns true if it does - bool Check( T const element ); - - // Returns the count of elements in the stack - int Count() const { return m_heap.Count(); } - - // doesn't deallocate memory - void RemoveAll() { m_heap.RemoveAll(); } - - // Memory deallocation - void Purge() { m_heap.Purge(); } - -protected: - CUtlVector m_heap; - T m_current; -}; - -template< class T > -inline CUtlQueue::CUtlQueue( int growSize, int initSize ) : - m_heap(growSize, initSize) -{ -} - -template< class T > -inline CUtlQueue::CUtlQueue( T *pMemory, int numElements ) : - m_heap(pMemory, numElements) -{ -} - -template -inline T const& CUtlQueue::RemoveAtHead() -{ - m_current = m_heap[0]; - m_heap.Remove((int)0); - return m_current; -} - -template -inline T const& CUtlQueue::RemoveAtTail() -{ - m_current = m_heap[ m_heap.Count() - 1 ]; - m_heap.Remove((int)(m_heap.Count() - 1)); - return m_current; -} - -template -inline T const& CUtlQueue::Head() -{ - m_current = m_heap[0]; - return m_current; -} - -template -inline T const& CUtlQueue::Tail() -{ - m_current = m_heap[ m_heap.Count() - 1 ]; - return m_current; -} - -template -void CUtlQueue::Insert( T const &element ) -{ - int index = m_heap.AddToTail(); - m_heap[index] = element; -} - -template -bool CUtlQueue::Check( T const element ) -{ - int index = m_heap.Find(element); - return ( index != -1 ); -} - - -#endif // UTLQUEUE_H diff --git a/Resources/NetHook/tier1/utlrbtree.h b/Resources/NetHook/tier1/utlrbtree.h deleted file mode 100644 index ff30898b..00000000 --- a/Resources/NetHook/tier1/utlrbtree.h +++ /dev/null @@ -1,1557 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#ifndef UTLRBTREE_H -#define UTLRBTREE_H - -#include "tier1/utlmemory.h" -#include "tier1/utlfixedmemory.h" -#include "tier1/utlblockmemory.h" - -//----------------------------------------------------------------------------- -// Tool to generate a default compare function for any type that implements -// operator<, including all simple types -//----------------------------------------------------------------------------- - -template -class CDefOps -{ -public: - static bool LessFunc( const T &lhs, const T &rhs ) { return ( lhs < rhs ); } -}; - -#define DefLessFunc( type ) CDefOps< type >::LessFunc - -//------------------------------------- - -inline bool StringLessThan( const char * const &lhs, const char * const &rhs) { return ( strcmp( lhs, rhs) < 0 ); } -inline bool CaselessStringLessThan( const char * const &lhs, const char * const &rhs ) { return ( stricmp( lhs, rhs) < 0 ); } - -// Same as CaselessStringLessThan, but it ignores differences in / and \. -inline bool CaselessStringLessThanIgnoreSlashes( const char * const &lhs, const char * const &rhs ) -{ - const char *pa = lhs; - const char *pb = rhs; - while ( *pa && *pb ) - { - char a = *pa; - char b = *pb; - - // Check for dir slashes. - if ( a == '/' || a == '\\' ) - { - if ( b != '/' && b != '\\' ) - return ('/' < b); - } - else - { - if ( a >= 'a' && a <= 'z' ) - a = 'A' + (a - 'a'); - - if ( b >= 'a' && b <= 'z' ) - b = 'A' + (b - 'a'); - - if ( a > b ) - return false; - else if ( a < b ) - return true; - } - ++pa; - ++pb; - } - - return false; -} - -//------------------------------------- -// inline these two templates to stop multiple definitions of the same code -template <> inline bool CDefOps::LessFunc( const char * const &lhs, const char * const &rhs ) { return StringLessThan( lhs, rhs ); } -template <> inline bool CDefOps::LessFunc( char * const &lhs, char * const &rhs ) { return StringLessThan( lhs, rhs ); } - -//------------------------------------- - -template -void SetDefLessFunc( RBTREE_T &RBTree ) -{ -#ifdef _WIN32 - RBTree.SetLessFunc( DefLessFunc( RBTREE_T::KeyType_t ) ); -#elif _LINUX - RBTree.SetLessFunc( DefLessFunc( typename RBTREE_T::KeyType_t ) ); -#endif -} - -//----------------------------------------------------------------------------- -// A red-black binary search tree -//----------------------------------------------------------------------------- - -template < class I > -struct UtlRBTreeLinks_t -{ - I m_Left; - I m_Right; - I m_Parent; - I m_Tag; -}; - -template < class T, class I > -struct UtlRBTreeNode_t : public UtlRBTreeLinks_t< I > -{ - T m_Data; -}; - -template < class T, class I = unsigned short, typename L = bool (*)( const T &, const T & ), class M = CUtlMemory< UtlRBTreeNode_t< T, I >, I > > -class CUtlRBTree -{ -public: - - typedef T KeyType_t; - typedef T ElemType_t; - typedef I IndexType_t; - - // Less func typedef - // Returns true if the first parameter is "less" than the second - typedef L LessFunc_t; - - // constructor, destructor - // Left at growSize = 0, the memory will first allocate 1 element and double in size - // at each increment. - // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below - CUtlRBTree( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 ); - CUtlRBTree( const LessFunc_t &lessfunc ); - ~CUtlRBTree( ); - - void EnsureCapacity( int num ); - - void CopyFrom( const CUtlRBTree &other ); - - // gets particular elements - T& Element( I i ); - T const &Element( I i ) const; - T& operator[]( I i ); - T const &operator[]( I i ) const; - - // Gets the root - I Root() const; - - // Num elements - unsigned int Count() const; - - // Max "size" of the vector - // it's not generally safe to iterate from index 0 to MaxElement()-1 - // it IS safe to do so when using CUtlMemory as the allocator, - // but we should really remove patterns using this anyways, for safety and generality - I MaxElement() const; - - // Gets the children - I Parent( I i ) const; - I LeftChild( I i ) const; - I RightChild( I i ) const; - - // Tests if a node is a left or right child - bool IsLeftChild( I i ) const; - bool IsRightChild( I i ) const; - - // Tests if root or leaf - bool IsRoot( I i ) const; - bool IsLeaf( I i ) const; - - // Checks if a node is valid and in the tree - bool IsValidIndex( I i ) const; - - // Checks if the tree as a whole is valid - bool IsValid() const; - - // Invalid index - static I InvalidIndex(); - - // returns the tree depth (not a very fast operation) - int Depth( I node ) const; - int Depth() const; - - // Sets the less func - void SetLessFunc( const LessFunc_t &func ); - - // Allocation method - I NewNode(); - - // Insert method (inserts in order) - I Insert( T const &insert ); - void Insert( const T *pArray, int nItems ); - I InsertIfNotFound( T const &insert ); - - // Find method - I Find( T const &search ) const; - - // Remove methods - void RemoveAt( I i ); - bool Remove( T const &remove ); - void RemoveAll( ); - void Purge(); - - // Allocation, deletion - void FreeNode( I i ); - - // Iteration - I FirstInorder() const; - I NextInorder( I i ) const; - I PrevInorder( I i ) const; - I LastInorder() const; - - I FirstPreorder() const; - I NextPreorder( I i ) const; - I PrevPreorder( I i ) const; - I LastPreorder( ) const; - - I FirstPostorder() const; - I NextPostorder( I i ) const; - - // If you change the search key, this can be used to reinsert the - // element into the tree. - void Reinsert( I elem ); - - // swap in place - void Swap( CUtlRBTree< T, I, L > &that ); - -private: - // Can't copy the tree this way! - CUtlRBTree& operator=( const CUtlRBTree &other ); - -protected: - enum NodeColor_t - { - RED = 0, - BLACK - }; - - typedef UtlRBTreeNode_t< T, I > Node_t; - typedef UtlRBTreeLinks_t< I > Links_t; - - // Sets the children - void SetParent( I i, I parent ); - void SetLeftChild( I i, I child ); - void SetRightChild( I i, I child ); - void LinkToParent( I i, I parent, bool isLeft ); - - // Gets at the links - Links_t const &Links( I i ) const; - Links_t &Links( I i ); - - // Checks if a link is red or black - bool IsRed( I i ) const; - bool IsBlack( I i ) const; - - // Sets/gets node color - NodeColor_t Color( I i ) const; - void SetColor( I i, NodeColor_t c ); - - // operations required to preserve tree balance - void RotateLeft(I i); - void RotateRight(I i); - void InsertRebalance(I i); - void RemoveRebalance(I i); - - // Insertion, removal - I InsertAt( I parent, bool leftchild ); - - // copy constructors not allowed - CUtlRBTree( CUtlRBTree const &tree ); - - // Inserts a node into the tree, doesn't copy the data in. - void FindInsertionPosition( T const &insert, I &parent, bool &leftchild ); - - // Remove and add back an element in the tree. - void Unlink( I elem ); - void Link( I elem ); - - // Used for sorting. - LessFunc_t m_LessFunc; - - M m_Elements; - I m_Root; - I m_NumElements; - I m_FirstFree; - typename M::Iterator_t m_LastAlloc; // the last index allocated - - Node_t* m_pElements; - - FORCEINLINE M const &Elements( void ) const - { - return m_Elements; - } - - - void ResetDbgInfo() - { - m_pElements = (Node_t*)m_Elements.Base(); - } -}; - -// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice -template < class T, class I = int, typename L = bool (*)( const T &, const T & ) > -class CUtlFixedRBTree : public CUtlRBTree< T, I, L, CUtlFixedMemory< UtlRBTreeNode_t< T, I > > > -{ -public: - - typedef L LessFunc_t; - - CUtlFixedRBTree( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 ) - : CUtlRBTree< T, I, L, CUtlFixedMemory< UtlRBTreeNode_t< T, I > > >( growSize, initSize, lessfunc ) {} - CUtlFixedRBTree( const LessFunc_t &lessfunc ) - : CUtlRBTree< T, I, L, CUtlFixedMemory< UtlRBTreeNode_t< T, I > > >( lessfunc ) {} - - bool IsValidIndex( I i ) const - { - if ( !Elements().IsIdxValid( i ) ) - return false; - -#ifdef _DEBUG // it's safe to skip this here, since the only way to get indices after m_LastAlloc is to use MaxElement() - if ( Elements().IsIdxAfter( i, this->m_LastAlloc ) ) - { - Assert( 0 ); - return false; // don't read values that have been allocated, but not constructed - } -#endif - - return LeftChild(i) != i; - } - -protected: - void ResetDbgInfo() {} - -private: - // this doesn't make sense for fixed rbtrees, since there's no useful max pointer, and the index space isn't contiguous anyways - I MaxElement() const; -}; - -// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice -template < class T, class I = unsigned short, typename L = bool (*)( const T &, const T & ) > -class CUtlBlockRBTree : public CUtlRBTree< T, I, L, CUtlBlockMemory< UtlRBTreeNode_t< T, I >, I > > -{ -public: - typedef L LessFunc_t; - CUtlBlockRBTree( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 ) - : CUtlRBTree< T, I, L, CUtlBlockMemory< UtlRBTreeNode_t< T, I >, I > >( growSize, initSize, lessfunc ) {} - CUtlBlockRBTree( const LessFunc_t &lessfunc ) - : CUtlRBTree< T, I, L, CUtlBlockMemory< UtlRBTreeNode_t< T, I >, I > >( lessfunc ) {} -protected: - void ResetDbgInfo() {} -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline CUtlRBTree::CUtlRBTree( int growSize, int initSize, const LessFunc_t &lessfunc ) : -m_Elements( growSize, initSize ), -m_LessFunc( lessfunc ), -m_Root( InvalidIndex() ), -m_NumElements( 0 ), -m_FirstFree( InvalidIndex() ), -m_LastAlloc( m_Elements.InvalidIterator() ) -{ - ResetDbgInfo(); -} - -template < class T, class I, typename L, class M > -inline CUtlRBTree::CUtlRBTree( const LessFunc_t &lessfunc ) : -m_Elements( 0, 0 ), -m_LessFunc( lessfunc ), -m_Root( InvalidIndex() ), -m_NumElements( 0 ), -m_FirstFree( InvalidIndex() ), -m_LastAlloc( m_Elements.InvalidIterator() ) -{ - ResetDbgInfo(); -} - -template < class T, class I, typename L, class M > -inline CUtlRBTree::~CUtlRBTree() -{ - Purge(); -} - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::EnsureCapacity( int num ) -{ - m_Elements.EnsureCapacity( num ); -} - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::CopyFrom( const CUtlRBTree &other ) -{ - Purge(); - m_Elements.EnsureCapacity( other.m_Elements.Count() ); - memcpy( m_Elements.Base(), other.m_Elements.Base(), other.m_Elements.Count() * sizeof( T ) ); - m_LessFunc = other.m_LessFunc; - m_Root = other.m_Root; - m_NumElements = other.m_NumElements; - m_FirstFree = other.m_FirstFree; - m_LastAlloc = other.m_LastAlloc; - ResetDbgInfo(); -} - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline T &CUtlRBTree::Element( I i ) -{ - return m_Elements[i].m_Data; -} - -template < class T, class I, typename L, class M > -inline T const &CUtlRBTree::Element( I i ) const -{ - return m_Elements[i].m_Data; -} - -template < class T, class I, typename L, class M > -inline T &CUtlRBTree::operator[]( I i ) -{ - return Element(i); -} - -template < class T, class I, typename L, class M > -inline T const &CUtlRBTree::operator[]( I i ) const -{ - return Element(i); -} - -//----------------------------------------------------------------------------- -// -// various accessors -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Gets the root -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::Root() const -{ - return m_Root; -} - -//----------------------------------------------------------------------------- -// Num elements -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline unsigned int CUtlRBTree::Count() const -{ - return (unsigned int)m_NumElements; -} - -//----------------------------------------------------------------------------- -// Max "size" of the vector -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::MaxElement() const -{ - return ( I )m_Elements.NumAllocated(); -} - - -//----------------------------------------------------------------------------- -// Gets the children -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::Parent( I i ) const -{ - return Links(i).m_Parent; -} - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::LeftChild( I i ) const -{ - return Links(i).m_Left; -} - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::RightChild( I i ) const -{ - return Links(i).m_Right; -} - -//----------------------------------------------------------------------------- -// Tests if a node is a left or right child -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsLeftChild( I i ) const -{ - return LeftChild(Parent(i)) == i; -} - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsRightChild( I i ) const -{ - return RightChild(Parent(i)) == i; -} - - -//----------------------------------------------------------------------------- -// Tests if root or leaf -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsRoot( I i ) const -{ - return i == m_Root; -} - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsLeaf( I i ) const -{ - return (LeftChild(i) == InvalidIndex()) && (RightChild(i) == InvalidIndex()); -} - - -//----------------------------------------------------------------------------- -// Checks if a node is valid and in the tree -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsValidIndex( I i ) const -{ - if ( !m_Elements.IsIdxValid( i ) ) - return false; - - if ( m_Elements.IsIdxAfter( i, m_LastAlloc ) ) - return false; // don't read values that have been allocated, but not constructed - - return LeftChild(i) != i; -} - - -//----------------------------------------------------------------------------- -// Invalid index -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline I CUtlRBTree::InvalidIndex() -{ - return ( I )M::InvalidIndex(); -} - - -//----------------------------------------------------------------------------- -// returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline int CUtlRBTree::Depth() const -{ - return Depth(Root()); -} - -//----------------------------------------------------------------------------- -// Sets the children -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::SetParent( I i, I parent ) -{ - Links(i).m_Parent = parent; -} - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::SetLeftChild( I i, I child ) -{ - Links(i).m_Left = child; -} - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::SetRightChild( I i, I child ) -{ - Links(i).m_Right = child; -} - -//----------------------------------------------------------------------------- -// Gets at the links -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline typename CUtlRBTree::Links_t const &CUtlRBTree::Links( I i ) const -{ - // Sentinel node, makes life easier - static Links_t s_Sentinel = - { - InvalidIndex(), InvalidIndex(), InvalidIndex(), CUtlRBTree::BLACK - }; - - return (i != InvalidIndex()) ? *(Links_t*)&m_Elements[i] : *(Links_t*)&s_Sentinel; -} - -template < class T, class I, typename L, class M > -inline typename CUtlRBTree::Links_t &CUtlRBTree::Links( I i ) -{ - Assert(i != InvalidIndex()); - return *(Links_t *)&m_Elements[i]; -} - -//----------------------------------------------------------------------------- -// Checks if a link is red or black -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsRed( I i ) const -{ - return (Links(i).m_Tag == RED); -} - -template < class T, class I, typename L, class M > -inline bool CUtlRBTree::IsBlack( I i ) const -{ - return (Links(i).m_Tag == BLACK); -} - - -//----------------------------------------------------------------------------- -// Sets/gets node color -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -inline typename CUtlRBTree::NodeColor_t CUtlRBTree::Color( I i ) const -{ - return (NodeColor_t)Links(i).m_Tag; -} - -template < class T, class I, typename L, class M > -inline void CUtlRBTree::SetColor( I i, typename CUtlRBTree::NodeColor_t c ) -{ - Links(i).m_Tag = (I)c; -} - -//----------------------------------------------------------------------------- -// Allocates/ deallocates nodes -//----------------------------------------------------------------------------- -#pragma warning(push) -#pragma warning(disable:4389) // '==' : signed/unsigned mismatch -template < class T, class I, typename L, class M > -I CUtlRBTree::NewNode() -{ - I elem; - - // Nothing in the free list; add. - if ( m_FirstFree == InvalidIndex() ) - { - Assert( m_Elements.IsValidIterator( m_LastAlloc ) || m_NumElements == 0 ); - typename M::Iterator_t it = m_Elements.IsValidIterator( m_LastAlloc ) ? m_Elements.Next( m_LastAlloc ) : m_Elements.First(); - if ( !m_Elements.IsValidIterator( it ) ) - { - MEM_ALLOC_CREDIT_CLASS(); - m_Elements.Grow(); - - it = m_Elements.IsValidIterator( m_LastAlloc ) ? m_Elements.Next( m_LastAlloc ) : m_Elements.First(); - - Assert( m_Elements.IsValidIterator( it ) ); - if ( !m_Elements.IsValidIterator( it ) ) - { - Error( "CUtlRBTree overflow!\n" ); - } - } - m_LastAlloc = it; - elem = m_Elements.GetIndex( m_LastAlloc ); - Assert( m_Elements.IsValidIterator( m_LastAlloc ) ); - } - else - { - elem = m_FirstFree; - m_FirstFree = Links( m_FirstFree ).m_Right; - } - -#ifdef _DEBUG - // reset links to invalid.... - Links_t &node = Links( elem ); - node.m_Left = node.m_Right = node.m_Parent = InvalidIndex(); -#endif - - Construct( &Element( elem ) ); - ResetDbgInfo(); - - return elem; -} -#pragma warning(pop) - -template < class T, class I, typename L, class M > -void CUtlRBTree::FreeNode( I i ) -{ - Assert( IsValidIndex(i) && (i != InvalidIndex()) ); - Destruct( &Element(i) ); - SetLeftChild( i, i ); // indicates it's in not in the tree - SetRightChild( i, m_FirstFree ); - m_FirstFree = i; -} - - -//----------------------------------------------------------------------------- -// Rotates node i to the left -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::RotateLeft(I elem) -{ - I rightchild = RightChild(elem); - SetRightChild( elem, LeftChild(rightchild) ); - if (LeftChild(rightchild) != InvalidIndex()) - SetParent( LeftChild(rightchild), elem ); - - if (rightchild != InvalidIndex()) - SetParent( rightchild, Parent(elem) ); - if (!IsRoot(elem)) - { - if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), rightchild ); - else - SetRightChild( Parent(elem), rightchild ); - } - else - m_Root = rightchild; - - SetLeftChild( rightchild, elem ); - if (elem != InvalidIndex()) - SetParent( elem, rightchild ); -} - - -//----------------------------------------------------------------------------- -// Rotates node i to the right -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::RotateRight(I elem) -{ - I leftchild = LeftChild(elem); - SetLeftChild( elem, RightChild(leftchild) ); - if (RightChild(leftchild) != InvalidIndex()) - SetParent( RightChild(leftchild), elem ); - - if (leftchild != InvalidIndex()) - SetParent( leftchild, Parent(elem) ); - if (!IsRoot(elem)) - { - if (IsRightChild(elem)) - SetRightChild( Parent(elem), leftchild ); - else - SetLeftChild( Parent(elem), leftchild ); - } - else - m_Root = leftchild; - - SetRightChild( leftchild, elem ); - if (elem != InvalidIndex()) - SetParent( elem, leftchild ); -} - - -//----------------------------------------------------------------------------- -// Rebalances the tree after an insertion -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::InsertRebalance(I elem) -{ - while ( !IsRoot(elem) && (Color(Parent(elem)) == RED) ) - { - I parent = Parent(elem); - I grandparent = Parent(parent); - - /* we have a violation */ - if (IsLeftChild(parent)) - { - I uncle = RightChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ - SetColor(parent, BLACK); - SetColor(uncle, BLACK); - SetColor(grandparent, RED); - elem = grandparent; - } - else - { - /* uncle is BLACK */ - if (IsRightChild(elem)) - { - /* make x a left child, will change parent and grandparent */ - elem = parent; - RotateLeft(elem); - parent = Parent(elem); - grandparent = Parent(parent); - } - /* recolor and rotate */ - SetColor(parent, BLACK); - SetColor(grandparent, RED); - RotateRight(grandparent); - } - } - else - { - /* mirror image of above code */ - I uncle = LeftChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ - SetColor(parent, BLACK); - SetColor(uncle, BLACK); - SetColor(grandparent, RED); - elem = grandparent; - } - else - { - /* uncle is BLACK */ - if (IsLeftChild(elem)) - { - /* make x a right child, will change parent and grandparent */ - elem = parent; - RotateRight(parent); - parent = Parent(elem); - grandparent = Parent(parent); - } - /* recolor and rotate */ - SetColor(parent, BLACK); - SetColor(grandparent, RED); - RotateLeft(grandparent); - } - } - } - SetColor( m_Root, BLACK ); -} - - -//----------------------------------------------------------------------------- -// Insert a node into the tree -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -I CUtlRBTree::InsertAt( I parent, bool leftchild ) -{ - I i = NewNode(); - LinkToParent( i, parent, leftchild ); - ++m_NumElements; - - Assert(IsValid()); - - return i; -} - -template < class T, class I, typename L, class M > -void CUtlRBTree::LinkToParent( I i, I parent, bool isLeft ) -{ - Links_t &elem = Links(i); - elem.m_Parent = parent; - elem.m_Left = elem.m_Right = InvalidIndex(); - elem.m_Tag = RED; - - /* insert node in tree */ - if (parent != InvalidIndex()) - { - if (isLeft) - Links(parent).m_Left = i; - else - Links(parent).m_Right = i; - } - else - { - m_Root = i; - } - - InsertRebalance(i); -} - -//----------------------------------------------------------------------------- -// Rebalance the tree after a deletion -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::RemoveRebalance(I elem) -{ - while (elem != m_Root && IsBlack(elem)) - { - I parent = Parent(elem); - - // If elem is the left child of the parent - if (elem == LeftChild(parent)) - { - // Get our sibling - I sibling = RightChild(parent); - if (IsRed(sibling)) - { - SetColor(sibling, BLACK); - SetColor(parent, RED); - RotateLeft(parent); - - // We may have a new parent now - parent = Parent(elem); - sibling = RightChild(parent); - } - if ( (IsBlack(LeftChild(sibling))) && (IsBlack(RightChild(sibling))) ) - { - if (sibling != InvalidIndex()) - SetColor(sibling, RED); - elem = parent; - } - else - { - if (IsBlack(RightChild(sibling))) - { - SetColor(LeftChild(sibling), BLACK); - SetColor(sibling, RED); - RotateRight(sibling); - - // rotation may have changed this - parent = Parent(elem); - sibling = RightChild(parent); - } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( RightChild(sibling), BLACK ); - RotateLeft( parent ); - elem = m_Root; - } - } - else - { - // Elem is the right child of the parent - I sibling = LeftChild(parent); - if (IsRed(sibling)) - { - SetColor(sibling, BLACK); - SetColor(parent, RED); - RotateRight(parent); - - // We may have a new parent now - parent = Parent(elem); - sibling = LeftChild(parent); - } - if ( (IsBlack(RightChild(sibling))) && (IsBlack(LeftChild(sibling))) ) - { - if (sibling != InvalidIndex()) - SetColor( sibling, RED ); - elem = parent; - } - else - { - if (IsBlack(LeftChild(sibling))) - { - SetColor( RightChild(sibling), BLACK ); - SetColor( sibling, RED ); - RotateLeft( sibling ); - - // rotation may have changed this - parent = Parent(elem); - sibling = LeftChild(parent); - } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( LeftChild(sibling), BLACK ); - RotateRight( parent ); - elem = m_Root; - } - } - } - SetColor( elem, BLACK ); -} - -template < class T, class I, typename L, class M > -void CUtlRBTree::Unlink( I elem ) -{ - if ( elem != InvalidIndex() ) - { - I x, y; - - if ((LeftChild(elem) == InvalidIndex()) || - (RightChild(elem) == InvalidIndex())) - { - /* y has a NIL node as a child */ - y = elem; - } - else - { - /* find tree successor with a NIL node as a child */ - y = RightChild(elem); - while (LeftChild(y) != InvalidIndex()) - y = LeftChild(y); - } - - /* x is y's only child */ - if (LeftChild(y) != InvalidIndex()) - x = LeftChild(y); - else - x = RightChild(y); - - /* remove y from the parent chain */ - if (x != InvalidIndex()) - SetParent( x, Parent(y) ); - if (!IsRoot(y)) - { - if (IsLeftChild(y)) - SetLeftChild( Parent(y), x ); - else - SetRightChild( Parent(y), x ); - } - else - m_Root = x; - - // need to store this off now, we'll be resetting y's color - NodeColor_t ycolor = Color(y); - if (y != elem) - { - // Standard implementations copy the data around, we cannot here. - // Hook in y to link to the same stuff elem used to. - SetParent( y, Parent(elem) ); - SetRightChild( y, RightChild(elem) ); - SetLeftChild( y, LeftChild(elem) ); - - if (!IsRoot(elem)) - if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), y ); - else - SetRightChild( Parent(elem), y ); - else - m_Root = y; - - if (LeftChild(y) != InvalidIndex()) - SetParent( LeftChild(y), y ); - if (RightChild(y) != InvalidIndex()) - SetParent( RightChild(y), y ); - - SetColor( y, Color(elem) ); - } - - if ((x != InvalidIndex()) && (ycolor == BLACK)) - RemoveRebalance(x); - } -} - -template < class T, class I, typename L, class M > -void CUtlRBTree::Link( I elem ) -{ - if ( elem != InvalidIndex() ) - { - I parent; - bool leftchild; - - FindInsertionPosition( Element( elem ), parent, leftchild ); - - LinkToParent( elem, parent, leftchild ); - - Assert(IsValid()); - } -} - -//----------------------------------------------------------------------------- -// Delete a node from the tree -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::RemoveAt(I elem) -{ - if ( elem != InvalidIndex() ) - { - Unlink( elem ); - - FreeNode(elem); - --m_NumElements; - - Assert(IsValid()); - } -} - - -//----------------------------------------------------------------------------- -// remove a node in the tree -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > bool CUtlRBTree::Remove( T const &search ) -{ - I node = Find( search ); - if (node != InvalidIndex()) - { - RemoveAt(node); - return true; - } - return false; -} - - -//----------------------------------------------------------------------------- -// Removes all nodes from the tree -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::RemoveAll() -{ - // Have to do some convoluted stuff to invoke the destructor on all - // valid elements for the multilist case (since we don't have all elements - // connected to each other in a list). - - if ( m_LastAlloc == m_Elements.InvalidIterator() ) - { - Assert( m_Root == InvalidIndex() ); - Assert( m_FirstFree == InvalidIndex() ); - Assert( m_NumElements == 0 ); - return; - } - - for ( typename M::Iterator_t it = m_Elements.First(); it != m_Elements.InvalidIterator(); it = m_Elements.Next( it ) ) - { - I i = m_Elements.GetIndex( it ); - if ( IsValidIndex( i ) ) // skip elements in the free list - { - Destruct( &Element( i ) ); - SetRightChild( i, m_FirstFree ); - SetLeftChild( i, i ); - m_FirstFree = i; - } - - if ( it == m_LastAlloc ) - break; // don't destruct elements that haven't ever been constucted - } - - // Clear everything else out - m_Root = InvalidIndex(); - m_NumElements = 0; - - Assert( IsValid() ); -} - -//----------------------------------------------------------------------------- -// Removes all nodes from the tree and purges memory -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::Purge() -{ - RemoveAll(); - m_FirstFree = InvalidIndex(); - m_Elements.Purge(); - m_LastAlloc = m_Elements.InvalidIterator(); -} - - -//----------------------------------------------------------------------------- -// iteration -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -I CUtlRBTree::FirstInorder() const -{ - I i = m_Root; - while (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - return i; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::NextInorder( I i ) const -{ - Assert(IsValidIndex(i)); - - if (RightChild(i) != InvalidIndex()) - { - i = RightChild(i); - while (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - return i; - } - - I parent = Parent(i); - while (IsRightChild(i)) - { - i = parent; - if (i == InvalidIndex()) break; - parent = Parent(i); - } - return parent; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::PrevInorder( I i ) const -{ - Assert(IsValidIndex(i)); - - if (LeftChild(i) != InvalidIndex()) - { - i = LeftChild(i); - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - return i; - } - - I parent = Parent(i); - while (IsLeftChild(i)) - { - i = parent; - if (i == InvalidIndex()) break; - parent = Parent(i); - } - return parent; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::LastInorder() const -{ - I i = m_Root; - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - return i; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::FirstPreorder() const -{ - return m_Root; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::NextPreorder( I i ) const -{ - if (LeftChild(i) != InvalidIndex()) - return LeftChild(i); - - if (RightChild(i) != InvalidIndex()) - return RightChild(i); - - I parent = Parent(i); - while( parent != InvalidIndex()) - { - if (IsLeftChild(i) && (RightChild(parent) != InvalidIndex())) - return RightChild(parent); - i = parent; - parent = Parent(parent); - } - return InvalidIndex(); -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::PrevPreorder( I i ) const -{ - Assert(0); // not implemented yet - return InvalidIndex(); -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::LastPreorder() const -{ - I i = m_Root; - while (1) - { - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - - if (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - else - break; - } - return i; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::FirstPostorder() const -{ - I i = m_Root; - while (!IsLeaf(i)) - { - if (LeftChild(i)) - i = LeftChild(i); - else - i = RightChild(i); - } - return i; -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::NextPostorder( I i ) const -{ - I parent = Parent(i); - if (parent == InvalidIndex()) - return InvalidIndex(); - - if (IsRightChild(i)) - return parent; - - if (RightChild(parent) == InvalidIndex()) - return parent; - - i = RightChild(parent); - while (!IsLeaf(i)) - { - if (LeftChild(i)) - i = LeftChild(i); - else - i = RightChild(i); - } - return i; -} - - -template < class T, class I, typename L, class M > -void CUtlRBTree::Reinsert( I elem ) -{ - Unlink( elem ); - Link( elem ); -} - - -//----------------------------------------------------------------------------- -// returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -int CUtlRBTree::Depth( I node ) const -{ - if (node == InvalidIndex()) - return 0; - - int depthright = Depth( RightChild(node) ); - int depthleft = Depth( LeftChild(node) ); - return max(depthright, depthleft) + 1; -} - - -//#define UTLTREE_PARANOID - -//----------------------------------------------------------------------------- -// Makes sure the tree is valid after every operation -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -bool CUtlRBTree::IsValid() const -{ - if ( !Count() ) - return true; - - if ( m_LastAlloc == m_Elements.InvalidIterator() ) - return false; - - if ( !m_Elements.IsIdxValid( Root() ) ) - return false; - - if ( Parent( Root() ) != InvalidIndex() ) - return false; - -#ifdef UTLTREE_PARANOID - - // First check to see that mNumEntries matches reality. - // count items on the free list - int numFree = 0; - for ( int i = m_FirstFree; i != InvalidIndex(); i = RightChild( i ) ) - { - ++numFree; - if ( !m_Elements.IsIdxValid( i ) ) - return false; - } - - // iterate over all elements, looking for validity - // based on the self pointers - int nElements = 0; - int numFree2 = 0; - for ( M::Iterator_t it = m_Elements.First(); it != m_Elements.InvalidIterator(); it = m_Elements.Next( it ) ) - { - I i = m_Elements.GetIndex( it ); - if ( !IsValidIndex( i ) ) - { - ++numFree2; - } - else - { - ++nElements; - - int right = RightChild( i ); - int left = LeftChild( i ); - if ( ( right == left ) && ( right != InvalidIndex() ) ) - return false; - - if ( right != InvalidIndex() ) - { - if ( !IsValidIndex( right ) ) - return false; - if ( Parent( right ) != i ) - return false; - if ( IsRed( i ) && IsRed( right ) ) - return false; - } - - if ( left != InvalidIndex() ) - { - if ( !IsValidIndex( left ) ) - return false; - if ( Parent( left ) != i ) - return false; - if ( IsRed( i ) && IsRed( left ) ) - return false; - } - } - - if ( it == m_LastAlloc ) - break; - } - if ( numFree2 != numFree ) - return false; - - if ( nElements != m_NumElements ) - return false; - -#endif // UTLTREE_PARANOID - - return true; -} - - -//----------------------------------------------------------------------------- -// Sets the less func -//----------------------------------------------------------------------------- - -template < class T, class I, typename L, class M > -void CUtlRBTree::SetLessFunc( const typename CUtlRBTree::LessFunc_t &func ) -{ - if (!m_LessFunc) - { - m_LessFunc = func; - } - else if ( Count() > 0 ) - { - // need to re-sort the tree here.... - Assert(0); - } -} - - -//----------------------------------------------------------------------------- -// inserts a node into the tree -//----------------------------------------------------------------------------- - -// Inserts a node into the tree, doesn't copy the data in. -template < class T, class I, typename L, class M > -void CUtlRBTree::FindInsertionPosition( T const &insert, I &parent, bool &leftchild ) -{ - Assert( m_LessFunc ); - - /* find where node belongs */ - I current = m_Root; - parent = InvalidIndex(); - leftchild = false; - while (current != InvalidIndex()) - { - parent = current; - if (m_LessFunc( insert, Element(current) )) - { - leftchild = true; current = LeftChild(current); - } - else - { - leftchild = false; current = RightChild(current); - } - } -} - -template < class T, class I, typename L, class M > -I CUtlRBTree::Insert( T const &insert ) -{ - // use copy constructor to copy it in - I parent; - bool leftchild; - FindInsertionPosition( insert, parent, leftchild ); - I newNode = InsertAt( parent, leftchild ); - CopyConstruct( &Element( newNode ), insert ); - return newNode; -} - - -template < class T, class I, typename L, class M > -void CUtlRBTree::Insert( const T *pArray, int nItems ) -{ - while ( nItems-- ) - { - Insert( *pArray++ ); - } -} - - -template < class T, class I, typename L, class M > -I CUtlRBTree::InsertIfNotFound( T const &insert ) -{ - // use copy constructor to copy it in - I parent; - bool leftchild; - - I current = m_Root; - parent = InvalidIndex(); - leftchild = false; - while (current != InvalidIndex()) - { - parent = current; - if (m_LessFunc( insert, Element(current) )) - { - leftchild = true; current = LeftChild(current); - } - else if (m_LessFunc( Element(current), insert )) - { - leftchild = false; current = RightChild(current); - } - else - // Match found, no insertion - return InvalidIndex(); - } - - I newNode = InsertAt( parent, leftchild ); - CopyConstruct( &Element( newNode ), insert ); - return newNode; -} - - -//----------------------------------------------------------------------------- -// finds a node in the tree -//----------------------------------------------------------------------------- -template < class T, class I, typename L, class M > -I CUtlRBTree::Find( T const &search ) const -{ - Assert( m_LessFunc ); - - I current = m_Root; - while (current != InvalidIndex()) - { - if (m_LessFunc( search, Element(current) )) - current = LeftChild(current); - else if (m_LessFunc( Element(current), search )) - current = RightChild(current); - else - break; - } - return current; -} - - -//----------------------------------------------------------------------------- -// swap in place -//----------------------------------------------------------------------------- -template < class T, class I, typename L, class M > -void CUtlRBTree::Swap( CUtlRBTree< T, I, L > &that ) -{ - m_Elements.Swap( that.m_Elements ); - swap( m_LessFunc, that.m_LessFunc ); - swap( m_Root, that.m_Root ); - swap( m_NumElements, that.m_NumElements ); - swap( m_FirstFree, that.m_FirstFree ); - swap( m_pElements, that.m_pElements ); - swap( m_LastAlloc, that.m_LastAlloc ); - Assert( IsValid() ); - Assert( m_Elements.IsValidIterator( m_LastAlloc ) || ( m_NumElements == 0 && m_FirstFree == InvalidIndex() ) ); -} - - -#endif // UTLRBTREE_H diff --git a/Resources/NetHook/tier1/utlsoacontainer.h b/Resources/NetHook/tier1/utlsoacontainer.h deleted file mode 100644 index b056358c..00000000 --- a/Resources/NetHook/tier1/utlsoacontainer.h +++ /dev/null @@ -1,334 +0,0 @@ -//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// A Fixed-allocation class for maintaining a 1d or 2d or 3d array of data in a structure-of-arrays -// (SOA) sse-friendly manner. -// =============================================================================// - -#ifndef UTLSOACONTAINER_H -#define UTLSOACONTAINER_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier0/threadtools.h" -#include "tier1/utlmemory.h" -#include "tier1/utlblockmemory.h" -#include "mathlib/ssemath.h" - - -// strided pointers. gives you a class that acts like a pointer, but the ++ and += operators do the -// right thing -template class CStridedPtr -{ -protected: - T *m_pData; - size_t m_nStride; - -public: - FORCEINLINE CStridedPtr( void *pData, size_t nByteStride ) - { - m_pData = reinterpret_cast( pData ); - m_nStride = nByteStride / sizeof( T ); - } - - FORCEINLINE CStridedPtr( void ) {} - T *operator->(void) const - { - return m_pData; - } - - T & operator*(void) const - { - return *m_pData; - } - - FORCEINLINE operator T *(void) - { - return m_pData; - } - - FORCEINLINE CStridedPtr & operator++(void) - { - m_pData += m_nStride; - return *this; - } - - FORCEINLINE void operator+=( size_t nNumElements ) - { - m_pData += nNumElements * m_nStride; - } - -}; - -template class CStridedConstPtr -{ -protected: - const T *m_pData; - size_t m_nStride; - -public: - FORCEINLINE CStridedConstPtr( void const *pData, size_t nByteStride ) - { - m_pData = reinterpret_cast( pData ); - m_nStride = nByteStride / sizeof( T ); - } - - FORCEINLINE CStridedConstPtr( void ) {} - - const T *operator->(void) const - { - return m_pData; - } - - const T & operator*(void) const - { - return *m_pData; - } - - FORCEINLINE operator const T *(void) const - { - return m_pData; - } - - FORCEINLINE CStridedConstPtr &operator++(void) - { - m_pData += m_nStride; - return *this; - } - FORCEINLINE void operator+=( size_t nNumElements ) - { - m_pData += nNumElements*m_nStride; - } -}; - -// allowed field data types. if you change these values, you need to change the tables in the .cpp file -enum EAttributeDataType -{ - ATTRDATATYPE_FLOAT = 0, // a float attribute - ATTRDATATYPE_4V = 1, // vector data type, stored as class FourVectors - ATTRDATATYPE_INT = 2, // integer. not especially sse-able on - // all architectures. - ATTRDATATYPE_POINTER = 3, // a pointer. - ATTRDATATYPE_NONE = -1, // pad and varargs ender -}; - -#define MAX_SOA_FIELDS 32 - -class CSOAContainer -{ - -protected: - int m_nColumns; // # of rows and columns created with - int m_nRows; - int m_nSlices; - - int m_nPaddedColumns; // # of columns rounded up for sse - int m_nNumQuadsPerRow; // # of groups of 4 elements per row - - uint8 *m_pDataMemory; // the actual data memory - uint8 *m_pAttributePtrs[MAX_SOA_FIELDS]; - - EAttributeDataType m_nDataType[MAX_SOA_FIELDS]; - - size_t m_nStrideInBytes[MAX_SOA_FIELDS]; // stride from one field datum to another - size_t m_nRowStrideInBytes[MAX_SOA_FIELDS]; // stride from one row datum to another per field - size_t m_nSliceStrideInBytes[MAX_SOA_FIELDS]; // stride from one slice datum to another per field - - - - uint32 m_nFieldPresentMask; - - FORCEINLINE void Init( void ) - { - memset( m_nDataType, 0xff, sizeof( m_nDataType ) ); - m_pDataMemory = 0; - m_nColumns = m_nPaddedColumns = m_nRows = m_nSlices = 0; - m_nFieldPresentMask = 0; - } -public: - - - CSOAContainer( void ) // an empoty one with no attributes - { - Init(); - } - - void Purge( void ); // set back to un-initted state, freeing memory - - ~CSOAContainer( void ); - - // easy constructor for 2d using varargs. call like - // #define ATTR_RED 0 - // #define ATTR_GREEN 1 - // #define ATTR_BLUE 2 - // CSOAContainer myimage( 256, 256, ATTR_RED, ATTRDATATYPE_FLOAT, ATTR_GREEN, ATTRDATATYPE_FLOAT, - // ATTR_BLUE, ATTRDATATYPE_FLOAT, -1 ); - - CSOAContainer( int nCols, int nRows, ... ); - - size_t ElementSize( void ) const; // total bytes per element. not super fast. - - // set the data type for an attribute. If you set the data type, but tell it not to allocate, - // the data type will be set but writes will assert, and reads will give you back zeros. - FORCEINLINE void SetAttributeType( int nAttrIdx, EAttributeDataType nDataType, bool bAllocateMemory = true ) - { - Assert( !m_pDataMemory ); // can't change after memory allocated - Assert( nAttrIdx < MAX_SOA_FIELDS ); - m_nDataType[nAttrIdx] = nDataType; - if ( ( m_nDataType[nAttrIdx] != ATTRDATATYPE_NONE ) && bAllocateMemory ) - m_nFieldPresentMask |= ( 1 << nAttrIdx ); - else - m_nFieldPresentMask &= ~( 1 << nAttrIdx ); - } - - FORCEINLINE int NumRows( void ) const - { - return m_nRows; - } - - FORCEINLINE int NumCols( void ) const - { - return m_nColumns; - } - FORCEINLINE int NumSlices( void ) const - { - return m_nSlices; - } - - - FORCEINLINE void AssertDataType( int nAttrIdx, EAttributeDataType nDataType ) const - { - Assert( nAttrIdx >= 0 ); - Assert( nAttrIdx < MAX_SOA_FIELDS ); - Assert( m_nStrideInBytes[nAttrIdx] ); - } - - - // # of groups of 4 elements per row - FORCEINLINE int NumQuadsPerRow( void ) const - { - return m_nNumQuadsPerRow; - } - - FORCEINLINE int Count( void ) const // for 1d data - { - return NumCols(); - } - - FORCEINLINE int NumElements( void ) const - { - return NumCols() * NumRows() * NumSlices(); - } - - - // how much to step to go from the end of one row to the start of the next one. Basically, how - // many bytes to add at the end of a row when iterating over the whole 2d array with ++ - FORCEINLINE size_t RowToRowStep( int nAttrIdx ) const - { - return 0; - } - - FORCEINLINE void *RowPtr( int nAttributeIdx, int nRowNumber, int nSliceNumber = 0 ) const - { - Assert( nRowNumber < m_nRows ); - Assert( nAttributeIdx < MAX_SOA_FIELDS ); - Assert( m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE ); - Assert( m_nFieldPresentMask & ( 1 << nAttributeIdx ) ); - return m_pAttributePtrs[nAttributeIdx] + - + nRowNumber * m_nRowStrideInBytes[nAttributeIdx] - + nSliceNumber * m_nSliceStrideInBytes[nAttributeIdx]; - } - - FORCEINLINE void const *ConstRowPtr( int nAttributeIdx, int nRowNumber, int nSliceNumber = 0 ) const - { - Assert( nRowNumber < m_nRows ); - Assert( nAttributeIdx < MAX_SOA_FIELDS ); - Assert( m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE ); - return m_pAttributePtrs[nAttributeIdx] - + nRowNumber * m_nRowStrideInBytes[nAttributeIdx] - + nSliceNumber * m_nSliceStrideInBytes[nAttributeIdx]; - } - - - template FORCEINLINE T *ElementPointer( int nAttributeIdx, - int nX = 0, int nY = 0, int nZ = 0 ) const - { - Assert( nAttributeIdx < MAX_SOA_FIELDS ); - Assert( nX < m_nColumns ); - Assert( nY < m_nRows ); - Assert( nZ < m_nSlices ); - Assert( m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE ); - Assert( m_nDataType[nAttributeIdx] != ATTRDATATYPE_4V ); - return reinterpret_cast( m_pAttributePtrs[nAttributeIdx] - + nX * sizeof( float ) - + nY * m_nRowStrideInBytes[nAttributeIdx] - + nZ * m_nSliceStrideInBytes[nAttributeIdx] - ); - } - - FORCEINLINE size_t ItemByteStride( int nAttributeIdx ) const - { - Assert( nAttributeIdx < MAX_SOA_FIELDS ); - Assert( m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE ); - return m_nStrideInBytes[ nAttributeIdx ]; - } - - // copy the attribute data from another soacontainer. must be compatible geometry - void CopyAttrFrom( CSOAContainer const &other, int nAttributeIdx ); - - // copy the attribute data from another attribute. must be compatible data format - void CopyAttrToAttr( int nSrcAttributeIndex, int nDestAttributeIndex); - - // move all the data from one csoacontainer to another, leaving the source empty. - // this is just a pointer copy. - FORCEINLINE void MoveDataFrom( CSOAContainer other ) - { - (*this) = other; - other.Init(); - } - - - - void AllocateData( int nNCols, int nNRows, int nSlices = 1 ); // actually allocate the memory and set the pointers up - - // arithmetic and data filling functions. All SIMD and hopefully fast - - // set all elements of a float attribute to random #s - void RandomizeAttribute( int nAttr, float flMin, float flMax ) const ; - - // fill 2d a rectangle with values interpolated from 4 corner values. - void FillAttrWithInterpolatedValues( int nAttr, float flValue00, float flValue10, float flValue01, float flValue11 ) const; - void FillAttrWithInterpolatedValues( int nAttr, Vector flValue00, Vector flValue10, - Vector const &flValue01, Vector const &flValue11 ) const; - -}; - -class CFltX4AttributeIterator : public CStridedConstPtr -{ - FORCEINLINE CFltX4AttributeIterator( CSOAContainer const *pContainer, int nAttribute, int nRowNumber = 0 ) - : CStridedConstPtr( pContainer->ConstRowPtr( nAttribute, nRowNumber), - pContainer->ItemByteStride( nAttribute ) ) - { - } -}; - -class CFltX4AttributeWriteIterator : public CStridedPtr -{ - FORCEINLINE CFltX4AttributeWriteIterator( CSOAContainer const *pContainer, int nAttribute, int nRowNumber = 0 ) - : CStridedPtr( pContainer->RowPtr( nAttribute, nRowNumber), - pContainer->ItemByteStride( nAttribute ) ) - { - } - -}; - - -#endif diff --git a/Resources/NetHook/tier1/utlstack.h b/Resources/NetHook/tier1/utlstack.h deleted file mode 100644 index 8cacdd84..00000000 --- a/Resources/NetHook/tier1/utlstack.h +++ /dev/null @@ -1,331 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -// A stack based on a growable array -//=============================================================================// - -#ifndef UTLSTACK_H -#define UTLSTACK_H - -#include -#include -#include "utlmemory.h" - - -//----------------------------------------------------------------------------- -// The CUtlStack class: -// A growable stack class which doubles in size by default. -// It will always keep all elements consecutive in memory, and may move the -// elements around in memory (via a realloc) when elements are pushed or -// popped. Clients should therefore refer to the elements of the stack -// by index (they should *never* maintain pointers to elements in the stack). -//----------------------------------------------------------------------------- - -template< class T, class M = CUtlMemory< T > > -class CUtlStack -{ -public: - // constructor, destructor - CUtlStack( int growSize = 0, int initSize = 0 ); - ~CUtlStack(); - - void CopyFrom( const CUtlStack &from ); - - // element access - T& operator[]( int i ); - T const& operator[]( int i ) const; - T& Element( int i ); - T const& Element( int i ) const; - - // Gets the base address (can change when adding elements!) - T* Base(); - T const* Base() const; - - // Looks at the stack top - T& Top(); - T const& Top() const; - - // Size - int Count() const; - - // Is element index valid? - bool IsIdxValid( int i ) const; - - // Adds an element, uses default constructor - int Push(); - - // Adds an element, uses copy constructor - int Push( T const& src ); - - // Pops the stack - void Pop(); - void Pop( T& oldTop ); - void PopMultiple( int num ); - - // Makes sure we have enough memory allocated to store a requested # of elements - void EnsureCapacity( int num ); - - // Clears the stack, no deallocation - void Clear(); - - // Memory deallocation - void Purge(); - -private: - // Grows the stack allocation - void GrowStack(); - - // For easier access to the elements through the debugger - void ResetDbgInfo(); - - M m_Memory; - int m_Size; - - // For easier access to the elements through the debugger - T* m_pElements; -}; - - -//----------------------------------------------------------------------------- -// For easier access to the elements through the debugger -//----------------------------------------------------------------------------- - -template< class T, class M > -inline void CUtlStack::ResetDbgInfo() -{ - m_pElements = m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T, class M > -CUtlStack::CUtlStack( int growSize, int initSize ) : - m_Memory(growSize, initSize), m_Size(0) -{ - ResetDbgInfo(); -} - -template< class T, class M > -CUtlStack::~CUtlStack() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -// copy into -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::CopyFrom( const CUtlStack &from ) -{ - Purge(); - EnsureCapacity( from.Count() ); - for ( int i = 0; i < from.Count(); i++ ) - { - Push( from[i] ); - } -} - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- - -template< class T, class M > -inline T& CUtlStack::operator[]( int i ) -{ - assert( IsIdxValid(i) ); - return m_Memory[i]; -} - -template< class T, class M > -inline T const& CUtlStack::operator[]( int i ) const -{ - assert( IsIdxValid(i) ); - return m_Memory[i]; -} - -template< class T, class M > -inline T& CUtlStack::Element( int i ) -{ - assert( IsIdxValid(i) ); - return m_Memory[i]; -} - -template< class T, class M > -inline T const& CUtlStack::Element( int i ) const -{ - assert( IsIdxValid(i) ); - return m_Memory[i]; -} - - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- - -template< class T, class M > -inline T* CUtlStack::Base() -{ - return m_Memory.Base(); -} - -template< class T, class M > -inline T const* CUtlStack::Base() const -{ - return m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// Returns the top of the stack -//----------------------------------------------------------------------------- - -template< class T, class M > -inline T& CUtlStack::Top() -{ - assert( m_Size > 0 ); - return Element(m_Size-1); -} - -template< class T, class M > -inline T const& CUtlStack::Top() const -{ - assert( m_Size > 0 ); - return Element(m_Size-1); -} - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- - -template< class T, class M > -inline int CUtlStack::Count() const -{ - return m_Size; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- - -template< class T, class M > -inline bool CUtlStack::IsIdxValid( int i ) const -{ - return (i >= 0) && (i < m_Size); -} - -//----------------------------------------------------------------------------- -// Grows the stack -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::GrowStack() -{ - if (m_Size >= m_Memory.NumAllocated()) - m_Memory.Grow(); - - ++m_Size; - - ResetDbgInfo(); -} - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::EnsureCapacity( int num ) -{ - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Adds an element, uses default constructor -//----------------------------------------------------------------------------- - -template< class T, class M > -int CUtlStack::Push() -{ - GrowStack(); - Construct( &Element(m_Size-1) ); - return m_Size - 1; -} - -//----------------------------------------------------------------------------- -// Adds an element, uses copy constructor -//----------------------------------------------------------------------------- - -template< class T, class M > -int CUtlStack::Push( T const& src ) -{ - GrowStack(); - CopyConstruct( &Element(m_Size-1), src ); - return m_Size - 1; -} - - -//----------------------------------------------------------------------------- -// Pops the stack -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::Pop() -{ - assert( m_Size > 0 ); - Destruct( &Element(m_Size-1) ); - --m_Size; -} - -template< class T, class M > -void CUtlStack::Pop( T& oldTop ) -{ - assert( m_Size > 0 ); - oldTop = Top(); - Pop(); -} - -template< class T, class M > -void CUtlStack::PopMultiple( int num ) -{ - assert( m_Size >= num ); - for ( int i = 0; i < num; ++i ) - Destruct( &Element( m_Size - i - 1 ) ); - m_Size -= num; -} - - -//----------------------------------------------------------------------------- -// Element removal -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::Clear() -{ - for (int i = m_Size; --i >= 0; ) - Destruct(&Element(i)); - - m_Size = 0; -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- - -template< class T, class M > -void CUtlStack::Purge() -{ - Clear(); - m_Memory.Purge( ); - ResetDbgInfo(); -} - -#endif // UTLSTACK_H \ No newline at end of file diff --git a/Resources/NetHook/tier1/utlstring.cpp b/Resources/NetHook/tier1/utlstring.cpp deleted file mode 100644 index c9bd6e47..00000000 --- a/Resources/NetHook/tier1/utlstring.cpp +++ /dev/null @@ -1,334 +0,0 @@ -//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#include "tier1/utlstring.h" -#include "tier1/strtools.h" - - -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) : m_Memory( growSize, initSize ) -{ - m_nActualLength = 0; -} - -CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nInitialLength; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes ) -{ - m_nActualLength = nSizeInBytes; -} - -CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src ) -{ - Set( src.Get(), src.Length() ); -} - -void CUtlBinaryBlock::Get( void *pValue, int nLen ) const -{ - Assert( nLen > 0 ); - if ( m_nActualLength < nLen ) - { - nLen = m_nActualLength; - } - - if ( nLen > 0 ) - { - memcpy( pValue, m_Memory.Base(), nLen ); - } -} - -void CUtlBinaryBlock::SetLength( int nLength ) -{ - Assert( !m_Memory.IsReadOnly() ); - - m_nActualLength = nLength; - if ( nLength > m_Memory.NumAllocated() ) - { - int nOverFlow = nLength - m_Memory.NumAllocated(); - m_Memory.Grow( nOverFlow ); - - // If the reallocation failed, clamp length - if ( nLength > m_Memory.NumAllocated() ) - { - m_nActualLength = m_Memory.NumAllocated(); - } - } - -#ifdef _DEBUG - if ( m_Memory.NumAllocated() > m_nActualLength ) - { - memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength ); - } -#endif -} - -void CUtlBinaryBlock::Set( const void *pValue, int nLen ) -{ - Assert( !m_Memory.IsReadOnly() ); - - if ( !pValue ) - { - nLen = 0; - } - - SetLength( nLen ); - - if ( m_nActualLength ) - { - if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen || - ( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) ) - { - memcpy( m_Memory.Base(), pValue, m_nActualLength ); - } - else - { - memmove( m_Memory.Base(), pValue, m_nActualLength ); - } - } -} - - -CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src ) -{ - Assert( !m_Memory.IsReadOnly() ); - Set( src.Get(), src.Length() ); - return *this; -} - - -bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const -{ - if ( src.Length() != Length() ) - return false; - - return !memcmp( src.Get(), Get(), Length() ); -} - - -//----------------------------------------------------------------------------- -// Simple string class. -//----------------------------------------------------------------------------- -CUtlString::CUtlString() -{ -} - -CUtlString::CUtlString( const char *pString ) -{ - Set( pString ); -} - -CUtlString::CUtlString( const CUtlString& string ) -{ - Set( string.Get() ); -} - -// Attaches the string to external memory. Useful for avoiding a copy -CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength ) -{ -} - -CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes ) -{ -} - -void CUtlString::Set( const char *pValue ) -{ - Assert( !m_Storage.IsReadOnly() ); - int nLen = pValue ? Q_strlen(pValue) + 1 : 0; - m_Storage.Set( pValue, nLen ); -} - -// Returns strlen -int CUtlString::Length() const -{ - return m_Storage.Length() ? m_Storage.Length() - 1 : 0; -} - -// Sets the length (used to serialize into the buffer ) -void CUtlString::SetLength( int nLen ) -{ - Assert( !m_Storage.IsReadOnly() ); - - // Add 1 to account for the NULL - m_Storage.SetLength( nLen > 0 ? nLen + 1 : 0 ); -} - -const char *CUtlString::Get( ) const -{ - if ( m_Storage.Length() == 0 ) - { - return ""; - } - - return reinterpret_cast< const char* >( m_Storage.Get() ); -} - -// Converts to c-strings -CUtlString::operator const char*() const -{ - return Get(); -} - -char *CUtlString::Get() -{ - Assert( !m_Storage.IsReadOnly() ); - - if ( m_Storage.Length() == 0 ) - { - // In general, we optimise away small mallocs for empty strings - // but if you ask for the non-const bytes, they must be writable - // so we can't return "" here, like we do for the const version - jd - m_Storage.SetLength( 1 ); - m_Storage[ 0 ] = '\0'; - } - - return reinterpret_cast< char* >( m_Storage.Get() ); -} - -CUtlString &CUtlString::operator=( const CUtlString &src ) -{ - Assert( !m_Storage.IsReadOnly() ); - m_Storage = src.m_Storage; - return *this; -} - -CUtlString &CUtlString::operator=( const char *src ) -{ - Assert( !m_Storage.IsReadOnly() ); - Set( src ); - return *this; -} - -bool CUtlString::operator==( const CUtlString &src ) const -{ - return m_Storage == src.m_Storage; -} - -bool CUtlString::operator==( const char *src ) const -{ - return ( strcmp( Get(), src ) == 0 ); -} - -CUtlString &CUtlString::operator+=( const CUtlString &rhs ) -{ - Assert( !m_Storage.IsReadOnly() ); - - const int lhsLength( Length() ); - const int rhsLength( rhs.Length() ); - const int requestedLength( lhsLength + rhsLength ); - - SetLength( requestedLength ); - const int allocatedLength( Length() ); - const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); - memcpy( Get() + lhsLength, rhs.Get(), copyLength ); - m_Storage[ allocatedLength ] = '\0'; - - return *this; -} - -CUtlString &CUtlString::operator+=( const char *rhs ) -{ - Assert( !m_Storage.IsReadOnly() ); - - const int lhsLength( Length() ); - const int rhsLength( Q_strlen( rhs ) ); - const int requestedLength( lhsLength + rhsLength ); - - SetLength( requestedLength ); - const int allocatedLength( Length() ); - const int copyLength( allocatedLength - lhsLength < rhsLength ? allocatedLength - lhsLength : rhsLength ); - memcpy( Get() + lhsLength, rhs, copyLength ); - m_Storage[ allocatedLength ] = '\0'; - - return *this; -} - -CUtlString &CUtlString::operator+=( char c ) -{ - Assert( !m_Storage.IsReadOnly() ); - - int nLength = Length(); - SetLength( nLength + 1 ); - m_Storage[ nLength ] = c; - m_Storage[ nLength+1 ] = '\0'; - return *this; -} - -CUtlString &CUtlString::operator+=( int rhs ) -{ - Assert( !m_Storage.IsReadOnly() ); - Assert( sizeof( rhs ) == 4 ); - - char tmpBuf[ 12 ]; // Sufficient for a signed 32 bit integer [ -2147483648 to +2147483647 ] - Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%d", rhs ); - tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; - - return operator+=( tmpBuf ); -} - -CUtlString &CUtlString::operator+=( double rhs ) -{ - Assert( !m_Storage.IsReadOnly() ); - - char tmpBuf[ 256 ]; // How big can doubles be??? Dunno. - Q_snprintf( tmpBuf, sizeof( tmpBuf ), "%lg", rhs ); - tmpBuf[ sizeof( tmpBuf ) - 1 ] = '\0'; - - return operator+=( tmpBuf ); -} - -int CUtlString::Format( const char *pFormat, ... ) -{ - Assert( !m_Storage.IsReadOnly() ); - - char tmpBuf[ 4096 ]; //< Nice big 4k buffer, as much memory as my first computer had, a Radio Shack Color Computer - - va_list marker; - - va_start( marker, pFormat ); -#ifdef _WIN32 - int len = _vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); -#elif _LINUX - int len = vsnprintf( tmpBuf, sizeof( tmpBuf ) - 1, pFormat, marker ); -#else -#error "define vsnprintf type." -#endif - va_end( marker ); - - // Len < 0 represents an overflow - if( len < 0 ) - { - len = sizeof( tmpBuf ) - 1; - tmpBuf[sizeof( tmpBuf ) - 1] = 0; - } - - Set( tmpBuf ); - - return len; -} - -//----------------------------------------------------------------------------- -// Strips the trailing slash -//----------------------------------------------------------------------------- -void CUtlString::StripTrailingSlash() -{ - if ( IsEmpty() ) - return; - - int nLastChar = Length() - 1; - char c = m_Storage[ nLastChar ]; - if ( c == '\\' || c == '/' ) - { - m_Storage[ nLastChar ] = 0; - m_Storage.SetLength( m_Storage.Length() - 1 ); - } -} - diff --git a/Resources/NetHook/tier1/utlstring.h b/Resources/NetHook/tier1/utlstring.h deleted file mode 100644 index 6c427401..00000000 --- a/Resources/NetHook/tier1/utlstring.h +++ /dev/null @@ -1,160 +0,0 @@ -//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= -// -// Purpose: -// -//============================================================================= - -#ifndef UTLSTRING_H -#define UTLSTRING_H -#ifdef _WIN32 -#pragma once -#endif - - -#include "tier1/utlmemory.h" - - -//----------------------------------------------------------------------------- -// Base class, containing simple memory management -//----------------------------------------------------------------------------- -class CUtlBinaryBlock -{ -public: - CUtlBinaryBlock( int growSize = 0, int initSize = 0 ); - - // NOTE: nInitialLength indicates how much of the buffer starts full - CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ); - CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ); - CUtlBinaryBlock( const CUtlBinaryBlock& src ); - - void Get( void *pValue, int nMaxLen ) const; - void Set( const void *pValue, int nLen ); - const void *Get( ) const; - void *Get( ); - - unsigned char& operator[]( int i ); - const unsigned char& operator[]( int i ) const; - - int Length() const; - void SetLength( int nLength ); // Undefined memory will result - bool IsEmpty() const; - - bool IsReadOnly() const; - - CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src ); - - // Test for equality - bool operator==( const CUtlBinaryBlock &src ) const; - -private: - CUtlMemory m_Memory; - int m_nActualLength; -}; - - -//----------------------------------------------------------------------------- -// class inlines -//----------------------------------------------------------------------------- -inline const void *CUtlBinaryBlock::Get( ) const -{ - return m_Memory.Base(); -} - -inline void *CUtlBinaryBlock::Get( ) -{ - return m_Memory.Base(); -} - -inline int CUtlBinaryBlock::Length() const -{ - return m_nActualLength; -} - -inline unsigned char& CUtlBinaryBlock::operator[]( int i ) -{ - return m_Memory[i]; -} - -inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const -{ - return m_Memory[i]; -} - -inline bool CUtlBinaryBlock::IsReadOnly() const -{ - return m_Memory.IsReadOnly(); -} - -inline bool CUtlBinaryBlock::IsEmpty() const -{ - return Length() == 0; -} - - -//----------------------------------------------------------------------------- -// Simple string class. -// NOTE: This is *not* optimal! Use in tools, but not runtime code -//----------------------------------------------------------------------------- -class CUtlString -{ -public: - CUtlString(); - CUtlString( const char *pString ); - CUtlString( const CUtlString& string ); - - // Attaches the string to external memory. Useful for avoiding a copy - CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ); - CUtlString( const void* pMemory, int nSizeInBytes ); - - const char *Get( ) const; - void Set( const char *pValue ); - - // Converts to c-strings - operator const char*() const; - - // for compatibility switching items from UtlSymbol - const char *String() const { return Get(); } - - // Returns strlen - int Length() const; - bool IsEmpty() const; - - // Sets the length (used to serialize into the buffer ) - void SetLength( int nLen ); - char *Get(); - - // Strips the trailing slash - void StripTrailingSlash(); - - CUtlString &operator=( const CUtlString &src ); - CUtlString &operator=( const char *src ); - - // Test for equality - bool operator==( const CUtlString &src ) const; - bool operator==( const char *src ) const; - bool operator!=( const CUtlString &src ) const { return !operator==( src ); } - bool operator!=( const char *src ) const { return !operator==( src ); } - - CUtlString &operator+=( const CUtlString &rhs ); - CUtlString &operator+=( const char *rhs ); - CUtlString &operator+=( char c ); - CUtlString &operator+=( int rhs ); - CUtlString &operator+=( double rhs ); - - int Format( const char *pFormat, ... ); - -private: - CUtlBinaryBlock m_Storage; -}; - - -//----------------------------------------------------------------------------- -// Inline methods -//----------------------------------------------------------------------------- -inline bool CUtlString::IsEmpty() const -{ - return Length() == 0; -} - - -#endif // UTLSTRING_H diff --git a/Resources/NetHook/tier1/utlsymbol.cpp b/Resources/NetHook/tier1/utlsymbol.cpp deleted file mode 100644 index 551245ec..00000000 --- a/Resources/NetHook/tier1/utlsymbol.cpp +++ /dev/null @@ -1,395 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: Defines a symbol table -// -// $Header: $ -// $NoKeywords: $ -//=============================================================================// - -#pragma warning (disable:4514) - -#include "utlsymbol.h" -#include "KeyValues.h" -#include "tier0/threadtools.h" -#include "tier0/memdbgon.h" -#include "stringpool.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define INVALID_STRING_INDEX CStringPoolIndex( 0xFFFF, 0xFFFF ) - -#define MIN_STRING_POOL_SIZE 2048 - -//----------------------------------------------------------------------------- -// globals -//----------------------------------------------------------------------------- - -CUtlSymbolTableMT* CUtlSymbol::s_pSymbolTable = 0; -bool CUtlSymbol::s_bAllowStaticSymbolTable = true; - - -//----------------------------------------------------------------------------- -// symbol methods -//----------------------------------------------------------------------------- - -void CUtlSymbol::Initialize() -{ - // If this assert fails, then the module that this call is in has chosen to disallow - // use of the static symbol table. Usually, it's to prevent confusion because it's easy - // to accidentally use the global symbol table when you really want to use a specific one. - Assert( s_bAllowStaticSymbolTable ); - - // necessary to allow us to create global symbols - static bool symbolsInitialized = false; - if (!symbolsInitialized) - { - s_pSymbolTable = new CUtlSymbolTableMT; - symbolsInitialized = true; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Singleton to delete table on exit from module -//----------------------------------------------------------------------------- -class CCleanupUtlSymbolTable -{ -public: - ~CCleanupUtlSymbolTable() - { - delete CUtlSymbol::s_pSymbolTable; - CUtlSymbol::s_pSymbolTable = NULL; - } -}; - -static CCleanupUtlSymbolTable g_CleanupSymbolTable; - -CUtlSymbolTableMT* CUtlSymbol::CurrTable() -{ - Initialize(); - return s_pSymbolTable; -} - - -//----------------------------------------------------------------------------- -// string->symbol->string -//----------------------------------------------------------------------------- - -CUtlSymbol::CUtlSymbol( const char* pStr ) -{ - m_Id = CurrTable()->AddString( pStr ); -} - -const char* CUtlSymbol::String( ) const -{ - return CurrTable()->String(m_Id); -} - -void CUtlSymbol::DisableStaticSymbolTable() -{ - s_bAllowStaticSymbolTable = false; -} - -//----------------------------------------------------------------------------- -// checks if the symbol matches a string -//----------------------------------------------------------------------------- - -bool CUtlSymbol::operator==( const char* pStr ) const -{ - if (m_Id == UTL_INVAL_SYMBOL) - return false; - return strcmp( String(), pStr ) == 0; -} - - - -//----------------------------------------------------------------------------- -// symbol table stuff -//----------------------------------------------------------------------------- - -inline const char* CUtlSymbolTable::StringFromIndex( const CStringPoolIndex &index ) const -{ - Assert( index.m_iPool < m_StringPools.Count() ); - Assert( index.m_iOffset < m_StringPools[index.m_iPool]->m_TotalLen ); - - return &m_StringPools[index.m_iPool]->m_Data[index.m_iOffset]; -} - - -bool CUtlSymbolTable::CLess::operator()( const CStringPoolIndex &i1, const CStringPoolIndex &i2 ) const -{ - // Need to do pointer math because CUtlSymbolTable is used in CUtlVectors, and hence - // can be arbitrarily moved in memory on a realloc. Yes, this is portable. In reality, - // right now at least, because m_LessFunc is the first member of CUtlRBTree, and m_Lookup - // is the first member of CUtlSymbolTabke, this == pTable - CUtlSymbolTable *pTable = (CUtlSymbolTable *)( (byte *)this - offsetof(CUtlSymbolTable::CTree, m_LessFunc) ) - offsetof(CUtlSymbolTable, m_Lookup ); - const char* str1 = (i1 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString : - pTable->StringFromIndex( i1 ); - const char* str2 = (i2 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString : - pTable->StringFromIndex( i2 ); - - if ( !pTable->m_bInsensitive ) - return strcmp( str1, str2 ) < 0; - else - return strcmpi( str1, str2 ) < 0; -} - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -CUtlSymbolTable::CUtlSymbolTable( int growSize, int initSize, bool caseInsensitive ) : - m_Lookup( growSize, initSize ), m_bInsensitive( caseInsensitive ), m_StringPools( 8 ) -{ -} - -CUtlSymbolTable::~CUtlSymbolTable() -{ - // Release the stringpool string data - RemoveAll(); -} - - -CUtlSymbol CUtlSymbolTable::Find( const char* pString ) const -{ - if (!pString) - return CUtlSymbol(); - - // Store a special context used to help with insertion - m_pUserSearchString = pString; - - // Passing this special invalid symbol makes the comparison function - // use the string passed in the context - UtlSymId_t idx = m_Lookup.Find( INVALID_STRING_INDEX ); - -#ifdef _DEBUG - m_pUserSearchString = NULL; -#endif - - return CUtlSymbol( idx ); -} - - -int CUtlSymbolTable::FindPoolWithSpace( int len ) const -{ - for ( int i=0; i < m_StringPools.Count(); i++ ) - { - StringPool_t *pPool = m_StringPools[i]; - - if ( (pPool->m_TotalLen - pPool->m_SpaceUsed) >= len ) - { - return i; - } - } - - return -1; -} - - -//----------------------------------------------------------------------------- -// Finds and/or creates a symbol based on the string -//----------------------------------------------------------------------------- - -CUtlSymbol CUtlSymbolTable::AddString( const char* pString ) -{ - if (!pString) - return CUtlSymbol( UTL_INVAL_SYMBOL ); - - CUtlSymbol id = Find( pString ); - - if (id.IsValid()) - return id; - - int len = strlen(pString) + 1; - - // Find a pool with space for this string, or allocate a new one. - int iPool = FindPoolWithSpace( len ); - if ( iPool == -1 ) - { - // Add a new pool. - int newPoolSize = max( len, MIN_STRING_POOL_SIZE ); - StringPool_t *pPool = (StringPool_t*)malloc( sizeof( StringPool_t ) + newPoolSize - 1 ); - pPool->m_TotalLen = newPoolSize; - pPool->m_SpaceUsed = 0; - iPool = m_StringPools.AddToTail( pPool ); - } - - // Copy the string in. - StringPool_t *pPool = m_StringPools[iPool]; - Assert( pPool->m_SpaceUsed < 0xFFFF ); // This should never happen, because if we had a string > 64k, it - // would have been given its entire own pool. - - unsigned short iStringOffset = pPool->m_SpaceUsed; - - memcpy( &pPool->m_Data[pPool->m_SpaceUsed], pString, len ); - pPool->m_SpaceUsed += len; - - // didn't find, insert the string into the vector. - CStringPoolIndex index; - index.m_iPool = iPool; - index.m_iOffset = iStringOffset; - - UtlSymId_t idx = m_Lookup.Insert( index ); - return CUtlSymbol( idx ); -} - - -//----------------------------------------------------------------------------- -// Look up the string associated with a particular symbol -//----------------------------------------------------------------------------- - -const char* CUtlSymbolTable::String( CUtlSymbol id ) const -{ - if (!id.IsValid()) - return ""; - - Assert( m_Lookup.IsValidIndex((UtlSymId_t)id) ); - return StringFromIndex( m_Lookup[id] ); -} - - -//----------------------------------------------------------------------------- -// Remove all symbols in the table. -//----------------------------------------------------------------------------- - -void CUtlSymbolTable::RemoveAll() -{ - m_Lookup.Purge(); - - for ( int i=0; i < m_StringPools.Count(); i++ ) - free( m_StringPools[i] ); - - m_StringPools.RemoveAll(); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pFileName - -// Output : FileNameHandle_t -//----------------------------------------------------------------------------- -FileNameHandle_t CUtlFilenameSymbolTable::FindOrAddFileName( const char *pFileName ) -{ - if ( !pFileName ) - { - return NULL; - } - - // find first - FileNameHandle_t hFileName = FindFileName( pFileName ); - if ( hFileName ) - { - return hFileName; - } - - // Fix slashes+dotslashes and make lower case first.. - char fn[ MAX_PATH ]; - Q_strncpy( fn, pFileName, sizeof( fn ) ); - Q_RemoveDotSlashes( fn ); -#ifdef _WIN32 - strlwr( fn ); -#endif - - // Split the filename into constituent parts - char basepath[ MAX_PATH ]; - Q_ExtractFilePath( fn, basepath, sizeof( basepath ) ); - char filename[ MAX_PATH ]; - Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) ); - - // not found, lock and look again - FileNameHandleInternal_t handle; - m_lock.LockForWrite(); - handle.path = m_StringPool.FindStringHandle( basepath ); - handle.file = m_StringPool.FindStringHandle( filename ); - if ( handle.path && handle.file ) - { - // found - m_lock.UnlockWrite(); - return *( FileNameHandle_t * )( &handle ); - } - - // safely add it - handle.path = m_StringPool.ReferenceStringHandle( basepath ); - handle.file = m_StringPool.ReferenceStringHandle( filename ); - m_lock.UnlockWrite(); - - return *( FileNameHandle_t * )( &handle ); -} - -FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( const char *pFileName ) -{ - if ( !pFileName ) - { - return NULL; - } - - // Fix slashes+dotslashes and make lower case first.. - char fn[ MAX_PATH ]; - Q_strncpy( fn, pFileName, sizeof( fn ) ); - Q_RemoveDotSlashes( fn ); -#ifdef _WIN32 - strlwr( fn ); -#endif - - // Split the filename into constituent parts - char basepath[ MAX_PATH ]; - Q_ExtractFilePath( fn, basepath, sizeof( basepath ) ); - char filename[ MAX_PATH ]; - Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) ); - - FileNameHandleInternal_t handle; - - m_lock.LockForRead(); - handle.path = m_StringPool.FindStringHandle(basepath); - handle.file = m_StringPool.FindStringHandle(filename); - m_lock.UnlockRead(); - - if ( handle.path == NULL || handle.file == NULL ) - return NULL; - - return *( FileNameHandle_t * )( &handle ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : handle - -// Output : const char -//----------------------------------------------------------------------------- -bool CUtlFilenameSymbolTable::String( const FileNameHandle_t& handle, char *buf, int buflen ) -{ - buf[ 0 ] = 0; - - FileNameHandleInternal_t *internal = ( FileNameHandleInternal_t * )&handle; - if ( !internal ) - { - return false; - } - - m_lock.LockForRead(); - const char *path = m_StringPool.HandleToString(internal->path); - const char *fn = m_StringPool.HandleToString(internal->file); - m_lock.UnlockRead(); - - if ( !path || !fn ) - { - return false; - } - - Q_strncpy( buf, path, buflen ); - Q_strncat( buf, fn, buflen, COPY_ALL_CHARACTERS ); - - return true; -} - -void CUtlFilenameSymbolTable::RemoveAll() -{ - m_StringPool.FreeAll(); -} - -void CUtlFilenameSymbolTable::SpewStrings() -{ - m_lock.LockForRead(); - m_StringPool.SpewStrings(); - m_lock.UnlockRead(); - -} diff --git a/Resources/NetHook/tier1/utlsymbol.h b/Resources/NetHook/tier1/utlsymbol.h deleted file mode 100644 index 9bfa2e27..00000000 --- a/Resources/NetHook/tier1/utlsymbol.h +++ /dev/null @@ -1,261 +0,0 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: Defines a symbol table -// -// $Header: $ -// $NoKeywords: $ -//===========================================================================// - -#ifndef UTLSYMBOL_H -#define UTLSYMBOL_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "tier0/threadtools.h" -#include "tier1/utlrbtree.h" -#include "tier1/utlvector.h" -#include "tier1/stringpool.h" - - -//----------------------------------------------------------------------------- -// forward declarations -//----------------------------------------------------------------------------- -class CUtlSymbolTable; -class CUtlSymbolTableMT; - - -//----------------------------------------------------------------------------- -// This is a symbol, which is a easier way of dealing with strings. -//----------------------------------------------------------------------------- -typedef unsigned short UtlSymId_t; - -#define UTL_INVAL_SYMBOL ((UtlSymId_t)~0) - -class CUtlSymbol -{ -public: - // constructor, destructor - CUtlSymbol() : m_Id(UTL_INVAL_SYMBOL) {} - CUtlSymbol( UtlSymId_t id ) : m_Id(id) {} - CUtlSymbol( const char* pStr ); - CUtlSymbol( CUtlSymbol const& sym ) : m_Id(sym.m_Id) {} - - // operator= - CUtlSymbol& operator=( CUtlSymbol const& src ) { m_Id = src.m_Id; return *this; } - - // operator== - bool operator==( CUtlSymbol const& src ) const { return m_Id == src.m_Id; } - bool operator==( const char* pStr ) const; - - // Is valid? - bool IsValid() const { return m_Id != UTL_INVAL_SYMBOL; } - - // Gets at the symbol - operator UtlSymId_t const() const { return m_Id; } - - // Gets the string associated with the symbol - const char* String( ) const; - - // Modules can choose to disable the static symbol table so to prevent accidental use of them. - static void DisableStaticSymbolTable(); - -protected: - UtlSymId_t m_Id; - - // Initializes the symbol table - static void Initialize(); - - // returns the current symbol table - static CUtlSymbolTableMT* CurrTable(); - - // The standard global symbol table - static CUtlSymbolTableMT* s_pSymbolTable; - - static bool s_bAllowStaticSymbolTable; - - friend class CCleanupUtlSymbolTable; -}; - - -//----------------------------------------------------------------------------- -// CUtlSymbolTable: -// description: -// This class defines a symbol table, which allows us to perform mappings -// of strings to symbols and back. The symbol class itself contains -// a static version of this class for creating global strings, but this -// class can also be instanced to create local symbol tables. -//----------------------------------------------------------------------------- - -class CUtlSymbolTable -{ -public: - // constructor, destructor - CUtlSymbolTable( int growSize = 0, int initSize = 32, bool caseInsensitive = false ); - ~CUtlSymbolTable(); - - // Finds and/or creates a symbol based on the string - CUtlSymbol AddString( const char* pString ); - - // Finds the symbol for pString - CUtlSymbol Find( const char* pString ) const; - - // Look up the string associated with a particular symbol - const char* String( CUtlSymbol id ) const; - - // Remove all symbols in the table. - void RemoveAll(); - - int GetNumStrings( void ) const - { - return m_Lookup.Count(); - } - -protected: - class CStringPoolIndex - { - public: - inline CStringPoolIndex() - { - } - - inline CStringPoolIndex( unsigned short iPool, unsigned short iOffset ) - { - m_iPool = iPool; - m_iOffset = iOffset; - } - - inline bool operator==( const CStringPoolIndex &other ) const - { - return m_iPool == other.m_iPool && m_iOffset == other.m_iOffset; - } - - unsigned short m_iPool; // Index into m_StringPools. - unsigned short m_iOffset; // Index into the string pool. - }; - - class CLess - { - public: - CLess( int ignored = 0 ) {} // permits default initialization to NULL in CUtlRBTree - bool operator!() const { return false; } - bool operator()( const CStringPoolIndex &left, const CStringPoolIndex &right ) const; - }; - - // Stores the symbol lookup - class CTree : public CUtlRBTree - { - public: - CTree( int growSize, int initSize ) : CUtlRBTree( growSize, initSize ) {} - friend class CUtlSymbolTable::CLess; // Needed to allow CLess to calculate pointer to symbol table - }; - - struct StringPool_t - { - int m_TotalLen; // How large is - int m_SpaceUsed; - char m_Data[1]; - }; - - CTree m_Lookup; - bool m_bInsensitive; - mutable const char* m_pUserSearchString; - - // stores the string data - CUtlVector m_StringPools; - -private: - int FindPoolWithSpace( int len ) const; - const char* StringFromIndex( const CStringPoolIndex &index ) const; - - friend class CLess; -}; - -class CUtlSymbolTableMT : private CUtlSymbolTable -{ -public: - CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false ) - : CUtlSymbolTable( growSize, initSize, caseInsensitive ) - { - } - - CUtlSymbol AddString( const char* pString ) - { - m_lock.LockForWrite(); - CUtlSymbol result = CUtlSymbolTable::AddString( pString ); - m_lock.UnlockWrite(); - return result; - } - - CUtlSymbol Find( const char* pString ) const - { - m_lock.LockForWrite(); - CUtlSymbol result = CUtlSymbolTable::Find( pString ); - m_lock.UnlockWrite(); - return result; - } - - const char* String( CUtlSymbol id ) const - { - m_lock.LockForRead(); - const char *pszResult = CUtlSymbolTable::String( id ); - m_lock.UnlockRead(); - return pszResult; - } - -private: - mutable CThreadSpinRWLock m_lock; -}; - - - -//----------------------------------------------------------------------------- -// CUtlFilenameSymbolTable: -// description: -// This class defines a symbol table of individual filenames, stored more -// efficiently than a standard symbol table. Internally filenames are broken -// up into file and path entries, and a file handle class allows convenient -// access to these. -//----------------------------------------------------------------------------- - -// The handle is a CUtlSymbol for the dirname and the same for the filename, the accessor -// copies them into a static char buffer for return. -typedef void* FileNameHandle_t; - -// Symbol table for more efficiently storing filenames by breaking paths and filenames apart. -// Refactored from BaseFileSystem.h -class CUtlFilenameSymbolTable -{ - // Internal representation of a FileHandle_t - // If we get more than 64K filenames, we'll have to revisit... - // Right now CUtlSymbol is a short, so this packs into an int/void * pointer size... - struct FileNameHandleInternal_t - { - FileNameHandleInternal_t() - { - path = 0; - file = 0; - } - - // Part before the final '/' character - unsigned short path; - // Part after the final '/', including extension - unsigned short file; - }; - -public: - FileNameHandle_t FindOrAddFileName( const char *pFileName ); - FileNameHandle_t FindFileName( const char *pFileName ); - int PathIndex(const FileNameHandle_t &handle) { return (( const FileNameHandleInternal_t * )&handle)->path; } - bool String( const FileNameHandle_t& handle, char *buf, int buflen ); - void RemoveAll(); - void SpewStrings(); - -private: - CCountedStringPool m_StringPool; - mutable CThreadSpinRWLock m_lock; -}; - - -#endif // UTLSYMBOL_H diff --git a/Resources/NetHook/tier1/utlvector.h b/Resources/NetHook/tier1/utlvector.h deleted file mode 100644 index 9dc4c6e9..00000000 --- a/Resources/NetHook/tier1/utlvector.h +++ /dev/null @@ -1,794 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -// $NoKeywords: $ -// -// A growable array class that maintains a free list and keeps elements -// in the same location -//=============================================================================// - -#ifndef UTLVECTOR_H -#define UTLVECTOR_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include -#include "tier0/platform.h" -#include "tier0/dbg.h" -#include "tier0/threadtools.h" -#include "tier1/utlmemory.h" -#include "tier1/utlblockmemory.h" -#include "tier1/strtools.h" - -#define FOR_EACH_VEC( vecName, iteratorName ) \ - for ( int iteratorName = 0; iteratorName < vecName.Count(); iteratorName++ ) - -//----------------------------------------------------------------------------- -// The CUtlVector class: -// A growable array class which doubles in size by default. -// It will always keep all elements consecutive in memory, and may move the -// elements around in memory (via a PvRealloc) when elements are inserted or -// removed. Clients should therefore refer to the elements of the vector -// by index (they should *never* maintain pointers to elements in the vector). -//----------------------------------------------------------------------------- -template< class T, class A = CUtlMemory > -class CUtlVector -{ - typedef A CAllocator; -public: - typedef T ElemType_t; - - // constructor, destructor - CUtlVector( int growSize = 0, int initSize = 0 ); - CUtlVector( T* pMemory, int allocationCount, int numElements = 0 ); - ~CUtlVector(); - - // Copy the array. - CUtlVector& operator=( const CUtlVector &other ); - - // element access - T& operator[]( int i ); - const T& operator[]( int i ) const; - T& Element( int i ); - const T& Element( int i ) const; - T& Head(); - const T& Head() const; - T& Tail(); - const T& Tail() const; - - // Gets the base address (can change when adding elements!) - T* Base() { return m_Memory.Base(); } - const T* Base() const { return m_Memory.Base(); } - - // Returns the number of elements in the vector - // SIZE IS DEPRECATED! - int Count() const; - int Size() const; // don't use me! - - // Is element index valid? - bool IsValidIndex( int i ) const; - static int InvalidIndex(); - - // Adds an element, uses default constructor - int AddToHead(); - int AddToTail(); - int InsertBefore( int elem ); - int InsertAfter( int elem ); - - // Adds an element, uses copy constructor - int AddToHead( const T& src ); - int AddToTail( const T& src ); - int InsertBefore( int elem, const T& src ); - int InsertAfter( int elem, const T& src ); - - // Adds multiple elements, uses default constructor - int AddMultipleToHead( int num ); - int AddMultipleToTail( int num, const T *pToCopy=NULL ); - int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); // If pToCopy is set, then it's an array of length 'num' and - int InsertMultipleAfter( int elem, int num ); - - // Calls RemoveAll() then AddMultipleToTail. - void SetSize( int size ); - void SetCount( int count ); - - // Calls SetSize and copies each element. - void CopyArray( const T *pArray, int size ); - - // Fast swap - void Swap( CUtlVector< T, A > &vec ); - - // Add the specified array to the tail. - int AddVectorToTail( CUtlVector const &src ); - - // Finds an element (element needs operator== defined) - int Find( const T& src ) const; - - bool HasElement( const T& src ) const; - - // Makes sure we have enough memory allocated to store a requested # of elements - void EnsureCapacity( int num ); - - // Makes sure we have at least this many elements - void EnsureCount( int num ); - - // Element removal - void FastRemove( int elem ); // doesn't preserve order - void Remove( int elem ); // preserves order, shifts elements - bool FindAndRemove( const T& src ); // removes first occurrence of src, preserves order, shifts elements - void RemoveMultiple( int elem, int num ); // preserves order, shifts elements - void RemoveAll(); // doesn't deallocate memory - - // Memory deallocation - void Purge(); - - // Purges the list and calls delete on each element in it. - void PurgeAndDeleteElements(); - - // Compacts the vector to the number of elements actually in use - void Compact(); - - // Set the size by which it grows when it needs to allocate more memory. - void SetGrowSize( int size ) { m_Memory.SetGrowSize( size ); } - - int NumAllocated() const; // Only use this if you really know what you're doing! - - void Sort( int (__cdecl *pfnCompare)(const T *, const T *) ); - -#ifdef DBGFLAG_VALIDATE - void Validate( CValidator &validator, char *pchName ); // Validate our internal structures -#endif // DBGFLAG_VALIDATE - -protected: - // Can't copy this unless we explicitly do it! - CUtlVector( CUtlVector const& vec ) { Assert(0); } - - // Grows the vector - void GrowVector( int num = 1 ); - - // Shifts elements.... - void ShiftElementsRight( int elem, int num = 1 ); - void ShiftElementsLeft( int elem, int num = 1 ); - - CAllocator m_Memory; - int m_Size; - - // For easier access to the elements through the debugger - // it's in release builds so this can be used in libraries correctly - T *m_pElements; - - inline void ResetDbgInfo() - { - m_pElements = Base(); - } -}; - - -// this is kind of ugly, but until C++ gets templatized typedefs in C++0x, it's our only choice -template < class T > -class CUtlBlockVector : public CUtlVector< T, CUtlBlockMemory< T, int > > -{ -public: - CUtlBlockVector( int growSize = 0, int initSize = 0 ) - : CUtlVector< T, CUtlBlockMemory< T, int > >( growSize, initSize ) {} -}; - -//----------------------------------------------------------------------------- -// The CUtlVectorFixed class: -// A array class with a fixed allocation scheme -//----------------------------------------------------------------------------- - -template< class BASE_UTLVECTOR, class MUTEX_TYPE = CThreadFastMutex > -class CUtlVectorMT : public BASE_UTLVECTOR, public MUTEX_TYPE -{ - typedef BASE_UTLVECTOR BaseClass; -public: - MUTEX_TYPE Mutex_t; - - // constructor, destructor - CUtlVectorMT( int growSize = 0, int initSize = 0 ) : BaseClass( growSize, initSize ) {} - CUtlVectorMT( typename BaseClass::ElemType_t* pMemory, int numElements ) : BaseClass( pMemory, numElements ) {} -}; - - -//----------------------------------------------------------------------------- -// The CUtlVectorFixed class: -// A array class with a fixed allocation scheme -//----------------------------------------------------------------------------- -template< class T, size_t MAX_SIZE > -class CUtlVectorFixed : public CUtlVector< T, CUtlMemoryFixed > -{ - typedef CUtlVector< T, CUtlMemoryFixed > BaseClass; -public: - - // constructor, destructor - CUtlVectorFixed( int growSize = 0, int initSize = 0 ) : BaseClass( growSize, initSize ) {} - CUtlVectorFixed( T* pMemory, int numElements ) : BaseClass( pMemory, numElements ) {} -}; - - -//----------------------------------------------------------------------------- -// The CUtlVectorFixed class: -// A array class with a fixed allocation scheme -//----------------------------------------------------------------------------- -template< class T, size_t MAX_SIZE > -class CUtlVectorFixedGrowable : public CUtlVector< T, CUtlMemoryFixedGrowable > -{ - typedef CUtlVector< T, CUtlMemoryFixedGrowable > BaseClass; - -public: - // constructor, destructor - CUtlVectorFixedGrowable( int growSize = 0 ) : BaseClass( growSize, MAX_SIZE ) {} -}; - - -//----------------------------------------------------------------------------- -// The CCopyableUtlVector class: -// A array class that allows copy construction (so you can nest a CUtlVector inside of another one of our containers) -// WARNING - this class lets you copy construct which can be an expensive operation if you don't carefully control when it happens -// Only use this when nesting a CUtlVector() inside of another one of our container classes (i.e a CUtlMap) -//----------------------------------------------------------------------------- -template< class T > -class CCopyableUtlVector : public CUtlVector< T, CUtlMemory > -{ - typedef CUtlVector< T, CUtlMemory > BaseClass; -public: - CCopyableUtlVector( int growSize = 0, int initSize = 0 ) : BaseClass( growSize, initSize ) {} - CCopyableUtlVector( T* pMemory, int numElements ) : BaseClass( pMemory, numElements ) {} - virtual ~CCopyableUtlVector() {} - CCopyableUtlVector( CCopyableUtlVector const& vec ) { CopyArray( vec.Base(), vec.Count() ); } -}; - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template< typename T, class A > -inline CUtlVector::CUtlVector( int growSize, int initSize ) : - m_Memory(growSize, initSize), m_Size(0) -{ - ResetDbgInfo(); -} - -template< typename T, class A > -inline CUtlVector::CUtlVector( T* pMemory, int allocationCount, int numElements ) : - m_Memory(pMemory, allocationCount), m_Size(numElements) -{ - ResetDbgInfo(); -} - -template< typename T, class A > -inline CUtlVector::~CUtlVector() -{ - Purge(); -} - -template< typename T, class A > -inline CUtlVector& CUtlVector::operator=( const CUtlVector &other ) -{ - int nCount = other.Count(); - SetSize( nCount ); - for ( int i = 0; i < nCount; i++ ) - { - (*this)[ i ] = other[ i ]; - } - return *this; -} - - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< typename T, class A > -inline T& CUtlVector::operator[]( int i ) -{ - return m_Memory[ i ]; -} - -template< typename T, class A > -inline const T& CUtlVector::operator[]( int i ) const -{ - return m_Memory[ i ]; -} - -template< typename T, class A > -inline T& CUtlVector::Element( int i ) -{ - return m_Memory[ i ]; -} - -template< typename T, class A > -inline const T& CUtlVector::Element( int i ) const -{ - return m_Memory[ i ]; -} - -template< typename T, class A > -inline T& CUtlVector::Head() -{ - Assert( m_Size > 0 ); - return m_Memory[ 0 ]; -} - -template< typename T, class A > -inline const T& CUtlVector::Head() const -{ - Assert( m_Size > 0 ); - return m_Memory[ 0 ]; -} - -template< typename T, class A > -inline T& CUtlVector::Tail() -{ - Assert( m_Size > 0 ); - return m_Memory[ m_Size - 1 ]; -} - -template< typename T, class A > -inline const T& CUtlVector::Tail() const -{ - Assert( m_Size > 0 ); - return m_Memory[ m_Size - 1 ]; -} - - -//----------------------------------------------------------------------------- -// Count -//----------------------------------------------------------------------------- -template< typename T, class A > -inline int CUtlVector::Size() const -{ - return m_Size; -} - -template< typename T, class A > -inline int CUtlVector::Count() const -{ - return m_Size; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< typename T, class A > -inline bool CUtlVector::IsValidIndex( int i ) const -{ - return (i >= 0) && (i < m_Size); -} - - -//----------------------------------------------------------------------------- -// Returns in invalid index -//----------------------------------------------------------------------------- -template< typename T, class A > -inline int CUtlVector::InvalidIndex() -{ - return -1; -} - - -//----------------------------------------------------------------------------- -// Grows the vector -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::GrowVector( int num ) -{ - if (m_Size + num > m_Memory.NumAllocated()) - { - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.Grow( m_Size + num - m_Memory.NumAllocated() ); - } - - m_Size += num; - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Sorts the vector -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::Sort( int (__cdecl *pfnCompare)(const T *, const T *) ) -{ - typedef int (__cdecl *QSortCompareFunc_t)(const void *, const void *); - if ( Count() <= 1 ) - return; - - if ( Base() ) - { - qsort( Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare) ); - } - else - { - Assert( 0 ); - // this path is untested - // if you want to sort vectors that use a non-sequential memory allocator, - // you'll probably want to patch in a quicksort algorithm here - // I just threw in this bubble sort to have something just in case... - - for ( int i = m_Size - 1; i >= 0; --i ) - { - for ( int j = 1; j <= i; ++j ) - { - if ( pfnCompare( &Element( j - 1 ), &Element( j ) ) < 0 ) - { - swap( Element( j - 1 ), Element( j ) ); - } - } - } - } -} - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::EnsureCapacity( int num ) -{ - MEM_ALLOC_CREDIT_CLASS(); - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Makes sure we have at least this many elements -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::EnsureCount( int num ) -{ - if (Count() < num) - AddMultipleToTail( num - Count() ); -} - - -//----------------------------------------------------------------------------- -// Shifts elements -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::ShiftElementsRight( int elem, int num ) -{ - Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 )); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) - Q_memmove( &Element(elem+num), &Element(elem), numToMove * sizeof(T) ); -} - -template< typename T, class A > -void CUtlVector::ShiftElementsLeft( int elem, int num ) -{ - Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 )); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) - { - Q_memmove( &Element(elem), &Element(elem+num), numToMove * sizeof(T) ); - -#ifdef _DEBUG - Q_memset( &Element(m_Size-num), 0xDD, num * sizeof(T) ); -#endif - } -} - - -//----------------------------------------------------------------------------- -// Adds an element, uses default constructor -//----------------------------------------------------------------------------- -template< typename T, class A > -inline int CUtlVector::AddToHead() -{ - return InsertBefore(0); -} - -template< typename T, class A > -inline int CUtlVector::AddToTail() -{ - return InsertBefore( m_Size ); -} - -template< typename T, class A > -inline int CUtlVector::InsertAfter( int elem ) -{ - return InsertBefore( elem + 1 ); -} - -template< typename T, class A > -int CUtlVector::InsertBefore( int elem ) -{ - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(); - ShiftElementsRight(elem); - Construct( &Element(elem) ); - return elem; -} - - -//----------------------------------------------------------------------------- -// Adds an element, uses copy constructor -//----------------------------------------------------------------------------- -template< typename T, class A > -inline int CUtlVector::AddToHead( const T& src ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count()) ) ); - return InsertBefore( 0, src ); -} - -template< typename T, class A > -inline int CUtlVector::AddToTail( const T& src ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count()) ) ); - return InsertBefore( m_Size, src ); -} - -template< typename T, class A > -inline int CUtlVector::InsertAfter( int elem, const T& src ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count()) ) ); - return InsertBefore( elem + 1, src ); -} - -template< typename T, class A > -int CUtlVector::InsertBefore( int elem, const T& src ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count()) ) ); - - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(); - ShiftElementsRight(elem); - CopyConstruct( &Element(elem), src ); - return elem; -} - - -//----------------------------------------------------------------------------- -// Adds multiple elements, uses default constructor -//----------------------------------------------------------------------------- -template< typename T, class A > -inline int CUtlVector::AddMultipleToHead( int num ) -{ - return InsertMultipleBefore( 0, num ); -} - -template< typename T, class A > -inline int CUtlVector::AddMultipleToTail( int num, const T *pToCopy ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || !pToCopy || (pToCopy + num < Base()) || (pToCopy >= (Base() + Count()) ) ); - - return InsertMultipleBefore( m_Size, num, pToCopy ); -} - -template< typename T, class A > -int CUtlVector::InsertMultipleAfter( int elem, int num ) -{ - return InsertMultipleBefore( elem + 1, num ); -} - - -template< typename T, class A > -void CUtlVector::SetCount( int count ) -{ - RemoveAll(); - AddMultipleToTail( count ); -} - -template< typename T, class A > -inline void CUtlVector::SetSize( int size ) -{ - SetCount( size ); -} - -template< typename T, class A > -void CUtlVector::CopyArray( const T *pArray, int size ) -{ - // Can't insert something that's in the list... reallocation may hose us - Assert( (Base() == NULL) || !pArray || (Base() >= (pArray + size)) || (pArray >= (Base() + Count()) ) ); - - SetSize( size ); - for( int i=0; i < size; i++ ) - { - (*this)[i] = pArray[i]; - } -} - -template< typename T, class A > -void CUtlVector::Swap( CUtlVector< T, A > &vec ) -{ - m_Memory.Swap( vec.m_Memory ); - swap( m_Size, vec.m_Size ); - swap( m_pElements, vec.m_pElements ); -} - -template< typename T, class A > -int CUtlVector::AddVectorToTail( CUtlVector const &src ) -{ - Assert( &src != this ); - - int base = Count(); - - // Make space. - AddMultipleToTail( src.Count() ); - - // Copy the elements. - for ( int i=0; i < src.Count(); i++ ) - { - (*this)[base + i] = src[i]; - } - - return base; -} - -template< typename T, class A > -inline int CUtlVector::InsertMultipleBefore( int elem, int num, const T *pToInsert ) -{ - if( num == 0 ) - return elem; - - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(num); - ShiftElementsRight(elem, num); - - // Invoke default constructors - for (int i = 0; i < num; ++i) - Construct( &Element(elem+i) ); - - // Copy stuff in? - if ( pToInsert ) - { - for ( int i=0; i < num; i++ ) - { - Element( elem+i ) = pToInsert[i]; - } - } - - return elem; -} - - -//----------------------------------------------------------------------------- -// Finds an element (element needs operator== defined) -//----------------------------------------------------------------------------- -template< typename T, class A > -int CUtlVector::Find( const T& src ) const -{ - for ( int i = 0; i < Count(); ++i ) - { - if (Element(i) == src) - return i; - } - return -1; -} - -template< typename T, class A > -bool CUtlVector::HasElement( const T& src ) const -{ - return ( Find(src) >= 0 ); -} - - -//----------------------------------------------------------------------------- -// Element removal -//----------------------------------------------------------------------------- -template< typename T, class A > -void CUtlVector::FastRemove( int elem ) -{ - Assert( IsValidIndex(elem) ); - - Destruct( &Element(elem) ); - if (m_Size > 0) - { - memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) ); - --m_Size; - } -} - -template< typename T, class A > -void CUtlVector::Remove( int elem ) -{ - Destruct( &Element(elem) ); - ShiftElementsLeft(elem); - --m_Size; -} - -template< typename T, class A > -bool CUtlVector::FindAndRemove( const T& src ) -{ - int elem = Find( src ); - if ( elem != -1 ) - { - Remove( elem ); - return true; - } - return false; -} - -template< typename T, class A > -void CUtlVector::RemoveMultiple( int elem, int num ) -{ - Assert( elem >= 0 ); - Assert( elem + num <= Count() ); - - for (int i = elem + num; --i >= elem; ) - Destruct(&Element(i)); - - ShiftElementsLeft(elem, num); - m_Size -= num; -} - -template< typename T, class A > -void CUtlVector::RemoveAll() -{ - for (int i = m_Size; --i >= 0; ) - { - Destruct(&Element(i)); - } - - m_Size = 0; -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- - -template< typename T, class A > -inline void CUtlVector::Purge() -{ - RemoveAll(); - m_Memory.Purge(); - ResetDbgInfo(); -} - - -template< typename T, class A > -inline void CUtlVector::PurgeAndDeleteElements() -{ - for( int i=0; i < m_Size; i++ ) - { - delete Element(i); - } - Purge(); -} - -template< typename T, class A > -inline void CUtlVector::Compact() -{ - m_Memory.Purge(m_Size); -} - -template< typename T, class A > -inline int CUtlVector::NumAllocated() const -{ - return m_Memory.NumAllocated(); -} - - -//----------------------------------------------------------------------------- -// Data and memory validation -//----------------------------------------------------------------------------- -#ifdef DBGFLAG_VALIDATE -template< typename T, class A > -void CUtlVector::Validate( CValidator &validator, char *pchName ) -{ - validator.Push( typeid(*this).name(), this, pchName ); - - m_Memory.Validate( validator, "m_Memory" ); - - validator.Pop(); -} -#endif // DBGFLAG_VALIDATE - - -#endif // CCVECTOR_H diff --git a/Resources/NetHook/utils.cpp b/Resources/NetHook/utils.cpp deleted file mode 100644 index 3690d874..00000000 --- a/Resources/NetHook/utils.cpp +++ /dev/null @@ -1,6527 +0,0 @@ - - -#include "utils.h" -#include "crypto.h" - -#include -#include -#include - - -const char *k_szEUDPPktTypes[] = -{ - "Invalid EUDPPktType", - - "k_EUDPPktTypeChallengeReq", - "k_EUDPPktTypeChallenge", - "k_EUDPPktTypeConnect", - "k_EUDPPktTypeAccept", - "k_EUDPPktTypeDisconnect", - "k_EUDPPktTypeData", - "k_EUDPPktTypeDatagram", -}; - -const char *PchStringFromUDPPktHdr( const UDPPktHdr_t *pHdr ) -{ - static char szBuff[ 1024 * 8 ]; - memset( szBuff, 0, sizeof( szBuff ) ); - - sprintf_s( szBuff, sizeof( szBuff ), - - "UDPPktHdr\r\n" - " m_cbPkt = %u bytes\r\n" - " m_EUDPPktType = %s (%u)\r\n" - " m_nFlags = %s (%u)\r\n" - " m_nSrcConnectionID = %u\r\n" - " m_nDstConnectionID = %u\r\n" - " m_nSeqThis = %u\r\n" - " m_nSeqAcked = %u\r\n" - " m_nPktsInMsg = %u\r\n" - " m_nMsgStartSeq = %u\r\n" - " m_cbMsgData = %u\r\n", - - pHdr->m_cbPkt, - PchNameFromEUDPPktType( (EUDPPktType)pHdr->m_EUDPPktType ), pHdr->m_EUDPPktType, - PchNameFromNetFlags( pHdr->m_nFlags ), pHdr->m_nFlags, - pHdr->m_nSrcConnectionID, - pHdr->m_nDstConnectionID, - pHdr->m_nSeqThis, - pHdr->m_nSeqAcked, - pHdr->m_nPktsInMsg, - pHdr->m_nMsgStartSeq, - pHdr->m_cbMsgData - ); - - return szBuff; - -} - -const char *PchStringFromMsgHdr( const MsgHdr_t *pMsgHdr ) -{ - static char szBuff[ 1024 * 8 ]; - memset( szBuff, 0, sizeof( szBuff ) ); - - sprintf_s( szBuff, sizeof( szBuff ), - - " MsgHdr_t\r\n" - " m_EMsg = %s (%u)\r\n" - " m_JobIDTarget = %llu\r\n" - " m_JobIDSource = %llu\r\n", - - g_Crypto->GetMessage( (EMsg)pMsgHdr->m_EMsg ), pMsgHdr->m_EMsg, - pMsgHdr->m_JobIDTarget, - pMsgHdr->m_JobIDSource - - ); - - return szBuff; -} - -const char *PchStringFromExtendedClientMsgHdr( const ExtendedClientMsgHdr_t *pMsgHdr ) -{ - static char szBuff[ 1024 * 8 ]; - memset( szBuff, 0, sizeof( szBuff ) ); - - const CSteamID *steamId = &pMsgHdr->m_ulSteamID; - - sprintf_s( szBuff, sizeof( szBuff ), - - " ExtendedClientMsgHdr_t\r\n" - " m_EMsg = %s (%u)\r\n" - " m_nCubHdr = %u\r\n" - " m_nHdrVersion = %u\r\n" - " m_JobIDTarget = %llu\r\n" - " m_JobIDSource = %llu\r\n" - " m_nHdrCanary = %u\r\n" - " m_ulSteamID = %s %s (%llu) (id = %d, instance = %d, type = %s (%d), universe = %s (%d))\r\n" - " m_nSessionID = %u\r\n", - - g_Crypto->GetMessage( (EMsg)pMsgHdr->m_EMsg ), pMsgHdr->m_EMsg, - pMsgHdr->m_nCubHdr, - pMsgHdr->m_nHdrVersion, - pMsgHdr->m_JobIDTarget, - pMsgHdr->m_JobIDSource, - pMsgHdr->m_nHdrCanary, - steamId->Render(), steamId->SteamRender(), steamId->ConvertToUint64(), - steamId->GetAccountID(), steamId->GetUnAccountInstance(), PchNameFromEAccountType( steamId->GetEAccountType() ), steamId->GetEAccountType(), - PchNameFromEUniverse( steamId->GetEUniverse() ), steamId->GetEUniverse(), - pMsgHdr->m_nSessionID - - ); - - return szBuff; -} - -char *szData = NULL; -const char *PchStringFromData( const uint8 *pData, uint32 cubData ) -{ - if ( cubData == 0 ) - return ""; - - uint32 memSize = cubData * 4; - - szData = (char *)realloc( szData, memSize ); - memset( szData, 0, memSize ); - - for ( uint32 x = 0; x < cubData; ++x ) - { - sprintf_s( szData, memSize, "%s%02X ", szData, (uint8 )pData[ x ] ); - - if ( ( x + 1 ) % 12 == 0 ) - sprintf_s( szData, memSize, "%s\r\n ", szData ); - } - - return szData; -} - -const char *PchNameFromEUDPPktType( EUDPPktType eUdpPktType ) -{ - if ( eUdpPktType <= 0 || eUdpPktType >= k_EUDPPktTypeMax ) - return k_szEUDPPktTypes[ 0 ]; - - return k_szEUDPPktTypes[ (int)eUdpPktType ]; -} - -const char *PchNameFromNetFlags( uint32 netFlags ) -{ - static char szBuff[ 1024 ]; - memset( szBuff, 0, sizeof( szBuff ) ); - - std::string str = ""; - - if ( netFlags & k_uNetFlagNoIOCP ) - str += "k_uNetFlagNoIOCP "; - - if ( netFlags & k_uNetFlagFindAvailPort ) - str += "k_uNetFlagFindAvailPort "; - - if ( netFlags & k_uNetFlagUseAuthentication ) - str += "k_uNetFlagUseAuthentication "; - - if ( netFlags & k_uNetFlagUseEncryption ) - str += "k_uNetFlagUseEncryption "; - - if ( netFlags & k_uNetFlagRawStream ) - str += "k_uNetFlagRawStream "; - - if ( netFlags & k_uNetFlagRawStreamSend ) - str += "k_uNetFlagRawStreamSend "; - - if ( netFlags & k_uNetFlagUnboundSocket ) - str += "k_uNetFlagUnboundSocket "; - - if ( netFlags & k_uNetFlagRawIORecv ) - str += "k_uNetFlagRawIORecv "; - - const char *cStr = str.c_str(); - strcpy_s( szBuff, sizeof( szBuff ), cStr ); - - return szBuff; -} - -const char *k_szUniverse[] = -{ - "k_EUniverseInvalid", - - "k_EUniversePublic", - "k_EUniverseBeta", - "k_EUniverseInternal", - "k_EUniverseDev", - "k_EUniverseRC", - -}; - -const char *PchNameFromEUniverse( EUniverse eUniverse ) -{ - static char szBuff[ 1024 ]; - memset( szBuff, 0, sizeof( szBuff ) ); - - if ( eUniverse <= k_EUniverseInvalid || eUniverse >= k_EUniverseMax ) - return k_szUniverse[ 0 ]; - - return k_szUniverse[ (int)eUniverse ]; -} - -// fuck me. -const char *k_szEMsg[] = -{ - "k_EMsgInvalid", - "k_EMsgMulti", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgGenericReply", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgDestJobFailed", - "", - "k_EMsgAlert", - "", - "", - "", - "", - "k_EMsgSCIDRequest", - "k_EMsgSCIDResponse", - "", - "k_EMsgJobHeartbeat", - "", - "k_EMsgStats", - "k_EMsgSubscribe", - "k_EMRouteMessage", - "k_EMsgRemoteSysID", - "k_EMsgAMCreateAccountResponse", - "k_EMsgWGRequest", - "k_EMsgWGResponse", - "k_EMsgKeepAlive", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgAssignSysID", - "k_EMsgExit", - "k_EMsgDirRequest", - "k_EMsgDirResponse", - "k_EMsgZipRequest", - "k_EMsgZipResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgUpdateRecordResponse", - "", - "", - "", - "", - "", - "k_EMsgUpdateCreditCardRequest", - "", - "", - "", - "k_EMsgUpdateUserBanResponse", - "k_EMsgPrepareToExit", - "k_EMsgContentDescriptionUpdate", - "k_EMsgTestResetServer", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgHeartbeat", - "k_EMsgShellFailed", - "", - "", - "", - "", - "", - "k_EMsgExitShells", - "k_EMsgExitShell", - "k_EMsgGracefulExitShell", - "", - "", - "", - "", - "k_EMsgNotifyWatchdog", - "", - "k_EMsgLicenseProcessingComplete", - "k_EMsgSetTestFlag", - "k_EMsgQueuedEmailsComplete", - "k_EMsgGMReportPHPError", - "k_EMsgGMDRMSync", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseAIS", - "k_EMsgAISRefreshContentDescription", - "k_EMsgAISRequestContentDescription", - "k_EMsgAISUpdateAppInfo", - "k_EMsgAISUpdatePackageInfo", - "k_EMsgAISGetPackageChangeNumber", - "k_EMsgAISGetPackageChangeNumberResponse", - "k_EMsgAISAppInfoTableChanged", - "k_EMsgAISUpdatePackageInfoResponse", - "k_EMsgAISCreateMarketingMessage", - "k_EMsgAISCreateMarketingMessageResponse", - "k_EMsgAISGetMarketingMessage", - "k_EMsgAISGetMarketingMessageResponse", - "k_EMsgAISUpdateMarketingMessage", - "k_EMsgAISUpdateMarketingMessageResponse", - "k_EMsgAISRequestMarketingMessageUpdate", - "k_EMsgAISDeleteMarketingMessage", - "", - "", - "k_EMsgAISGetMarketingTreatments", - "k_EMsgAISGetMarketingTreatmentsResponse", - "k_EMsgAISRequestMarketingTreatmentUpdate", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseAM", - "", - "", - "", - "k_EMsgAMUpdateUserBanRequest", - "k_EMsgAMAddLicense", - "", - "k_EMsgAMBeginProcessingLicenses", - "k_EMsgAMSendSystemIMToUser", - "k_EMsgAMExtendLicense", - "k_EMsgAMAddMinutesToLicense", - "k_EMsgAMCancelLicense", - "k_EMsgAMInitPurchase", - "k_EMsgAMPurchaseResponse", - "k_EMsgAMGetFinalPrice", - "k_EMsgAMGetFinalPriceResponse", - "k_EMsgAMGetLegacyGameKey", - "k_EMsgAMGetLegacyGameKeyResponse", - "k_EMsgAMFindHungTransactions", - "k_EMsgAMSetAccountTrustedRequest", - "", - "k_EMsgAMCompletePurchase", - "k_EMsgAMCancelPurchase", - "k_EMsgAMNewChallenge", - "", - "", - "k_EMsgAMFixPendingPurchase", - "k_EMsgAMIsUserBanned", - "k_EMsgAMRegisterKey", - "k_EMsgAMLoadActivationCodes", - "k_EMsgAMLoadActivationCodesResponse", - "k_EMsgAMLookupKeyResponse", - "k_EMsgAMLookupKey", - "k_EMsgAMChatCleanup", - "k_EMsgAMClanCleanup", - "k_EMsgAMFixPendingRefund", - "k_EMsgAMReverseChargeback", - "k_EMsgAMReverseChargebackResponse", - "k_EMsgAMClanCleanupList", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgAllowUserToPlayQuery", - "k_EMsgAllowUserToPlayResponse", - "k_EMsgAMVerfiyUser", - "k_EMsgAMClientNotPlaying", - "k_EMsgAMClientRequestFriendship", - "k_EMsgAMRelayPublishStatus", - "k_EMsgAMResetCommunityContent", - "k_EMsgCAMPrimePersonaStateCache", - "k_EMsgAMAllowUserContentQuery", - "k_EMsgAMAllowUserContentResponse", - "k_EMsgAMInitPurchaseResponse", - "k_EMsgAMRevokePurchaseResponse", - "k_EMsgAMLockProfile", - "k_EMsgAMRefreshGuestPasses", - "k_EMsgAMInviteUserToClan", - "k_EMsgAMAcknowledgeClanInvite", - "k_EMsgAMGrantGuestPasses", - "k_EMsgAMClanDataUpdated", - "k_EMsgAMReloadAccount", - "k_EMsgAMClientChatMsgRelay", - "k_EMsgAMChatMulti", - "k_EMsgAMClientChatInviteRelay", - "k_EMsgAMChatInvite", - "k_EMsgAMClientJoinChatRelay", - "k_EMsgAMClientChatMemberInfoRelay", - "k_EMsgAMPublishChatMemberInfo", - "k_EMsgAMClientAcceptFriendInvite", - "k_EMsgAMChatEnter", - "k_EMsgAMClientPublishRemovalFromSource", - "k_EMsgAMChatActionResult", - "k_EMsgAMFindAccounts", - "k_EMsgAMFindAccountsResponse", - "", - "", - "k_EMsgAMSetAccountFlags", - "", - "k_EMsgAMCreateClan", - "k_EMsgAMCreateClanResponse", - "k_EMsgAMGetClanDetails", - "k_EMsgAMGetClanDetailsResponse", - "k_EMsgAMSetPersonaName", - "k_EMsgAMSetAvatar", - "k_EMsgAMAuthenticateUser", - "k_EMsgAMAuthenticateUserResponse", - "k_EMsgAMGetAccountFriendsCount", - "k_EMsgAMGetAccountFriendsCountResponse", - "k_EMsgAMP2PIntroducerMessage", - "k_EMsgClientChatAction", - "k_EMsgAMClientChatActionRelay", - "", - "k_EMsgReqChallenge", - "k_EMsgVACResponse", - "k_EMsgReqChallengeTest", - "k_EMsgVSInitDB", - "k_EMsgVSMarkCheat", - "k_EMsgVSAddCheat", - "k_EMsgVSPurgeCodeModDB", - "k_EMsgVSGetChallengeResults", - "k_EMsgVSChallengeResultText", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgClientCSGetDepotManifestChunk", - "", - "", - "", - "", - "k_EMsgBaseDRMS", - "", - "", - "k_EMsgDRMBuildBlobRequest", - "k_EMsgDRMBuildBlobResponse", - "k_EMsgDRMResolveGuidRequest", - "k_EMsgDRMResolveGuidResponse", - "", - "k_EMsgDRMVariabilityReport", - "k_EMsgDRMVariabilityReportResponse", - "k_EMsgDRMStabilityReport", - "k_EMsgDRMStabilityReportResponse", - "k_EMsgDRMDetailsReportRequest", - "k_EMsgDRMDetailsReportResponse", - "k_EMsgDRMProcessFile", - "k_EMsgDRMAdminUpdate", - "k_EMsgDRMAdminUpdateResponse", - "k_EMsgDRMSync", - "k_EMsgDRMSyncResposne", - "k_EMsgDRMProcessFileResponse", - "", - "", - "", - "", - "", - "k_EMsgBaseCS", - "k_EMsgCSManifestUpdate", - "k_EMsgCSUserContentRequest", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseClient", - "k_EMsgClientLogOn", - "k_EMsgClientAnonLogOn", - "k_EMsgClientHeartBeat", - "k_EMsgClientVACResponse", - "k_EMsgClientGamesPlayed_obsolete", - "k_EMsgClientLogOff", - "k_EMsgClientNoUDPConnectivity", - "k_EMsgClientInformOfCreateAccount", - "k_EMsgClientAckVACBan", - "k_EMsgClientConnectionStats", - "k_EMsgClientInitPurchase", - "k_EMsgClientPingResponse", - "k_EMsgClientAddFriend", - "k_EMsgClientRemoveFriend", - "k_EMsgClientGamesPlayedNoDataBlob", - "k_EMsgClientChangeStatus", - "k_EMsgClientVacStatusResponse", - "k_EMsgClientFriendMsg", - "k_EMsgClientGameConnect_obsolete", - "k_EMsgClientGamesPlayed2_obsolete", - "k_EMsgClientGameEnded_obsolete", - "k_EMsgClientGetFinalPrice", - "", - "", - "", - "k_EMsgClientSystemIM", - "k_EMsgClientSystemIMAck", - "k_EMsgClientGetLicenses", - "k_EMsgClientCancelLicense", - "k_EMsgClientGetLegacyGameKey", - "k_EMsgClientContentServerLogOn", - "k_EMsgClientAckVACBan2", - "k_EMsgClientCompletePurchase", - "k_EMsgClientCancelPurchase", - "k_EMsgClientAckMessageByGID", - "k_EMsgClientGetPurchaseReceipts", - "k_EMsgClientAckPurchaseReceipt", - "k_EMsgClientGamesPlayed3_obsolete", - "k_EMsgClientSendGuestPass", - "k_EMsgClientAckGuestPass", - "k_EMsgClientRedeemGuestPass", - "k_EMsgClientGamesPlayed", - "k_EMsgClientRegisterKey", - "k_EMsgClientInviteUserToClan", - "k_EMsgClientAcknowledgeClanInvite", - "k_EMsgClientPurchaseWithMachineID", - "k_EMsgClientAppUsageEvent", - "k_EMsgClientGetGiftTargetList", - "k_EMsgClientGetGiftTargetListResponse", - "", - "k_EMsgClientLogOnResponse", - "", - "k_EMsgClientVACChallenge", - "", - "k_EMsgClientSetHeartbeatRate", - "k_EMsgClientNotLoggedOnDeprecated", - "k_EMsgClientLoggedOff", - "k_EMsgGSApprove", - "k_EMsgGSDeny", - "k_EMsgGSKick", - "k_EMsgClientCreateAcctResponse", - "k_EMsgClientVACBanStatus", - "k_EMsgClientPurchaseResponse", - "k_EMsgClientPing", - "k_EMsgClientNOP", - "k_EMsgClientPersonaState", - "k_EMsgClientFriendsList", - "k_EMsgClientAccountInfo", - "k_EMsgClientAddFriendResponse", - "k_EMsgClientVacStatusQuery", - "k_EMsgClientNewsUpdate", - "", - "k_EMsgClientGameConnectDeny", - "k_EMsgGSStatusReply", - "k_EMsgClientGetFinalPriceResponse", - "", - "", - "", - "k_EMsgClientGameConnectTokens", - "k_EMsgClientLicenseList", - "k_EMsgClientCancelLicenseResponse", - "k_EMsgClientVACBanStatus2", - "k_EMsgClientCMList", - "k_EMsgClientEncryptPct", - "k_EMsgClientGetLegacyGameKeyResponse", - "k_EMsgClientFavoritesList", - "k_EMsgCSUserContentApprove", - "k_EMsgCSUserContentDeny", - "k_EMsgClientInitPurchaseResponse", - "k_EMsgClientGetPurchaseReceiptsResponse", - "k_EMsgClientAddFriend2", - "k_EMsgClientAddFriendResponse2", - "k_EMsgClientInviteFriend", - "k_EMsgClientInviteFriendResponse", - "k_EMsgClientSendGuestPassResponse", - "k_EMsgClientAckGuestPassResponse", - "k_EMsgClientRedeemGuestPassResponse", - "k_EMsgClientUpdateGuestPassesList", - "k_EMsgClientChatMsg", - "k_EMsgClientChatInvite", - "k_EMsgClientJoinChat", - "k_EMsgClientChatMemberInfo", - "k_EMsgClientLogOnWithCredentials", - "k_EMsgClientPasswordChange", - "k_EMsgClientPasswordChangeResponse", - "", - "k_EMsgClientChatEnter", - "k_EMsgClientFriendRemovedFromSource", - "k_EMsgClientCreateChat", - "k_EMsgClientCreateChatResponse", - "k_EMsgClientUpdateChatMetadata", - "k_EMsgClientP2PTrackerMessage", - "k_EMsgClientP2PIntroducerMessage", - "k_EMsgClientChatActionResult", - "k_EMsgClientRequestFriendData", - "k_EMsgClientOneTimeWGAuthPassword", - "", - "k_EMsgClientGetUserStats", - "k_EMsgClientGetUserStatsResponse", - "k_EMsgClientStoreUserStats", - "k_EMsgClientStoreUserStatsResponse", - "k_EMsgClientClanState", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgClientServiceModule", - "k_EMsgClientServiceCall", - "k_EMsgClientServiceCallResponse", - "", - "", - "", - "", - "", - "", - "k_EMsgClientNatTraversalStatEvent", - "k_EMsgClientAppInfoRequest", - "k_EMsgClientAppInfoResponse", - "k_EMsgClientSteamUsageEvent", - "k_EMsgClientEmailChange", - "k_EMsgClientPersonalQAChange", - "k_EMsgClientCheckPassword", - "k_EMsgClientResetPassword", - "", - "k_EMsgClientCheckPasswordResponse", - "k_EMsgClientResetPasswordResponse", - "k_EMsgClientSessionToken", - "k_EMsgClientDRMProblemReport", - "", - "", - "k_EMsgClientLogonBounce", - "k_EMsgClientSetIgnoreFriend", - "k_EMsgClientSetIgnoreFriendResponse", - "k_EMsgClientGetAppOwnershipTicket", - "k_EMsgClientGetAppOwnershipTicketResponse", - "", - "k_EMsgClientGetLobbyListResponse", - "k_EMsgClientGetLobbyMetadata", - "k_EMsgClientGetLobbyMetadataResponse", - "k_EMsgClientVTTCert", - "k_EMsgClientAppInfoRequestOld", - "k_EMsgClientAppInfoResponseOld", - "k_EMsgClientAppInfoUpdate", - "k_EMsgClientAppInfoChanges", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgClientServerList", - "k_EMsgClientUpdateInvPos", - "k_EMsgClientUpdateInvPosResponse", - "k_EMsgClientDeleteItem", - "k_EMsgClientDeleteItemResponse", - "k_EMsgClientLoadItems", - "k_EMsgClientLoadItemsResponse", - "k_EMsgClientItemGranted", - "k_EMsgClientGetFriendsLobbies", - "k_EMsgClientGetFriendsLobbiesResponse", - "k_EMsgClientGetLobbyList", - "k_EMsgClientEmailChangeResponse", - "k_EMsgClientSecretQAChangeResponse", - "k_EMsgClientPasswordChange2", - "k_EMsgClientEmailChange2", - "k_EMsgClientPersonalQAChange2", - "k_EMsgClientDRMBlobRequest", - "k_EMsgClientDRMBlobResponse", - "k_EMsgClientLookupKey", - "k_EMsgClientLookupKeyResponse", - "k_EMsgBaseGameServer", - "k_EMsgGSDisconnectNotice", - "", - "k_EMsgGSStatus", - "", - "k_EMsgGSUserPlaying3", - "k_EMsgGSStatus2", - "k_EMsgGSStatusUpdate", - "k_EMsgGSServerType", - "k_EMsgGSPlayerList", - "k_EMsgGSGetUserAchievementStatus", - "k_EMsgGSGetUserAchievementStatusResponse", - "k_EMsgGSCreateItem", - "k_EMsgGSCreateItemResponse", - "k_EMsgGSItemDeleted", - "k_EMsgGSItemUpdated", - "k_EMsgGSLoadItems", - "k_EMsgGSLoadItemsResponse", - "k_EMsgGSGetPlayStats", - "k_EMsgGSGetPlayStatsResponse", - "k_EMsgGSGetUserGroupStatus", - "k_EMsgAMGetUserGroupStatus", - "k_EMsgAMGetUserGroupStatusResponse", - "k_EMsgGSGetUserGroupStatusResponse", - "k_EMsgGSGrantItem", - "k_EMsgGSGrantItemResponse", - "k_EMsgGSDeleteTempItem", - "k_EMsgGSDeleteTempItemResponse", - "k_EMsgGSDeleteAllTempItems", - "k_EMsgGSDeleteAllTempItemsResponse", - "k_EMsgGSItemGranted", - "k_EMsgGSUpdateItemQuantity", - "k_EMsgGSUpdateItemQuantityResponse", - "k_EMsgGSRestoreOwnedItems", - "k_EMsgGSRestoreOwnedItemsResponse", - "k_EMsgGSItemDropped", - "k_EMsgGSGetReputation", - "k_EMsgGSGetReputationResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgAdminCmd", - "", - "", - "", - "k_EMsgAdminCmdResponse", - "k_EMsgAdminLogListenRequest", - "k_EMsgAdminLogEvent", - "k_EMsgLogSearchRequest", - "k_EMsgLogSearchResponse", - "k_EMsgLogSearchCancel", - "k_EMsgUniverseData", - "", - "", - "", - "k_EMsgRequestStatHistory", - "k_EMsgStatHistory", - "", - "k_EMsgAdminPwLogon", - "k_EMsgAdminPwLogonResponse", - "k_EMsgAdminSpew", - "k_EMsgAdminConsoleTitle", - "", - "", - "k_EMsgAdminGCSpew", - "k_EMsgAdminGCCommand", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgFBSReqVersion", - "k_EMsgFBSVersionInfo", - "k_EMsgFBSForceRefresh", - "k_EMsgFBSForceBounce", - "k_EMsgFBSDeployPackage", - "k_EMsgFBSDeployResponse", - "k_EMsgFBSUpdateBootstrapper", - "k_EMsgFBSSetState", - "k_EMsgFBSApplyOSUpdates", - "k_EMsgFBSRunCMDScript", - "k_EMsgFBSRebootBox", - "k_EMsgFBSSetBigBrotherMode", - "k_EMsgFBSMinidumpServer", - "k_EMsgFBSSetShellCount", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgFileXferRequest", - "k_EMsgFileXferResponse", - "k_EMsgFileXferData", - "k_EMsgFileXferEnd", - "k_EMsgFileXferDataAck", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgChannelAuthChallenge", - "k_EMsgChannelAuthResponse", - "k_EMsgChannelAuthResult", - "k_EMsgChannelEncryptRequest", - "k_EMsgChannelEncryptResponse", - "k_EMsgChannelEncryptResult", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseBS", - "k_EMsgBSPurchaseStart", - "k_EMsgBSPurchaseResponse", - "", - "k_EMsgBSSettleStart", - "", - "k_EMsgBSSettleComplete", - "k_EMsgBSBannedRequest", - "k_EMsgBSInitPayPalTxn", - "k_EMsgBSInitPayPalTxnResponse", - "k_EMsgBSGetPayPalUserInfo", - "k_EMsgBSGetPayPalUserInfoResponse", - "", - "k_EMsgBSRefundTxn", - "k_EMsgBSRefundTxnResponse", - "k_EMsgBSGetEvents", - "k_EMsgBSChaseRFRRequest", - "k_EMsgBSPaymentInstrBan", - "k_EMsgBSPaymentInstrBanResponse", - "k_EMsgBSProcessGCReports", - "k_EMsgBSProcessPPReports", - "k_EMsgBSInitGCPayPalTxn", - "k_EMsgBSInitGCPayPalTxnResponse", - "k_EMsgBSQueryGCPayPalTxn", - "k_EMsgBSQueryGCPayPalTxnResponse", - "k_EMsgBSCommitGCTxn", - "k_EMsgBSQueryGCOrderStatus", - "k_EMsgBSQueryGCOrderStatusResponse", - "k_EMsgBSQueryCBOrderStatus", - "k_EMsgBSQueryCBOrderStatusResponse", - "k_EMsgBSRunRedFlagReport", - "k_EMsgBSQueryPaymentInstUsage", - "k_EMsgBSQueryPaymentInstResponse", - "k_EMsgBSQueryTxnExtendedInfo", - "k_EMsgBSQueryTxnExtendedInfoResponse", - "k_EMsgBSUpdateConversionRates", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseATS", - "k_EMsgATSStartStressTest", - "k_EMsgATSStopStressTest", - "k_EMsgATSRunFailServerTest", - "k_EMsgATSUFSPerfTestTask", - "k_EMsgATSUFSPerfTestResponse", - "k_EMsgATSCycleTCM", - "k_EMsgATSInitDRMSStressTest", - "k_EMsgATSCallTest", - "k_EMsgATSCallTestReply", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseDP", - "k_EMsgDPSetPublishingState", - "k_EMsgDPGamePlayedStats", - "k_EMsgDPUniquePlayersStat", - "", - "k_EMsgDPVacInfractionStats", - "k_EMsgDPVacBanStats", - "k_EMsgDPCoplayStats", - "k_EMsgDPNatTraversalStats", - "k_EMsgDPSteamUsageEvent", - "k_EMsgDPVacCertBanStats", - "k_EMsgDPVacCafeBanStats", - "k_EMsgDPCloudStats", - "k_EMsgDPAchievementStats", - "k_EMsgDPAccountCreationStats", - "k_EMsgDPGetPlayerCount", - "k_EMsgDPGetPlayerCountResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseCM", - "k_EMsgCMSetAllowState", - "k_EMsgCMSpewAllowState", - "k_EMsgCMAppInfoResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseDSS", - "k_EMsgDSSNewFile", - "k_EMsgDSSCurrentFileList", - "k_EMsgDSSSynchList", - "k_EMsgDSSSynchListResponse", - "k_EMsgDSSSynchSubscribe", - "k_EMsgDSSSynchUnsubscribe", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseEPM", - "k_EMsgEPMStartProcess", - "k_EMsgEPMStopProcess", - "k_EMsgEPMRestartProcess", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgAMInternalAuthComplete", - "k_EMsgAMInternalRemoveAMSession", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgISCreateItem", - "k_EMsgISCreateItemResponse", - "k_EMsgISRefresh", - "k_EMsgISCreateSpecificItem", - "k_EMsgISAssignItemIDs", - "k_EMsgISAssignItemIDsResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgGCSendClient", - "k_EMsgAMRelayToGC", - "k_EMsgGCUpdatePlayedState", - "k_EMsgGCCmdRevive", - "k_EMsgGCCmdBounce", - "k_EMsgGCCmdForceBounce", - "k_EMsgGCCmdDown", - "k_EMsgGCCmdDeploy", - "k_EMsgGCCmdDeployResponse", - "k_EMsgGCCmdSwitch", - "k_EMsgAMRefreshSessions", - "k_EMsgGCUpdateGSState", - "k_EMsgGCAchievementAwarded", - "k_EMsgGCSystemMessage", - "k_EMsgGCValidateSession", - "k_EMsgGCValidateSessionResponse", - "k_EMsgGCCmdStatus", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseP2P", - "k_EMsgP2PTrackerMessage", - "k_EMsgP2PIntroducerMessage", - "k_EMsgP2PSeederUpload", - "k_EMsgP2PSeederUploadResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseSM", - "k_EMsgSMBuildUGSTables", - "k_EMsgSMExpensiveReport", - "k_EMsgSMHourlyReport", - "k_EMsgSMFishingReport", - "k_EMsgSMPartitionRenames", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgFailServer", - "k_EMsgJobHeartbeatTest", - "k_EMsgJobHeartbeatTestResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseFTSRange", - "k_EMsgFTSGetBrowseCounts", - "k_EMsgFTSGetBrowseCountsResponse", - "k_EMsgFTSBrowseClans", - "k_EMsgFTSBrowseClansResponse", - "k_EMsgFTSSearchClansByLocation", - "k_EMsgFTSSearchClansByLocationResponse", - "k_EMsgFTSSearchPlayersByLocation", - "k_EMsgFTSSearchPlayersByLocationResponse", - "k_EMsgFTSClanDeleted", - "k_EMsgFTSSearch", - "k_EMsgFTSSearchResponse", - "k_EMsgFTSSearchStatus", - "k_EMsgFTSSearchStatusResponse", - "k_EMsgFTSGetGSPlayStats", - "k_EMsgFTSGetGSPlayStatsResponse", - "k_EMsgFTSGetGSPlayStatsForServer", - "k_EMsgFTSGetGSPlayStatsForServerResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseCCSRange", - "k_EMsgCCSGetComments", - "k_EMsgCCSGetCommentsResponse", - "k_EMsgCCSAddComment", - "k_EMsgCCSAddCommentResponse", - "k_EMsgCCSDeleteComment", - "k_EMsgCCSDeleteCommentResponse", - "k_EMsgCCSPreloadComments", - "k_EMsgCCSNotifyCommentCount", - "k_EMsgCCSGetCommentsForNews", - "k_EMsgCCSGetCommentsForNewsResponse", - "k_EMsgCCSDeleteAllComments", - "k_EMsgCCSDeleteAllCommentsResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseLBSRange", - "k_EMsgLBSSetScore", - "k_EMsgLBSSetScoreResponse", - "k_EMsgLBSFindOrCreateLB", - "k_EMsgLBSFindOrCreateLBResponse", - "k_EMsgLBSGetLBEntries", - "k_EMsgLBSGetLBEntriesResponse", - "k_EMsgLBSGetLBList", - "k_EMsgLBSGetLBListResponse", - "k_EMsgLBSSetLBDetails", - "k_EMsgLBSDeleteLB", - "k_EMsgLBSDeleteLBEntry", - "k_EMsgLBSResetLB", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseOGS", - "k_EMsgOGSBeginSession", - "k_EMsgOGSBeginSessionResponse", - "k_EMsgOGSEndSession", - "k_EMsgOGSEndSessionResponse", - "k_EMsgOGSWriteRow", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseAMRange2", - "k_EMsgAMCreateChat", - "k_EMsgAMCreateChatResponse", - "k_EMsgAMUpdateChatMetadata", - "k_EMsgAMPublishChatMetadata", - "k_EMsgAMSetProfileURL", - "k_EMsgAMGetAccountEmailAddress", - "k_EMsgAMGetAccountEmailAddressResponse", - "k_EMsgAMRequestFriendData", - "k_EMsgAMRouteToClients", - "k_EMsgAMLeaveClan", - "k_EMsgAMClanPermissions", - "k_EMsgAMClanPermissionsResponse", - "k_EMsgAMCreateClanEvent", - "k_EMsgAMCreateClanEventResponse", - "k_EMsgAMUpdateClanEvent", - "k_EMsgAMUpdateClanEventResponse", - "k_EMsgAMGetClanEvents", - "k_EMsgAMGetClanEventsResponse", - "k_EMsgAMDeleteClanEvent", - "k_EMsgAMDeleteClanEventResponse", - "k_EMsgAMSetClanPermissionSettings", - "k_EMsgAMSetClanPermissionSettingsResponse", - "k_EMsgAMGetClanPermissionSettings", - "k_EMsgAMGetClanPermissionSettingsResponse", - "k_EMsgAMPublishChatRoomInfo", - "k_EMsgClientChatRoomInfo", - "k_EMsgAMCreateClanAnnouncement", - "k_EMsgAMCreateClanAnnouncementResponse", - "k_EMsgAMUpdateClanAnnouncement", - "k_EMsgAMUpdateClanAnnouncementResponse", - "k_EMsgAMGetClanAnnouncementsCount", - "k_EMsgAMGetClanAnnouncementsCountResponse", - "k_EMsgAMGetClanAnnouncements", - "k_EMsgAMGetClanAnnouncementsResponse", - "k_EMsgAMDeleteClanAnnouncement", - "k_EMsgAMDeleteClanAnnouncementResponse", - "k_EMsgAMGetSingleClanAnnouncement", - "k_EMsgAMGetSingleClanAnnouncementResponse", - "k_EMsgAMGetClanHistory", - "k_EMsgAMGetClanHistoryResponse", - "k_EMsgAMGetClanPermissionBits", - "k_EMsgAMGetClanPermissionBitsResponse", - "k_EMsgAMSetClanPermissionBits", - "k_EMsgAMSetClanPermissionBitsResponse", - "k_EMsgAMSessionInfoRequest", - "k_EMsgAMSessionInfoResponse", - "k_EMsgAMValidateWGToken", - "k_EMsgAMGetSingleClanEvent", - "k_EMsgAMGetSingleClanEventResponse", - "k_EMsgAMGetClanRank", - "k_EMsgAMGetClanRankResponse", - "k_EMsgAMSetClanRank", - "k_EMsgAMSetClanRankResponse", - "k_EMsgAMGetClanPOTW", - "k_EMsgAMGetClanPOTWResponse", - "k_EMsgAMSetClanPOTW", - "k_EMsgAMSetClanPOTWResponse", - "k_EMsgAMRequestChatMetadata", - "k_EMsgAMDumpUser", - "k_EMsgAMKickUserFromClan", - "k_EMsgAMAddFounderToClan", - "k_EMsgAMValidateWGTokenResponse", - "k_EMsgAMSetCommunityState", - "k_EMsgAMSetAccountDetails", - "k_EMsgAMGetChatBanList", - "k_EMsgAMGetChatBanListResponse", - "k_EMsgAMUnBanFromChat", - "k_EMsgAMSetClanDetails", - "k_EMsgAMGetAccountLinks", - "k_EMsgAMGetAccountLinksResponse", - "k_EMsgAMSetAccountLinks", - "k_EMsgAMSetAccountLinksResponse", - "k_EMsgAMGetUserGameStats", - "k_EMsgAMGetUserGameStatsResponse", - "k_EMsgAMCheckClanMembership", - "k_EMsgAMGetClanMembers", - "k_EMsgAMGetClanMembersResponse", - "k_EMsgAMJoinPublicClan", - "k_EMsgAMNotifyChatOfClanChange", - "k_EMsgAMResubmitPurchase", - "k_EMsgAMAddFriend", - "k_EMsgAMAddFriendResponse", - "k_EMsgAMRemoveFriend", - "k_EMsgAMGetVIPStatus", - "k_EMsgAMVIPStatusResponse", - "k_EMsgAMCancelEasyCollect", - "k_EMsgAMCancelEasyCollectResponse", - "k_EMsgAMGetClanMembershipList", - "k_EMsgAMGetClanMembershipListResponse", - "k_EMsgAMClansInCommon", - "k_EMsgAMClansInCommonResponse", - "k_EMsgAMIsValidAccountID", - "k_EMsgAMConvertClan", - "k_EMsgAMGetGiftTargetListRelay", - "k_EMsgAMWipeFriendsList", - "k_EMsgAMSetIgnored", - "k_EMsgAMClansInCommonCountResponse", - "k_EMsgAMFriendsList", - "k_EMsgAMFriendsListResponse", - "k_EMsgAMFriendsInCommon", - "k_EMsgAMFriendsInCommonResponse", - "k_EMsgAMFriendsInCommonCountResponse", - "k_EMsgAMClansInCommonCount", - "k_EMsgAMChallengeVerdict", - "k_EMsgAMChallengeNotification", - "k_EMsgAMFindGSByIP", - "k_EMsgAMFoundGSByIP", - "k_EMsgAMGiftRevoked", - "k_EMsgAMCreateAccountRecord", - "k_EMsgAMUserClanList", - "k_EMsgAMUserClanListResponse", - "k_EMsgAMGetAccountDetails2", - "k_EMsgAMGetAccountDetailsResponse2", - "k_EMsgAMSetCommunityProfileSettings", - "k_EMsgAMSetCommunityProfileSettingsResponse", - "k_EMsgAMGetCommunityPrivacyState", - "k_EMsgAMGetCommunityPrivacyStateResponse", - "k_EMsgAMCheckClanInviteRateLimiting", - "k_EMsgAMGetUserAchievementStatus", - "k_EMsgAMGetIgnored", - "k_EMsgAMGetIgnoredResponse", - "k_EMsgAMSetIgnoredResponse", - "k_EMsgAMSetFriendRelationshipNone", - "k_EMsgAMGetFriendRelationship", - "k_EMsgAMGetFriendRelationshipResponse", - "k_EMsgAMServiceModulesCache", - "k_EMsgAMServiceModulesCall", - "k_EMsgAMServiceModulesCallResponse", - "k_EMsgAMGetCaptchaDataForIP", - "k_EMsgAMGetCaptchaDataForIPResponse", - "k_EMsgAMValidateCaptchaDataForIP", - "k_EMsgAMValidateCaptchaDataForIPResponse", - "k_EMsgAMTrackFailedAuthByIP", - "k_EMsgAMGetCaptchaDataByGID", - "k_EMsgAMGetCaptchaDataByGIDResponse", - "k_EMsgAMGetLobbyList", - "k_EMsgAMGetLobbyListResponse", - "k_EMsgAMGetLobbyMetadata", - "k_EMsgAMGetLobbyMetadataResponse", - "k_EMsgAMAddFriendNews", - "k_EMsgAMAddClanNews", - "k_EMsgAMWriteNews", - "k_EMsgAMFindClanUser", - "k_EMsgAMFindClanUserResponse", - "k_EMsgAMBanFromChat", - "k_EMsgAMGetUserHistoryResponse", - "k_EMsgAMGetUserNewsSubscriptions", - "k_EMsgAMGetUserNewsSubscriptionsResponse", - "k_EMsgAMSetUserNewsSubscriptions", - "k_EMsgAMGetUserNews", - "k_EMsgAMGetUserNewsResponse", - "k_EMsgAMSendQueuedEmails", - "k_EMsgAMSetLicenseFlags", - "k_EMsgAMGetUserHistory", - "k_EMsgAMDeleteUserNews", - "k_EMsgAMAllowUserFilesRequest", - "k_EMsgAMAllowUserFilesResponse", - "k_EMsgAMGetAccountStatus", - "k_EMsgAMGetAccountStatusResponse", - "k_EMsgAMEditBanReason", - "", - "k_EMsgAMProbeClanMembershipList", - "k_EMsgAMProbeClanMembershipListResponse", - "k_EMsgAMRouteClientMsgToAM", - "k_EMsgAMGetFriendsLobbies", - "k_EMsgAMGetFriendsLobbiesResponse", - "k_EMsgAMLoadItems", - "k_EMsgAMLoadItemsResponse", - "k_EMsgAMCacheNewItem", - "k_EMsgAMRelayItemUpdateGS", - "k_EMsgAMRelayItemDeletedGS", - "k_EMsgAMGetUserFriendNewsResponse", - "k_EMsgAMGetUserFriendNews", - "k_EMsgAMGetUserClansNewsResponse", - "k_EMsgAMGetUserClansNews", - "k_EMsgAMStoreInitPurchase", - "k_EMsgAMStoreInitPurchaseResponse", - "k_EMsgAMStoreGetFinalPrice", - "k_EMsgAMStoreGetFinalPriceResponse", - "k_EMsgAMStoreCompletePurchase", - "k_EMsgAMStoreCancelPurchase", - "k_EMsgAMStorePurchaseResponse", - "k_EMsgAMCreateAccountRecordInSteam3", - "k_EMsgAMGetPreviousCBAccount", - "k_EMsgAMGetPreviousCBAccountResponse", - "k_EMsgAMUpdateBillingAddress", - "k_EMsgAMUpdateBillingAddressResponse", - "k_EMsgAMGetBillingAddress", - "k_EMsgAMGetBillingAddressResponse", - "k_EMsgAMGetUserLicenseHistory", - "k_EMsgAMGetUserLicenseHistoryResponse", - "k_EMsgAMGetUserTransactionHistory", - "k_EMsgAMGetUserTransactionHistoryResponse", - "k_EMsgAMSupportChangePassword", - "k_EMsgAMSupportChangeEmail", - "k_EMsgAMSupportChangeSecretQA", - "k_EMsgAMResetUserVerificationGSByIP", - "k_EMsgAMUpdateGSPlayStats", - "k_EMsgAMSupportEnableOrDisable", - "k_EMsgAMGetComments", - "k_EMsgAMGetCommentsResponse", - "k_EMsgAMAddComment", - "k_EMsgAMAddCommentResponse", - "k_EMsgAMDeleteComment", - "k_EMsgAMDeleteCommentResponse", - "k_EMsgAMGetPurchaseStatus", - "k_EMsgAMChatDetailsQuery", - "k_EMsgAMChatDetailsResponse", - "k_EMsgAMSupportIsAccountEnabled", - "k_EMsgAMSupportIsAccountEnabledResponse", - "k_EMsgAMGetUserStats", - "k_EMsgAMSupportKickSession", - "k_EMsgAMGSSearch", - "k_EMsgAMAwardItem", - "k_EMsgAMRelayItemAwardedGS", - "k_EMsgMarketingMessageUpdate", - "k_EMsgAMRelayItemQuantityUpdated", - "k_EMsgAMRelayItemQuantityUpdatedResponse", - "k_EMsgAMRouteFriendMsg", - "k_EMsgAMTicketAuthRequestOrResponse", - "k_EMsgAMFlushItemCaches", - "k_EMsgAMVerifyDepotManagementRights", - "k_EMsgAMVerifyDepotManagementRightsResponse", - "k_EMsgAMAddFreeLicense", - "k_EMsgAMGetUserFriendsMinutesPlayed", - "k_EMsgAMGetUserFriendsMinutesPlayedResponse", - "k_EMsgAMGetUserMinutesPlayed", - "k_EMsgAMGetUserMinutesPlayedResponse", - "k_EMsgAMReloadAccountItemSection", - "k_EMsgAMRelayCurrentCoplayCount", - "k_EMsgAMValidateEmailLink", - "k_EMsgAMValidateEmailLinkResponse", - "k_EMsgAMReportDroppedItemGS", - "k_EMsgAMAddUsersToMarketingTreatment", - "k_EMsgAMAddItemListToUser", - "k_EMsgAMStoreUserStats", - "k_EMsgAMGetUserGameplayInfo", - "k_EMsgAMGetUserGameplayInfoResponse", - "k_EMsgAMGetCardList", - "k_EMsgAMGetCardListResponse", - "k_EMsgAMDeleteStoredCard", - "k_EMsgAMRevokeLegacyGameKeys", - "k_EMsgAMCommitPurchasedItem", - "k_EMsgAMGetWalletDetails", - "k_EMsgAMGetWalletDetailsResponse", - "k_EMsgAMDeleteStoredPaymentInfo", - "k_EMsgAMGetStoredPaymentSummary", - "k_EMsgAMGetStoredPaymentSummaryResponse", - "k_EMsgAMGetWalletConversionRate", - "k_EMsgAMGetWalletConversionRateResponse", - "k_EMsgAMConvertWallet", - "k_EMsgAMConvertWalletResponse", - "k_EMsgAMRelayGetFriendsWhoPlayGame", - "k_EMsgAMRelayGetFriendsWhoPlayGameResponse", - "k_EMsgAMSetPreApproval", - "k_EMsgAMSetPreApprovalResponse", - "k_EMsgAMMarketingTreatmentUpdate", - "k_EMsgAMCreateRefund", - "k_EMsgAMCreateRefundResponse", - "k_EMsgAMCreateChargeback", - "k_EMsgAMCreateChargebackResponse", - "k_EMsgAMCreateDispute", - "k_EMsgAMCreateDisputeResponse", - "k_EMsgAMClearDispute", - "k_EMsgAMClearDisputeResponse", - "k_EMsgCAMQueryPersonaStateCache", - "k_EMsgCAMQueryPersonaStateCacheResponse", - "k_EMsgAMSetDRMTestConfig", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBasePSRange", - "k_EMsgPSCreateShoppingCart", - "k_EMsgPSCreateShoppingCartResponse", - "k_EMsgPSIsValidShoppingCart", - "k_EMsgPSIsValidShoppingCartResponse", - "k_EMsgPSAddPackageToShoppingCart", - "k_EMsgPSAddPackageToShoppingCartResponse", - "k_EMsgPSRemoveLineItemFromShoppingCart", - "k_EMsgPSRemoveLineItemFromShoppingCartResponse", - "k_EMsgPSGetShoppingCartContents", - "k_EMsgPSGetShoppingCartContentsResponse", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseUFSRange", - "", - "k_EMsgClientUFSUploadFileRequest", - "k_EMsgClientUFSUploadFileResponse", - "k_EMsgClientUFSUploadFileChunk", - "k_EMsgClientUFSUploadFileFinished", - "k_EMsgClientUFSGetFileListForApp", - "k_EMsgClientUFSGetFileListForAppResponse", - "k_EMsgRouteClientMsgToUFS", - "k_EMsgRouteUFSMsgToClient", - "k_EMsgClientUFSDownloadRequest", - "k_EMsgClientUFSDownloadResponse", - "k_EMsgClientUFSDownloadChunk", - "k_EMsgClientUFSLoginRequest", - "k_EMsgClientUFSLoginResponse", - "k_EMsgUFSReloadPartitionInfo", - "k_EMsgClientUFSTransferHeartbeat", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseClient2", - "k_EMsgClientRequestForgottenPasswordEmail", - "k_EMsgClientRequestForgottenPasswordEmailResponse", - "k_EMsgClientCreateAccountResponse", - "k_EMsgClientResetForgottenPassword", - "k_EMsgClientResetForgottenPasswordResponse", - "k_EMsgClientCreateAccount2", - "k_EMsgClientInformOfResetForgottenPassword", - "k_EMsgClientInformOfResetForgottenPasswordResponse", - "k_EMsgClientAnonUserLogOn", - "k_EMsgClientGamesPlayedWithDataBlob", - "k_EMsgClientUpdateUserGameInfo", - "k_EMsgClientFileToDownload", - "k_EMsgClientFileToDownloadResponse", - "k_EMsgClientLBSSetScore", - "k_EMsgClientLBSSetScoreResponse", - "k_EMsgClientLBSFindOrCreateLB", - "k_EMsgClientLBSFindOrCreateLBResponse", - "k_EMsgClientLBSGetLBEntries", - "k_EMsgClientLBSGetLBEntriesResponse", - "k_EMsgClientMarketingMessageUpdate", - "k_EMsgClientGetItemBlob", - "k_EMsgClientGetItemBlobResponse", - "k_EMsgClientSetItemBlob", - "k_EMsgClientSetItemBlobResponse", - "k_EMsgClientItemQuantityUpdated", - "k_EMsgClientChatDeclined", - "k_EMsgClientFriendMsgIncoming", - "k_EMsgClientAuthList", - "k_EMsgClientTicketAuthComplete", - "k_EMsgClientIsLimitedAccount", - "k_EMsgClientRequestAuthList", - "k_EMsgClientAuthList2", - "k_EMsgClientStat", - "k_EMsgClientP2PConnectionInfo", - "k_EMsgClientP2PConnectionFailInfo", - "k_EMsgClientGetNumberOfCurrentPlayers", - "k_EMsgClientGetNumberOfCurrentPlayersResponse", - "k_EMsgClientGetDepotDecryptionKey", - "k_EMsgClientGetDepotDecryptionKeyResponse", - "k_EMsgGSPerformHardwareSurvey", - "k_EMsgClientCheckForUpdatedDepotManifest", - "k_EMsgClientCheckForUpdatedDepotManifestResponse", - "k_EMsgClientEnableTestLicense", - "k_EMsgClientEnableTestLicenseResponse", - "k_EMsgClientDisableTestLicense", - "k_EMsgClientDisableTestLicenseResponse", - "", - "k_EMsgClientRequestValidationMail", - "k_EMsgClientRequestValidationMailResponse", - "k_EMsgClientDropItem", - "k_EMsgClientDropItemResponse", - "k_EMsgClientToGC", - "k_EMsgClientFromGC", - "k_EMsgClientRequestChangeMail", - "k_EMsgClientRequestChangeMailResponse", - "k_EMsgClientEmailAddrInfo", - "k_EMsgClientPasswordChange3", - "k_EMsgClientEmailChange3", - "k_EMsgClientPersonalQAChange3", - "k_EMsgClientResetForgottenPassword3", - "k_EMsgClientRequestForgottenPasswordEmail3", - "k_EMsgClientCreateAccount3", - "k_EMsgClientNewLoginKey", - "k_EMsgClientNewLoginKeyAccepted", - "k_EMsgClientLogOnWithHash", - "k_EMsgClientStoreUserStats2", - "k_EMsgClientStatsUpdated", - "k_EMsgClientActivateOEMLicense", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgClientRequestedClientStats", - "k_EMsgClientStat2Int32", - "k_EMsgClientStat2", - "k_EMsgClientVerifyPassword", - "k_EMsgClientVerifyPasswordResponse", - "k_EMsgClientDRMDownloadRequest", - "k_EMsgClientDRMDownloadResponse", - "k_EMsgClientDRMFinalResult", - "k_EMsgClientGetFriendsWhoPlayGame", - "k_EMsgClientGetFriendsWhoPlayGameResponse", - "k_EMsgClientOGSBeginSession", - "k_EMsgClientOGSBeginSessionResponse", - "k_EMsgClientOGSEndSession", - "k_EMsgClientOGSEndSessionResponse", - "k_EMsgClientOGSWriteRow", - "k_EMsgClientDRMTest", - "k_EMsgClientDRMTestResult", - "", - "", - "", - "k_EMsgClientServerUnavailable", - "k_EMsgClientServersAvailable", - "k_EMsgClientRegisterAuthTicketWithCM", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseDFS", - "k_EMsgDFSGetFile", - "k_EMsgDFSInstallLocalFile", - "k_EMsgDFSConnection", - "k_EMsgDFSConnectionReply", - "k_EMsgClientDFSAuthenticateRequest", - "k_EMsgClientDFSAuthenticateResponse", - "k_EMsgClientDFSEndSession", - "k_EMsgDFSPurgeFile", - "k_EMsgDFSRouteFile", - "k_EMsgDFSGetFileFromServer", - "k_EMsgDFSAcceptedResponse", - "k_EMsgDFSRequestPingback", - "k_EMsgDFSRecvTransmitFile", - "k_EMsgDFSSendTransmitFile", - "k_EMsgDFSRequestPingback2", - "k_EMsgDFSResponsePingback2", - "k_EMsgClientDFSDownloadStatus", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgBaseMDS", - "k_EMsgClientMDSLoginRequest", - "k_EMsgClientMDSLoginResponse", - "k_EMsgClientMDSUploadManifestRequest", - "k_EMsgClientMDSUploadManifestResponse", - "k_EMsgClientMDSTransmitManifestDataChunk", - "k_EMsgClientMDSHeartbeat", - "k_EMsgClientMDSUploadDepotChunks", - "k_EMsgClientMDSUploadDepotChunksResponse", - "k_EMsgClientMDSInitDepotBuildRequest", - "k_EMsgClientMDSInitDepotBuildResponse", - "k_EMsgClientMDSChunkListResponse", - "k_EMsgAMToMDSGetDepotDecryptionKey", - "k_EMsgMDSToAMGetDepotDecryptionKeyResponse", - "k_EMsgMDSGetVersionsForDepot", - "k_EMsgMDSGetVersionsForDepotResponse", - "k_EMsgMDSSetPublicVersionForDepot", - "k_EMsgMDSSetPublicVersionForDepotResponse", - "k_EMsgClientMDSGetDepotManifest", - "k_EMsgClientMDSGetDepotManifestResponse", - "k_EMsgClientMDSGetDepotManifestChunk", - "k_EMsgAMToMDSCheckForUpdatedDepotManifest", - "k_EMsgMDSToAMCheckForUpdatedDepotManifestResponse", - "k_EMsgClientMDSDownloadDepotChunksRequest", - "k_EMsgClientMDSDownloadDepotChunksAsync", - "k_EMsgClientMDSDownloadDepotChunksAck", - "k_EMsgMDSContentServerStatsBroadcast", - "k_EMsgMDSContentServerConfigRequest", - "k_EMsgMDSContentServerConfig", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "k_EMsgCSBase", - "k_EMsgClientCSLoginRequest", - "k_EMsgClientCSLoginResponse", - "k_EMsgClientCSGetDepotManifest", - "k_EMsgClientCSGetDepotManifestResponse", -}; - -/* -const char *PchNameFromEMsg( EMsg eMsg ) -{ - if ( eMsg <= k_EMsgInvalid || eMsg > k_EMsgClientCSGetDepotManifestResponse ) - return k_szEMsg[ 0 ]; - - return k_szEMsg[ (int)eMsg ]; -} -*/ - -const char *k_szEResult[] = -{ - "Invalid EResult", - "k_EResultOK", - "k_EResultFail", - "k_EResultNoConnection", - "k_EResultNoConnectionRetry", - "k_EResultInvalidPassword", - "k_EResultLoggedInElsewhere", - "k_EResultInvalidProtocolVer", - "k_EResultInvalidParam", - "k_EResultFileNotFound", - "k_EResultBusy", - "k_EResultInvalidState", - "k_EResultInvalidName", - "k_EResultInvalidEmail", - "k_EResultDuplicateName", - "k_EResultAccessDenied", - "k_EResultTimeout", - "k_EResultBanned", - "k_EResultAccountNotFound", - "k_EResultInvalidSteamID", - "k_EResultServiceUnavailable", - "k_EResultNotLoggedOn", - "k_EResultPending", - "k_EResultEncryptionFailure", - "k_EResultInsufficientPrivilege", - "k_EResultLimitExceeded", - "k_EResultRevoked", - "k_EResultExpired", - "k_EResultAlreadyRedeemed", - "k_EResultDuplicateRequest", - "k_EResultAlreadyOwned", - "k_EResultIPNotFound", - "k_EResultPersistFailed", - "k_EResultLockingFailed", - "k_EResultLogonSessionReplaced", - "k_EResultConnectFailed", - "k_EResultHandshakeFailed", - "k_EResultIOFailure", - "k_EResultRemoteDisconnect", - "k_EResultShoppingCartNotFound", - "k_EResultBlocked", - "k_EResultIgnored", - "k_EResultNoMatch", - "k_EResultAccountDisabled", - "k_EResultServiceReadOnly", - "k_EResultAccountNotFeatured", - "k_EResultAdministratorOK", - "k_EResultContentVersion", - "k_EResultTryAnotherCM", - "k_EResultPasswordRequiredToKickSession", - "k_EResultAlreadyLoggedInElsewhere", - "k_EResultSuspended", - "k_EResultCancelled", - "k_EResultDataCorruption", - "k_EResultDiskFull", - "k_EResultRemoteCallFailed", -}; - -const char *PchNameFromEResult( EResult eResult ) -{ - if ( eResult <= 0 || eResult >= 55 ) - return k_szEResult[ 0 ]; - - return k_szEResult[ (int)eResult ]; -} - -const char *k_szEAccountType[] = -{ - "k_EAccountTypeInvalid", - "k_EAccountTypeIndividual", - "k_EAccountTypeMultiseat", - "k_EAccountTypeGameServer", - "k_EAccountTypeAnonGameServer", - "k_EAccountTypePending", - "k_EAccountTypeContentServer", - "k_EAccountTypeClan", - "k_EAccountTypeChat", - "k_EAccountTypeP2PSuperSeeder", - "k_EAccountTypeAnonUser", -}; - -const char *PchNameFromEAccountType( EAccountType eAccountType ) -{ - if ( eAccountType <= 0 || eAccountType >= k_EAccountTypeMax ) - return k_szEAccountType[ 0 ]; - - return k_szEAccountType[ (int)eAccountType ]; -} - -const char *PchStringFromSockAddr( const sockaddr_in *sockAddr ) -{ - static char szSockAddr[ 22 ]; - memset( szSockAddr, 0, sizeof( szSockAddr ) ); - - if ( !sockAddr ) - return NULL; - - sprintf_s( szSockAddr, sizeof( szSockAddr ), "%s:%hu", inet_ntoa( sockAddr->sin_addr ), ntohs( sockAddr->sin_port ) ); - - return szSockAddr; -} \ No newline at end of file diff --git a/Resources/NetHook/utils.h b/Resources/NetHook/utils.h deleted file mode 100644 index e6e10332..00000000 --- a/Resources/NetHook/utils.h +++ /dev/null @@ -1,36 +0,0 @@ - -#ifndef UTILS_H_ -#define UTILS_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#include "steam/steamtypes.h" -#include "steam/csteamid.h" -#include "steam/udppkt.h" - -#include - - - -const char *PchStringFromUDPPktHdr( const UDPPktHdr_t *pHdr ); -const char *PchStringFromMsgHdr( const MsgHdr_t *pMsgHdr ); -const char *PchStringFromExtendedClientMsgHdr( const ExtendedClientMsgHdr_t *pMsgHdr ); - - -const char *PchStringFromData( const uint8 *pData, uint32 cubData ); - -const char *PchNameFromEMsg( EMsg eMsg ); -const char *PchNameFromNetFlags( uint32 netFlags ); -const char *PchNameFromEUDPPktType( EUDPPktType eUdpPktType ); - -const char *PchNameFromEUniverse( EUniverse eUniverse ); -const char *PchNameFromEResult( EResult eResult ); -const char *PchNameFromEAccountType( EAccountType eAccountType ); - -const char *PchStringFromSockAddr( const sockaddr_in *sockAddr ); - - -#endif // !UTILS_H_ - diff --git a/Resources/NetHook/zdll.lib b/Resources/NetHook/zdll.lib deleted file mode 100644 index d6ff1bf40f0aca1f3b36c214162b5a86201115a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38996 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 +fileHeader->m_ExtraFieldLength; - uint32 dataSize = fileHeader->m_CompressedSize; - - return CZip::InternalInflate( pCompressed + offsetStart, dataSize, pDecompressed, cubDecompressed ); -} - -bool CZip::InternalInflate( const uint8 *pCompressed, uint32 cubCompressed, uint8 *pDecompressed, uint32 cubDecompressed ) -{ - z_stream zstrm; - - zstrm.zalloc = Z_NULL; - zstrm.zfree = Z_NULL; - zstrm.opaque = Z_NULL; - zstrm.avail_in = 0; - zstrm.next_in = Z_NULL; - - int ret = inflateInit2( &zstrm, -15 ); - - if ( ret != Z_OK ) - return false; - - zstrm.avail_in = cubCompressed; - zstrm.next_in = (Bytef *)pCompressed; - - zstrm.avail_out = cubDecompressed; - zstrm.next_out = pDecompressed; - - ret = inflate( &zstrm, Z_NO_FLUSH ); - - inflateEnd( &zstrm ); - - if ( ret != Z_STREAM_END ) - return false; - - return true; -} diff --git a/Resources/NetHook/zip.h b/Resources/NetHook/zip.h deleted file mode 100644 index 2f050fb0..00000000 --- a/Resources/NetHook/zip.h +++ /dev/null @@ -1,25 +0,0 @@ - -#ifndef ZIP_H_ -#define ZIP_H_ -#ifdef _WIN32 -#pragma once -#endif - - -#include "steam/steamtypes.h" - - -class CZip -{ - -public: - static bool Inflate( const uint8 *pCompressed, uint32 cubCompressed, uint8 *pDecompressed, uint32 cubDecompressed ); - -private: - static bool InternalInflate( const uint8 *pCompressed, uint32 cubCompressed, uint8 *pDecompressed, uint32 cubDecompressed ); - -}; - - -#endif // !ZIP_H_ - diff --git a/Resources/NetHook/zlib.def b/Resources/NetHook/zlib.def deleted file mode 100644 index 03df8bf8..00000000 --- a/Resources/NetHook/zlib.def +++ /dev/null @@ -1,74 +0,0 @@ -LIBRARY -; zlib data compression library - -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress - gzopen - gzdopen - gzbuffer - gzsetparams - gzread - gzwrite - gzprintf - gzputs - gzgets - gzputc - gzgetc - gzungetc - gzflush - gzseek - gzrewind - gztell - gzoffset - gzeof - gzdirect - gzclose - gzclose_r - gzclose_w - gzerror - gzclearerr -; checksum functions - adler32 - crc32 - adler32_combine - crc32_combine -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine diff --git a/Resources/NetHook/zlib.lib b/Resources/NetHook/zlib.lib deleted file mode 100644 index 7229b87f95717a68923ae04dbd429b2c71263d3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247310 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 z zUEan;v^Qaw&vB9G6JeJFxQGTn?838n(KFjzcxobc@%B3&4p)z zN_2JMFb#;yB2vh6G`*`n9447K&^Fo5;@OiDomMyuPkoeVN5d{WS5czh47>0|M9C9{ zunW&XOZY6b{7SU;VHfo9qNB38ph1_X zn>H78;!2(wgwIOmj67V!F6fixS*gth&9G>FZ7zK|x-jBS(Yh+pT7~18h>Pg$!Y*hq z)juPywFDQQ7umwxgo|ji!)Kuv6rHHeMV>y2<|rIS?pvM_gk8SDMV``xUC@Uq(T9ay z(0nO*LKAjD2c_g0N7x1Jl03n-xn$##5OR^aDob>pj@iPDB8=$F!tqST<-$-HIg4qi z68%;<%yhztCf9JefulpFogo!Pq}m~3{;b#h)|rP}*hZXTEl{kJnw;g@*1xuyzse^i z`W2Spm7b+GV$CRTV2soi>4m@isN7HxR);%?KuVzY2J(hWNNRFDP zhn8Lu>6MGvZze+5ak!hb-9)siLNb_)Hq&C&jeNT%;*h-M`u1`%lN44ogtH^8U5HdE zSe3;nnW!aqD3@#+14=TiCa}&nbpsqWr4ZmA>{@_O`9&=KxqbP8MObsey@eOb_Kc1w z1+z^U$&ak}oD;Q1k4&z4cj1dzS#PN7^b*`wj<(hp$`@O4+E&;RjoesP=NCmUoUOEw za=lt^I`8zAoHMu%wFLdqAfz4R&Ug+7=@{!-&v{je$?u7{~Y;zd-#dIo_ zHx=?*M$^ce<1Kpb2*Z2i?6W-ai$k~Xpnq&`PUPrVm0NyKQyck`1{Ra*q^QZBJE@C1 zI-Jb?yBtM07SHPZqX;MK)(ej!oLqP8QG}EDDvlzYj2xar!X+JYzY?GKkZ_0Qi|8+W zM-fietxE}~e*%Lnx&gN$zNmL=Fu199+;n@nag3xlHA&vB5&6!H^|*H+%pNlwL$Y!w z9a_E;-RS{n9Xtm zCKR7h9wQ7_V-46=6jC-L?TseiIVX2O|B?A4coB1-_65U7WnVO+eWc^C{G6fv3v!3I z=gFYnjx1YyPzN0Kug62Z4(s;5$tqRSDH$ct<1B`M+ATjFAEsZzG1K^woPIAj53yp8 z{@3FrmA~%C<0ZzA$4jP^s*VGykK!F3p<7GsSd!W?r-bJS{q8&?9PKvpF^1wnhqS*siXB@lt zvB&o9HB>=KF}Ggu!^55(c`qGvMV~D*`yTT!+fH=&3$7mj$NuA&97wKPJj6B^V`oEc%bKpbhT`+ z!~Ln}8W)^0ZNdI!QzRO77>b+)%c zOf9i$8SmraRnwC?O_ms}ck@(9EokE1JXS6I4Hqk=O&S;bb;+%iA7a=2lH?xUorRM1 zvw6TAy!^M^!BoCqP;TDAuginF8FgdjiweIj5>F}V_$@b5QtSE6cT!yWn^M4nrkGc; z�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νISx&bIeN$ZjbKoU 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 diff --git a/Resources/NetHook/zlib/zconf.h b/Resources/NetHook/zlib/zconf.h deleted file mode 100644 index 02ce56c4..00000000 --- a/Resources/NetHook/zlib/zconf.h +++ /dev/null @@ -1,428 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# define uncompress z_uncompress -# define zError z_zError -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# define gzFile z_gzFile -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef STDC -# include /* for off_t */ -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define z_off64_t off64_t -#else -# define z_off64_t z_off_t -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/Resources/NetHook/zlib/zlib.h b/Resources/NetHook/zlib/zlib.h deleted file mode 100644 index bfbba83e..00000000 --- a/Resources/NetHook/zlib/zlib.h +++ /dev/null @@ -1,1613 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 - - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef voidp gzFile; /* opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/Resources/NetHook/zlib1.dll b/Resources/NetHook/zlib1.dll deleted file mode 100644 index 869b00d4a574faa6b7fe68967657bdacc1ed838a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100352 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

{M7n# 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\mAtct?*^zltmvlU1tR>x1 zmvsAW1@n%slJ3M>J0Mq8Qd8>!skM_X>9ky7vyfOzO1quxXGtc{eNu}tT*CR=344S@ z))!4}ja`_BKQdCiyaSEm6`{7Su)jDj(vb+a#zJkurf5ez5$Z_zgSC120lz;HEAYn? z&3=Dju(qTpe17`yDhGQN$b<7j9m`=%Fc6C*mbHfyk)~iG7K$X|utr)@nHpD?9;`Gy zSb2J|iu7Q!(}Pu}2dhdCHYYvU-1K0E8lj(-q+L9%8z^Y_v z@#T@ul}uU{jW5+DT{tCJ(Vl2&3$@1m1%-Zeovw~ZVrf?k@$`i3>>=Zp$f|I28l=d&r7apt$I7MAXj`bQb6F@2+F(PXITB3+7;4_XE1qbH zgxk`wmfBjnST0t&;MQogd1=Jc3vhIT0*dHI;b==*xRy|)EiK^EP`;3DvSQ~AMh11I!*jTu; zE!5;0tsKNlBONlh_fVdt;a0EmG=#&;np3U0Mw7e|b66$J8G)5Dl zwvz5dI9?rTM`J8SZ8cYQbao{g5^zYnA3drw7EMGckfX)6wuSxve3}@!85V|O9g&XK z#$~ZEf;2i;@5$zcQN(y8+RhHxU8pK3$xDHQ9eZ6s5z4>c{v1SEO3DYeT`%#P-8 zM^kqn32MarrxCNSJ~EVJ_LYHp1KL)ksn40ON`yP8FZ9v)y3PcY<9*a_z@#)`)ioOn z*IKY#nTHdp)^M^WP~Op;If=6gI!sBHH)ot8_hfpyWPQ-B4adJQ}=->~M*ZhT(>C}NqE2`@PjalZbs%@M) zCCi-i*9Iv#Cl_Yf(2A->MR$(p>bYS?d&X*&Yo8{zdp;HHRTNr zf!W#aP9=*Q%Nw$6DK-79SABWy{F*G=*|2sRsi4hzk7`&OUM143T8d~Ltf{KaVofn) zU{RJC1M}tu7B^Jwopyhs(}U_jNqKd!uD-FVt~QWqAgT^64Y$dWO%Ts3-)nx=yz;UP zi|R#OUmj@8E-_i3g_^b*D>yT*Yd2?~YJ0hJhUqmwNj6;+CsfucS8uer1btO@&NF+H zG3jPfY@Q`IhaG1(wo~t9^FQnI!2-G{)YtNROj>*60%!4Q{_U8QCaZLp*}c&9u(}u8 zUPiMuX!LUMOeN}m>Jh$i*4O?W+ zuQTCL^XUvYtRV%Hx#UcudnMpadvokriGonrHheQf4_V=IKrGxu*FAchU->HRF2FvC z4qWQ033bj5J1!{nY;g~*H68PNprAQe4-QC!fu~@Z(a1QN8Ht!m^uR%rsCvgm29GiZ z70zR3z-_Q9?zv#!7b@qx&VwVV6}VDG8zsUqt^{iv?FCDHG>+?hE5cPBiA-o}!>yq# z(3C~HmbQg6F+^PB%!Hvav~*#lIkC*&7+oIjzyvau{E~EWK6W+)v8^fEBz9-*6)5-D zmz4SUHj0abyE_u6miUceFw))`EH2IuuWAbOl-N`Zl1c`i{ge@bCp(Y~oLA^6EeQCFu_dxR;O`;XVYuKVvm6P+ta+0iVrheybhabs z`GNBKz@jSQ%<|-kE0eQbG%X9o)TU0kS+gNf2}AO^6m8*-Ry3?6xGLFjnxdVwInR@;K2S#gOUjt9 zJ-Q-kt~R77Yp^}sPAWz*Ce@Kv+CY;clPYe-sga8UfwF*Tv%x@fv=bX^t1xv8VHZS@ zwlU@F#=WS%gnczToG@o|emU!Mhq%3{`W9G_IDw-|p;H0BMcnD!DFVen$%5iML|wuA8S(F2^j@>J*Ou{py+i$}tiT zhSkMp=km2@%L&#}6;eD*3tk*pIEClv1=62wyn3Ea@kmvy2rFIeFi(WA=cc1In6?3) zEnOEm7)L-zuOyyC?P60(rsiO}*eeSA0wbOOP^GA*o{n?Tj~S+Bb=KDIv4ZH?6tWQu z(Efzk*fN`r-J+g(oI8lzH-laHP=&)=)W&V#E_ zICXD88*U3%M>@m`T0QoTA+-A&(J;jsy@$gC<%@7H1L_(2^W)+9iI!<%LRKDc3Uz|e z-#Z#KI@(}2zhikvbfwsqaEzT`^TgZa+?BnJ{&75YLD}yb;PzxexP~3`; z`s@;oQASeI#|Z{4CSf|;jor{aYa*NrjRsc0++>QMPgJ^MG4S-v5Ga|?xnLJKRH;{B z3ve`+;Bx!1h7u3Qs@gl-c3*Nae9T!aOHIOaFSMfB9p;^|^cD=sR|3j}yA zhSUn?R9DrPl~vC17f-e&6js;N%${8u-~_FcpRPmwI0=ciR)<%JJwGs2xRz}#o$a4J zr?R4cb~)Im;9p@p)>K?5?yM*-R5e^&NQU!ROp8?EWy^5sr7avA484qIU8Sp5Rm5=e zUn$I*%r;UapcSt{Vx$NJi4c}B2Zcp4K&nA?aE0xGwJLew9$>pDbc+~M>#wS+sjjZV zhDT{r4^hUW*A8r9Jp1T?o8-|;2iT?zCNcrc6SFZOis@b7{E#ghs_A^XqcxD=1&!WC zE7%aM#WEgUvSD@GBza1an4;thQpfDQcRBGDp1=Z{7)#dR?pdJK=aX6FqVvrx(5ds$ zEKtew)vPg@=d;OfpzuLeco)lbl3w{Tve1;LZ#uwf#STioKv72 zC)%k?!55M3<;EqX9oiELcEg9w6qU1&nLpc~0fOP?PU-k`LlR*vI9Ge-H-dW)7^$f}F_37|II*r~| z(sUGT-PyC1rO%>V5-eS&x0+;7YoJ?HC3da^7vTa~hP}9?d=Xlf+$qF_*uN7D)5Rp= z1lk0o_H6OWV8B18qPD88IzZ0|qsMJvMKBsIE^3S7qgV_KE{cV+Y*@4_5sbD3!HWkY zaD#9eR^>0PsIM*w)Ky}67oj84TwJ6q#AB$i2{76r4Qvj}Z80=TTX)E)riP7AVgph! z!iNe+nZ*V)BRI0YWPY$z?4ZDf60`&CAQDjsVr;VFr}@b6msx(OS%f$|?uZwmZBZ~= z{m~4eNgSG`j8GeWW-9dakVo}sR&?)rZ;!?76&(tb4qj}33#|&u*^6ns90S!1u{aM) z@hfo;f!`M9Y$N63KwjQnA8x{=E=F<=!-6e~( zI6$2fe`wgjU}IIGd&4M}7z?p|QSPnewRJo~DY~*;Z%Lg7)zZd*mo6nF-H3{Pt&Yu> z6yH?~DJW!GrR~^v>7SNtSFD(cKsz;nl2hca!g!Lcw|csh$Ga*~`58?g)0RR}j@@O%zA%%76P%1O9i82w3cFWP!=H+x~M9r)EPcxq7b9*!6 zPg)t}`{xIf7n+>fLQf{c_JJ%zP?%$US??+ zeI>D1THjcTX*n~4sRkyAxRHeC^nA}o#%Jv~m82D+=1_v3=ORttH_E?CYFz|O>ITJWK% zPOu7(uEdibGP9H}Bg+MyU}K~?(`ySbE?CRvSyxKZSh#g~ORmID%hqZOUGq?9WpvtP z^7g$oVyI2Ae#3bT`o&qB+wmoXhAG#roaIhuVsEn|9R=$t2c2;DofLz#|YC>&XYr>66h=QFd4heNe+ z-usX%22b(W^+8}r)@C1Q`f^1+Ym{;@FP?4=ahYB?a1Nd7I(|ki-WIYm9C_4@%(@q$ zGfE@V8BJ`aq@&;*eyE?|3NinzB`D+R9j*={Kn7`jv}su$w%TTm zl$T-F0$=S{E?)L0fV3BGUS!bRCX4{E&Hr-Ji zl=C8Vj{fTARW#P8b)`{ib{ zsgAA;$K({!wOq|lA<1yOK)BX>uX}lOAMd-)#*DQw){P7Qas2k!Kv{qb1HIpfne1Xg zpSj$NgBe(5Um(nY$QHXYa8xmG6Yayf1-gSiw+PP0wd#x~0$7(3k19~>JpCCuX@(TS zPtfrXCuL)bBxcTHqLfu)gi*16MQ7>#8^Jk_;+LK1_mVQMZm~!h=>QvTBFcu(tE^7P z>4h4FGmOS^_{(HhkJz=6NnguGNY5mHIeIe%??myG#_yn^bIva*`G65K|cS5a%bf488na`v3rbLP}jQngCL zR?Pm2De6owt6g6-Z(2^uDy^*Ata3V@RhEt3ZSCCI4I3(?Hj8~GXfx)%k8H#a9xMC4 zeMxMI_?Zy&BvPrA@P?q+L3tMIRG3Cho1|`f_MNrCm?4W=wXB+A^ zhwR3WKF1)n?uc_zI5dl4EyMkVdPq}FZ^Sv5RdREoLgI2SzbODBYlw> zM>45|jsDod4qdURjbTQb=0E1XD6@Q%$?gTyc_z^Es1RQSuQ>gLqcmf-`Q=-z~9 z>=hSbkBNNjHg#5dx{qxq;UFmm8)fbe8$4FoR+0vbS*laWMb_SJ4&)`!wb&sB(kSW- z>#~t1LY+F7B^O(F+ICb>2O2 zfGzUseFJKe>Us0Ad9SsDeh5AhZp9Pm`qTx3bAxj+#3dV9vY3b0mU|h@vYCrH6yZl? zOR6eMOH1eYrHhJ-aMLGVT8fMKwof%0iTg!4^eU%;vh&63TuA%}j%C5SEOE&61k#E*yE*4AM$(GvEW`S)zhs3+8FLmf(Oa&=|t zobt-LT7O4K-F`1t8m5)bt}82>TVI3Q^;_^@)03XJePCR}jyzJ;1ZpYu4GRFx|xDR-`PkV%vP5R+FqZHsUu9JG&B?frUfu^iXnK zhNA7Wu0FBWvNA(guSPeqcqIIpw{e{+h9Rz~nMw=}E7?=?0pfVV0u@zr{l)f6T?M7pb4zRH%tc>yUgnxzSyfgsn=X)5);hEb zYv$kyD|5=}0vQtRnv-j5YD((@b+ehWvf80Lxw>rboYI<_I+d)n`8uKXCh&M~E)iN4 z=_d13m*HLAqTjOin*a1)<{nd|{>$8B7S(^5)9G)4vx&HNK&rhDV%k(tGG|Wt-0D)q zx4hC)IWa2bpPvc4A9=7iz;|L~aG?`RU1+qlurBhSTw7OLT2@8+9jz7 z#S@j`Ra5ae+mf!97A%Lj3e8V>p;K@Ekv6F?xv&QX`B)ff>Xhn|`m&OeITdVb{wnFL z224`h!c~cA$Sd1S{Uw$P)@~kR3T3&yzu%gyV`%Hod~IW3|7FZKk7m$+sQ2=vJGGY~ zueh?e`wTN^le|xy_9*a{IoA+VJb>0<)@D1y8c16l?RtPsu{HGpwFMh7`nkD^%iPx6 z8~V4qsQh)G>3X0~l2o7;h~&xm&Q ziYMHOV4&9}|BpL_PW5|mfw($57%P>pC!t<5xR}mUaoe!jgEummJFvOGfgWOAQT_kk zuuUHRue(ECc;dyb1);XCKHYtX{;F=bz;B}1Z?_Nv=j|5ar&Cu4^+7?j_xP8)Z3EaI1p-ZDtJOT<1lAhK6FRBjI*VR_f_P2!E;$gW0E>`lVRM!P?!EA1s zKM@0w`=a$HA=O|i|X2hFZl>zNtCM_9&^PtrUBcoR@033|Y>@tBGVk3wI;Pb{>}9bv&W(Bfou>5p@FrpCwz)Rv@kH zWy7$ZXye!0@I!~aY>1iKmFKa@#?5KqE%R7z8zh!_EW8a8%RH9g28m@Ji*bX*GLL1s zL1LN50^K07%;UsrkXTk=6wgnzOlt_Wgw;08IN!Ltwl*w?YfHsqi(%PX+QvwCTgfac z)>0NVW)^E}GbTUTZ|&~I49?**4d-Ue0Uyo0rc;B#DE9A#3NAv7- z#vZnZWF?dS=l{ns~iG zf#p%YxQzwU;-aQ#M=~$@x9uK;yEUBx)4SaIp6*hHu!ZP!MRxxd8 z;6N%jG+5UBl5A#Rv;~&cjSSfSQD0SGT~=GCN=xqTh@xVe!+3TB6_mDhXesSP2(QxB zQ{%6jQ(9J68=&iV*e(+1y&RVE%3B+&D@sf1%1d$oZi;7KaY?fg`yFRU*>2XlL2YX{ueA)l zE`qPE%)Gk5TFlG6sJ7NJb6(!;Z4jrsv#hPs`>JME!lh%i$Z@@3uo|A{aeDGwG2P>g zTGm{1ML1t#M;62F9^a|92%S5lBJm@TR2jD?w zV$wNs>V9mU8dE5APmLk1%)->T*zuE)eZJDmOA}ds@`b(vO}`<@Pkim=VjrK3!b@r( zllx`l`ks>Z=>hCk&di+VwL&)7EX?zW{)5iO0lR z+{tSY1@-lHW%aWwYmrn|m;7$LK~pNnP%+pV2F$aK6NAn^btfO6JY=m_?c1~a{BVl? zx5sNnEbDB5Je1<@!hy0Vc|aa0i;{=mfwD+nO)jV`t*b4sEu)Bv=l$A(ZB1=$#hh~7 zr;cD-lRVfCP#L^K>%bY~6-Wol8Zo!-?eY-s*Hl4`Zl>w`&&QgVppPNWW%mn_~83&czMOqOn9jX6R~J{cJ#<#}4cMHo;@0>TeS~ zHd*wy2_7?u{x-p}C90pZcf_0i&)pVu`a65RYj_|758bugfBAdGoqo2!Bkc6E1s+kS zpDpkRI{j>cBj)sP?v9Yt@0r^oPCw@^))dn1@r!sC%)jT^NjDSd9|A2bn_D`!s;ZVB z=vfh$>#E|XIq7DZK3%PKU+Shy7p`l#HQ`umczzr|+*gI)aFRLo^Z=V+Er`@z*;O6R z2ZdR35etKsE5k`2vNS-3cwLblC{sLE{s+nwz2uMQq?VTi>dQ(i=bCp{wMXLAV(>HK z;RCuNF}hi)g&JzScrxx#qFb%1@awY?JXG~Se#&flEEbK$mA?DoTsXsA#Oud{_9rHs zH;W8Vy*PsHz*%97x&vi~*vrC~O?ZcEMJ(E`?$!#$;ypZwOWk3S(dI~x9YrGKsnryG z^V*nV2KT{jx#u!5`Sv&9b7Fwr9Wv87LFs*FUi*@`ovfwoJRZZcHnU3>kJnP^oYyERzO9|Cyh74i%gG%@ z)>2lo;}5`O)?6J(Ic*(y%bZvAL{J}iySy6YK%A8%t4R6aj6vhBVm@_TOZ`X<{Q8RX zTFlIA1X-Ked5j=yGdqtFWNl{W7(v!zR*nw4c5||gAZs%#(X9qk;Ia3?L13A41mWr! z1a^5f$iZQjyY&tRyW}}YPiI8QuUB}U*oe-VWm4y;+Y^1JKQ3jt3?t6hTm#}jTjcD7 z18t9^^9=%XY@Kev?QxAO1K)(5al5}QayH?Cw#U(g2Z1@ZCOqKwjM%MkazU=;C@7p( zG;L~rLBSM@5FZQj^QTUonwvXq`m_R}u-}Mk-|NQ4mtIi4pU-Ek8Dj7;sTmK?Osoit zZ-#LaK8)ExeUtAaMj4ZuX|HWwgGwozZy5h@;QYp@l1Z`VP$HyIhT+4<_g0zT>63rd zD8Co({WNexq5pvkm+#^u+{bC+K2H<(b(*;E)5QIpCeGJQUNaB>DDU#FlO}GxG;tfG zi5s0JZqqbzTcnBGI!)YmY2tQF6Sqs6xQS`v3eva+|_B~u1^zpbDFr@)5P7CChp!eaSx`6 zdo)ellWF3f^};3aSaox1VQh`hF9P?C#L_e|cU1j;&iP+1CUzqZG>l#UAe4vU4f8tJ z{BI=WoxmIB#!2nz}+e4lP2FN z$lnL%J3CI!6HVNDzzsRbFxJN(9Xem0$C^0GcUxfgNCQ^~%yK8rqa23-bGF2#D#t&8 zx!#U*m17;)_iteCapD~HOZD*>FfU15viki9xK9Z8M|{Ac>({}zGtzPoHjGOA(Lwd= z)m}b>yakvAhY-pz$X;$Q4!*4*KUQK0M~4?5+4m3NPCAqj$@!>$?>f{l9>O0TO zWZ!g&NySI)c~9W>Ix#gL^^YSYrYF7=fLrtD)O_nB`6-D>#WxoAy$amdwBUdvS$ihF zola(me(~zR#8(L1oKplW86RNAK@y_~lkxo#xYJHe%}4F;eu+uNNA39`;I8>gYCf|2 zZHY<6_Y)F70PdZ?rsgC2Ha|@S(Z%}``Tw(;0aF}m6#+gl!crS1-NG!DruX0e_ zeG`~3&Jt|N+SP_g&O2LR)T zoR^=ezx@%o@IM4yvU(ei;)gpPT z3*j65(Lv?#DsLtD&IabKix_75c@<4O^Ylt1`FXF44I_j~O zbAg+CsX!%bFVuejC^4z{X#71ExYd{S%=ehY^u+ffa35cunvcr6?G=hiynB^*9PHa3 zxLH@G<{N?JPKi;h$@mTg?)0lt^Hm`E0bn+~THun^?;~U%FrQqLnveU#wF0AFz3ij$ zXh+~`u1n3gA(9V~m{feLz;_~W>)eo#0aFf zeLo@b7vO%lU7(WLHwMWQ?odqP-OIju*yjiCY=A(FU32?XHotkesaGwIR_dNnf?ZB(NYvAZtfH~*^f!iE!x<1TsZ)^qm z(gzW<@JEMke~x&60@BU~W~YZ3W>7ohaUsq?A;jxQ{546877ocbob#(Kkr;L0yvjlC z;5gupdRVX}YX=k}Zv>|45fkUdmydpQ8Zh@hCUD8x=?6%j{J3F^dqUubk8|Z0dgi+TnD1T^ zxMby}cG~hX&Z+T72b!6ueH15;1m?0=7?$+BY&?=*17_%}0+)<$84@-GX2ol%`F@Aw zi-CDs;@~Dv`x4-L518M-o|=!!dm=FBNnA4fD6U-!%=2$R0Y|d-Hv?(wy=fSw_@g5k z-x?&;0Q2!%0+)=B;?TBl8%72G=tx#xI`7#VnA6`8xMX|@BtHPm%y$JY8Q&A&s|P0c zeSsT>H?Q_g_1gl>2@;o#kLD3;fVqu26pm!}J&wTh2{5;REO5l{)jxI~j`fXCG1h!5 zaGT;y+h>Vuiy)u;9oBR3N5=^KF`r}q!ETU$DlvqkgX5Y5Hx2S_zUO59;)SDlydVwS zMBtjzz)?ItISm~3kH2`~9C3UJaCZQ=bqpfyTOd!Lss_`Ll!7)OU+;un4&9u`n@L76pO~A zEs5Nn=k1bP*NLCOjU0%lBIK4v+dCs|;h1rJ&Yq)x|$_)GltBb>OXm#w8RAGhjLe&6tZZ5q ziUkw=xg{EFXo_|sp(2{Rbf)#XE}_ueD}@zJ*!DH4vw10OYR;Y5Sf4vF)DddyJ}?ZM z!}Jsj{Eji6ZU<9Q$*^u^^OV9VQ^fn!-T6JgU>d(qE-K>pY5Dmgy{LfSr%#{C?*&uD z`{aD!szTqtVeWZe94O4C*=pSqPfUG zi!>%pT7tJFtgyMRuXV^90E7{kqZOaNHOT)Jmus zMr}0E)D(`#jSZy8XUq$SnvD(R*CEEjSR@f&%|`VXT%dRghOK!2+WKc z0zt~lw1`ZE5LRxgfn+6Q!q71?Q^R1Gw2Zt!DH}>EN1w5hjc{6nHvVXX+Hvp;kd@>yZu}tcNt{ZH~03G29Ggz2#jx zBl6PC;|TmKO9d5~^}{yA(H!oG#@d6SrSWh_f@w(ZQ*s1FPN2MhW`$U^tD`xXh^`F9 znu7<1V^L!ZndUQ8TCgJ=f}-Gi1Z{nYQC&Bi$Jt={ym@u=I3r5PF%v2Rje%-oEXW)h zWg=xOWBBMlpk{-?d5w)#B^WJB+d}a;KmGu|89w?-N-PZ}5WA^c;5XPs+WJWALQ%;n zH~}6$nkL)qAY&rFy$Ul#_n$$5H4$Cf)iPrS(!((X-x)KiqpkABb7KPFCvKSz@pjRXwOwbagZ(&~QuJqVcX+7-#uVy0hov;t@)b z_%ci(a)FO{W+Ew#=|CKeNu1k(=;fG>#I2re(36`$td(nG6HyaWry!yXAH9RDB>7d< z+2lfFJET&paA$+ssSd9Qw{ca5&;s&;ajzDV7sLcL7AomZgyX@2sYV_cr&5EFXqq;) zg%jbrr8FUfpF@dg46Ska=;`QkZTQ|6j&!s{gD6*5Q^FXJlsll0Uk{iuV`-!r&!J*p zhuVUOfHBezCPJ;oZoo~>mAI}B1dkxyjYicnvzg=fgszTwq_rd5oQpO$%P5Az2V)g+ zC?08|EDGtxZibI;MquF_gH@_%OVRxb3XMvno`dMZsjA#F#W#8| zo6Q#!h;c$Nh+sBbac3E${Mpgf9*&{lZJ5-eaCQe#97rgOLTywvaQ4g< z(May+G5m5oA9dUZb zu)7kpot#c}(Ezf&vP3px21Q~FK8vZ0StAWLFl&%%l-)=1pWV|!6NsQ3AmWMcwlKDr z4d-FNk}hJtNTz6TiLxx%z!4z0BGjgur*N5BXR>|CMw zvy4XMU5*&eRVLaqnlnPPy;8h_Ns8*)9jq^HW@C-YUc$ZH)xX%ssAmdqx8W+G#hkPh zb?Yw&!4-WXu(k9tpgA3_r8V5ap$5&QBg*aj8`TP}E@AUAHy%EkhAdIiXiE$BJq{mz zvr%q~^N|En5$~V%j7&dg1>bc5MLp0WIry8px5_998 zWo!$`EeaCtN;o6Eu>$~GDu9DS4gg}Hx?6SFcsCYF+U01pC)BS{{ZvL@TRBp zRpVTw0|6+~91O);F{)q&NI}Y%q;hlwSEG~`@YqbFK-m+0!6=#q5qjGaImfmOF%qYZ)3|$du}hl=csz_aoAM`s4~g#mI#9Jmu5N>^#lOX zvS~#^j0x1}bFlK((bd-0nZT^Zm$(9V;`AFMBdDJl%Q_ithIJKndYOWE) z&(|eF5yXoi&J$L3^Kf#VYG*hr3dhhKR?0S90@Y8HA@(}*=rI#$`r>$*Wh@0pe5MSR z!GN0UaJ`73!xqp}_}&@HrMuuTniT#CQ(PIBnlVpq3S&7j+JTeQ;k;52tdFAkquB9K zOBf?9O`?XYDs%MirKs3h#;!n&N`lZH7PBOtVeaVRW15iU<3w@z=;Kr>76dUJ6O-9G zBvj#)fbCWj2JPqGyTYI$&1au@tBGF=S`)NTbQw<|-=armv!m zL4(8ID%mTjsyM+Or6LD$!sIx)p!s!$>iXs+NoTSf(qC5+M=(Rg*!Y>RfZ&N8L~IwDEDut6QeFtvVK;bTX3 z+WHQb7;N9U`wda%1Z%t6>GVhh-s?a!4CmIOg)hMQCC(|yH7v-m=Q{&JHaK&sZYXH{ zq(=2%RW!bICXbyIG`@AqQ7sMO@N%3#^TgvTPefg3xT76o5=WlTJt4>_5yH|V&0aq7 zL{zjVTG~Rbah{xf`gA&S zqB2CCr*t&q+0_WX^N~1NH6qo!Ew9tb@5K{u44{od)v7=A1e-=V*uJVt0ZkAyihCQ^Lmv6`k1$QPoedSr1{mhk` z-)+i7T+-p?OEp~ZO3jr(ELPo3JPLep_cWTE(26>D-AI(i#U?Dbi4VqpNNw!F&79PO1m3eQTb z)zl6r=a}}%dB^t9-64st=;gC;d0_bH9g|=z;Xo`%Y^#7A{YBHIxexcM(Y6}Yj}^_z2JvK>o<6o@}p z)#aSKnogc>E1+^9&En5j?vJjpO{{6<^-|UB%~;}ypR;)8xDaRSV)$Gfign1-0J1D! z5s0-;?O54BXb_`0sb$K~RYJ4TdzD>SwrN%Cr~4w|6I`oz~ZRVf{|! z$>b|z2KB>rRXMpC=t|V*$<&B9Q(TUIF1iq%_8zJ#6z65ZXiJdmmH8*Dfs&RFaY8I6 zr949NuttOFIo=cZbR0lSS-13AU7tSCiuI)#(AZ8QsO5L7&Y}7gW?t0V5RqhWsztEj z4sig)Tk2l^|ET*Cz$l9B{T>oSm>>j*2jUSlDhgr_ZqQ7C08tXc9po575+IPvWWu4S z(SQ<0JXY~OKyXF8Z&XACd7tE#K@HXxFbOLMBy!Nwuj^fqZnJ9_}#ff$dyC*G`RGAl4x#kTBNVm3lFEvXXky zSKV=&)jJ*R!;RjJG7fr`7uOc{VK882!N$?5r%3eJ3W7L@KU)qNW5tN<`r-LXbo)eW z+e*(@TcuEK8pjxq)!PfNn5NbyfHq{Bs?~w#Y?CpU7c^-*NT2pTA_2&IDET2sUohq` zl5PwoG*Mz%A~LLb^=C$KY0KZ&`(m=<{0Vl8E#J}zF&10S{^5_ ze9&76&L{HDgN>QcM+h4sipX+3tC|1oR7j)G^cU)hP}Ud&Jk!cC1I{!&;9OV#ylv$i z{Q_$c~e%7Ss@O^%tc<7p!+sUtmnZGjjcE$ z*|PUUb*%7BNAISvbV{JJUtHg{x~Gb3RYMxq;ayS$aeM|`S|49(Ph-LsMXPKYdt0LA zJQb3>qtQaArTPS<0x9(lpbBVF*tm~@aJh^~EHWEXj3qsl1=HsS6e-eBT5lSn+9Zks=un*PDzULWMcVfs&HK;#p834LCDM zECTY0=v1b1py+*z@z0AROj9?Z)ncK<@{$tWDi5bP%X&OfMruJGI>4JXPz=Nh&Dd`{ zpqo^2e=9^n!W87RWYMb>SA;O@MOj$J*C!#Rw`gAqc@vN@YI?}TyvRm$ho-oc? zSUhzqG{?>tHR;t=$&UR{TtJp>+4`|6q3^_bOg=I^5i+_@9}FvVg;L=;EP&^f6krX3 zv~zM4hHGSJ6?pS~7*v>o#f4Z>hn2E9<#HV$A91;q)rOF(VW}~pz-l1ET7uM6aib~X zw!~sL+$hWCje^szQ?anpVoGGW%whoxl&_A^+icV`Ron(pdNJ2miWW$$*L0LD(!8?1 zG^eEq+@kt$-DKgfz&jbU^0B523pCgav+#SpEdD*ZA%QF<>Gg?9O%tqKsOTMS*c7tX z)XOU8GQWbY#Z{3pnCQWB!ZJ>4@S*!^2(Z~|F^(uK5wyfbuOV#_D>Ln*GLI~wtY%n% zC~F#RwYhfdg}M}Po1n1a_Rj&Lueb+wEyGX+=QT$6SmecGTt_svFNkf!+#ZxQG*eXi zJZZ47vXjlk1lF?L>_IsKIFWarn>|prD8h=&!j`rL;x|i_R~0Ghd4Nb`7*mki-KetO zY9^CfFaJEJdeY>7pLONWkUvt;qpo|SV~4X^NhtGTI;x>6}SN8erl_}3ZjV*Ts{kwA)KAd#M1NWV`yTzCHyq|@4)lS8G zQ}M2@pD*8c^}23@KCd0|{%=Qy_ebk1=znyKp7%=c&${1y_lGyu9XRz)O?yDlN9Qkm zuI*EE|1)Lor}opcFa;f|vGSx*l6J)>vA z$gWrAXU%!#%70-^h@j7YsQulY|8vJ#k1soTc}m)%J=i8k(6=|sJA86f<*4#qt|P0i z@Ig603VNP@=Lb_y81lVu=c~hOJGSesY28sb<6YOxYWvtlXP&TS@;P5${avdb_n^KC zdPR?a7W`+2e^AfLe^gvo_RVdyVm~&o_UtZr8syyfY%E&)F*n-;38CFBbImPb^M~df@aW z^Vh`w8aw)#Vb~5s&@UfTantUD(|%}n;ey*Axo;$Nb3oAdpFjVfmp^~XXWu+Gs^`5c zYnCAWF_eGa%2mA<-+k64UGmyL{=~L_-hkJ21$~cp)#9(Gbso1u+rFms!B+R-bxT3t zHgm$Etu@!SdbG@c(z#uVGf@sv7UNwnpY`tU4h6S8()IS8XMMTu=6`EihM;dae!zbZ z%&VRJVB7mHUbVFDOHI2<(7)}t@w2OD^*kK&W97u;H@J=0dO(KT5yjiHtYW<12qfIT!Sq(}(10qmEj2ZQ3!vJoVJUU+_9$3(D^_ zcTn+;OZwf=YH&i|<|*f;;FVfIzx>^^S6=zaBV&)*qy2t*@#7z3D+ED5(Y5u12M-*b z{Ps`U0~bE`*m>CMM$l`LCTE7q8{Nr(RkPVwJnB3AMV>e?T+tm zZn5w)JS5}@`s9K8`!4^Zc0xu%!I?jv-s~pG7xZPruPZM+dGY6E-_Kri&5(8vY1+Gj zzW%nwn?ITH=to_T$}AnVZTmQEwG>DByIvf9=sNH68$O(H<&mMocS6sT1U>HU(K8FL zcw*&Ok36~Y;G+lg@OrYK&%3^$*`q5ieJ!&n?Uo&F_gsN(QUv|rSMEK1qQ82tSx%SI zKl-L-VGE0vl>hQq2Rfg9OU$yIlOOypV|mIacuic;bJp~J;kgIj{q?#Zf4*Vbnptn* z)n-Be{K>UDx^^rZKk4>$XT8}XFJ0623i=;k?U?aw%-$WdZk;%>^~s;_*0ghuru@DO zj$Ab__p7oECv9G?-TKNF)Kfukw<_wGS67r2p8J)z;DiZZC287Yg8s>aZ|B@{eb;MO z&g=h9=R3#EMm-Yr_>H|DxFBoq#bY|J{pY^})?|5AE^7jQo__FU;$58tj0e zdsgh2QhZlQmxoT>p7MOgb!VX-wWj>nX1$ahbI)BPyMK}S)s36JxDj?h(9gei(z1+6 zi+*oY6`kGX?rM~W)q+0xoKK#dSUh+C$1Sfu{NWqij^MDMU;j`-<%Uf)qb~RF{k(X` z$jA9=Ddk`Cb(dC`|B;tEdtv;=pTF`DhC8nk^z%=P9rt}Z*QZ}za?w@qEFant+c66I z{x=_cDE*dB{*Qkz&G^TCZ|_4rZ9_SQM>n56=gQvSZD~6)>)La^{1)$e3i^c|?^$$a zYV+Z5KU@5dmmg@2^ehncl$1VN>Afe<_<8G&ojF5xpeL|V(AWR-v+c7=zx_7*;Nnkv zZMp*V7##7g_TRnGG3(d887)0)|9#7mV-KL73i@>ym%i$%8`tNqg)g4{{q@hGd|o5y zyH-q|zyH+qr)zF_|D(zUzkQEa$_0INtJB7>Kdbz=rKP`pKm6k}r{WbNw6gK8r*2&H z!rlQ{x_nWADuw?Rd??>>dr5}{AKpg?JqAn`EA(# z96?`v?DWM;^F6J;eJW=Avon@dp`Hr*sHc3zeqQm?y}xzaTu{9m`X3|c&#yf)|K!>8f4#Z% zmfKETwc|l-1%h^Y1@c)d=);$A#XGK3#XGL0#(T80RjGz@Yrijeu<4o7$vXX|E z(NZyfDiaanz4b_6m~C)n!<$+u1?8osSO(Q#8ME-_=G3ajD07aQY-w;3=9Ctda=5a= z04iU!z*TIbuhUh9>}(S-wQsa1nDbjlv0v zMo5sk*>C}<7Gl1w!6rrWH>NlhRQd|1Olyn;S(X|jp@5~S;aY5TS)4k%GQXnX*PkQ! zQyMP7^0rii%fcLe9IW9I@Zu##G8=1LV65c=wuWn@Kukk5oL|>PV@hRU5nh88T3VV` zSXMr}QK{g3Tw?@?C6SF0fR0lkI$sUX3^x9a5-^9&cQIa7YH&u#6f{N)jZOkuo2l5o zslm5UASQzw!4Dmj6i;cm0CD}ss8A-LQ4(fXpuO}>ZQL_am}<=BY3Ie9NrQ_c_G&4r^vN{*=^HTZi`IyCzpmlU?B*9pM?+K*bVos=L4cN_$Q10U7`RxZHyv~Vp|S=hRVIXc8j6GjWb1k`Qs3Q@ z*v4JXeA`VT$w;@J>?Y8OT_w6`LnGGgYt((DaFI3u zRoN4ZF~kWI?$|j_9+*7BW^vfyP92zt7n>Ewz~_MpZw-^uS_>RlBq8{SB@L5!S|Sci zoC+5z-hR@5$C~CqiO4i!7Qdm8l0Jh*E9dt)8GNU21g6IAXBI8c`y|8~X{zKpeWmVpHK5NB1~Hx#9CS4Pn&H>4*Z?V@(>)nQzq^m?kGv@9A{OBY|^2Bsahin#( z6BT`&ORK?pXze2S)Y+>znrm}ZC{CNFLT>FdgZ3YTcF>?5GH3``+&27@8v9a&nD(zl z2&W*&G`x-@MijrdMMwvAP0tu(=+6UndORZP4GW5QM@LET;t-{R1nEA2CzFGP6e^M> zijF%+()aMBoJ`E|_+?EDqn+@df*ylql~~OnLO2P>#2X_WArr5sgo*zGhbi$gxtj#y z$mx{HJC!AyI>o%Ty0M=SO2VN#3NyPjW;h&*f+)ka@IAINtn<*nD^NJ?W%zO9gKQt(GC%-N zaadMcUU_CvPU+W2ifV$)4RcB_3`S1L+J%)f%2qHWZ3RPa4Qq2WNn<6DH0ar%8M`>w zwRi;+uPuu8%->S|Yv=V7H!uNIo}e=hu7mUpkDS(Sa92z&F!G#N-TpljBBzEgwJbxj*{2c@8eq(Ql@7Qe5PqH zeCqO79J0_dBnvG=Zf%Wr{*w1@zQ0W1ya#UAar7kWT_6l{S2pUr*S}Z|J6>4Sit;T`Z#jzQIRI6;Y z%!*~&?26r|6ng+ZE~M>Oiam_5R4hYMu?)F|F_kn{Ye}PGr6pyJItrFmHVpQns5h*k zH2Va&?V2SIHA_DN&6eVA{l8ALtix0j-M^uAQGkOr&9vGz9o4Fh?Y8*G;EKN%G%!$@(wMU%J&W8MBDQ#DI#wskRiABCQ*X6LxtSh`e@Mv*=+)Eo=&e;_CD1j#My0v&O^RVEacLO zK9y|)QoOR5QCME#tEUX|(cnx-vOOB)QD0tc*Mn6_rV_`#gYKA?gGfC4khtn)Y*wzj+goUS)}VZ$m~ zEz{OYk%#HUU1`4gI0@$p-qkw4s-U35Kp1lDcBZt*r)1(%865n&0Kv=b>P;vlprx5jn}G9G!<5 zd1)7eJ6Jh#6hHLN;(hvvkF|%_8VlSdxQZ%priLWZxU^K*WVETce;9G;u2hOT1w`3! zFeDYlkXvJ&le7<1$gTM^q8&A*7at{Di$qg84>dNgahei4$uxzgm?pcXu2PyxGBm}I z)D%NfQ<6qaNt)lCwr;@|U+dbr(MNnO{6nvb_AJ;^z28xLY);J1u02}(QCjPOiNbH4 z=QxB{&o{Wklrzz*vus{p6{b#V=sdPV>3SBj+iBQ#whDXC@|A5<8S7-A9ks_Rnw?#H%Mn>&tED;* z%ib|ensn-MTJ0Cou(!eS^0fTGiFFJ~zXTrY)EE+1$D8Zz0YIQ3!!eEga2?Z_q^MsV zrPVO_HGI;)flp0#H8jbP)FeZ)qb+Id&`Da_y51S_t#4lEs80R41!&>y>RbWp#Wr>7 zJnXWxZ)$ZG;UhuyJ?793+Vp8xC(~$GXR8>g&ergm_IUVIXPTi-hNL$jKp!{V4r zXz(Kn(`i@gJI%Ekru|*`O#gfEsnlMEQW=s;WymdtA0=(C!l9-4Yn7Vt|4pg3Vu~BK zmsBUEeyEiCu~O3v10^1u2LIk?`1tKlA z*sdI2zs9DVWgsy<%T-f781Yg$3`ylMkcHAtw<%1oa$akkoRVZ2v=1Y+=k?(9@@an@ zUX3_=Uy?jb{xLX?Ym1X``V>GT`;y*FtTXykEwx^V#h_PC(QMHhWv88G*sOA<+ph9u zXjXVH_rd4=ELY9U7(?X@NtH9?#wSnlzM`NVQX#iC9U)E5-E2pcmXA{m%m<#9MaW6> z>>-$)y%pkffW6zP^U&{YXg;=Sdhy;o?4VhX>RV|?sm3opX=qLwX41{S`8hC4x0K_) zx&>^RzzQmJ#oSWyUhFN^7sv&WwcRQ=#zTwJ7&9bugCV!}FQ6s}+FL3lCx0di+UKA# z==27;b7t+!;Z;{Worg8SW=`&^^MyzPfSf>Ykk}aDe>l_ zTg>{yOc3?QGH7S7KujMS0j4nt2i-Fu@%OXvneOM{Q`%JEWR@``vy34*N-Sw#D4ZN6 ze#M_1TNg{sQb#}G(651@ShGRjtWOp#VyVyeko~evpPVNphMn@0Z2D}%cA?2c)l>PH zktYV)6@9o`%xdLgz{1GMvr$LAxv~h0I*0qW=OuMxH-@RmJL;=DeCn(ReCFj$BQF_} zdC8DlR6R+XjNg)m_6PGSwFh0*$FLn@3$!Scb1Vy^+e}>FQqzf1*|E8;*Jj4&4p+6R zC1cZYy*S8nu2ttFmX4{Svo}{eL94cv0`jng_Q7$kVKkenxf*~yjO&}MK`)7UXL`ES zE1{@!!|*{WeWpPW(u%w;%pdA-tQdve6pGg|3vun;3vYr z6h3vq-_&CT_+?FHNaij>ZjE1=m$XC`5;b*%M|oqtokrH zT9qx+DU9%L+Gsq~4einWT z{O93!gZ~2jUhtoT&->(WW@t4sOD>^eNG^+D$gQ!RlQd?nq)i8hx$i;)FZ(W+i4d>+ z6OJU}l+&x9{`+sxcfneUp#0F2C-cMFSNY5OE}tP6c;Q_tH!gt|W%Xi6RxgHR-{n$4 zdkc7mWZz|;pnVP+L$dE8c{Ti&yzIM38uL`rRG-CHUY;oSOsw5}#PN}xIcj$H+?$O^ z`+Td;L&FkFYa*TKc?NY&@YQ2)gk!@04YX%QeK7agd0m!BUN=cy6chY441NrsbQpb6 z?iTFKMEgiglhO)H@maUE7-(4r*lCEDm{?8k*t+LqoEeQ6Dam z-zBlB3mY!m?Fb|&$Dwn*t!N9OUVedBC@QEy=k+_G^)_oNM`>sne5NZ`X=;(7DTbt` z7?Oha1_=uSaGdt@nna7p$v3i_41_XaBeO;Wm1wD zOxFCnCvM=X$~$na1Wur<#mDHvX}5zGqh%l@mk(l?LAz7nSibGH9c4yzuf!D*X4&Ud z0yywo#69+ZWeO#R7mDLX>RQn(3T(+r`@4KZtb54-6CkKR7fsxCP$q1AJ8N( zM;j#VkU>Mh;+Qkv;fN9Wb`K=Pz(xcdGi|ChHbR#&)68^SMKBU}by>$kKX?tfFdVM~xxbQDaDU z10?Npq)*Zw55HzZudnvj{5lBm*y=0W2s)OMaYlWWo387loadbQKk?)ng%WgJCYGnWk@QNAvyOeXd(!9oM-LX+e;|ZY9D{XuzC&CJXTftJXPgiHWbQ` zR47AkZ7Vzn`2 z{g<`$@AsWrdpQR8P8{h!dBG81+}M%&>nbfrvTSpZe0<&I@tX!Eu=BJrx~JyF08lKx zc!LfHjs)#&oY{d5jP%XNFWs?|N~bq#%%@iP&3q$`BUp5Ly!pL2c11ZbLZ`=1M(_A2 z_3Jp$_3EL=zsTORXq9C*cRPOBEkD!5H1x;Oqp8aQzKl{Byy~YVE+w75ipn&kr1v&x z`Mv$Ci%WdQ5O6g~_Q|lxQj$3HURX}3t5J&nswyY1!H)-R6MU*=3w%zVZH3Q1**5r{ z;BSYY3jYoG)XAIhncyvu+gz+WWhhR(RKk#3E5TXPDpZI~bcm|Tp=dh2sD%2EHD@Q}tQ#L)b8ZfOiH$C*aq)ei&zD6}Q zO&}zK{OKNOr1a?&@e~=+bPB70?x+uYzGWi6sGmV9-`;^9Wxg>a^Nk_5mW#8bjZz^s z(7xY4C>|pOWBa~R6*ryNl0yKnz@1;|yQ!*~{~(O-aQ~Quk#gw$WQ@drDuc%&_+IBt zQ6J_;eHQiB$PtQjP&{67>AZ=?yKYeY_{vuPR$L$86)zdaYW~;Fzi8v+T=ww@$+_$i z2pxq~23}P%n{7SJl1@jn%_fI+md89Cbb7q`l|w#lSBTg^Jk7TLi;wd?ZSi)q?MBM% zW}9hZ8t8v#*aZENuaWB&up|UK3)-7)li9A}2%dQm1K+o?5%>{~222n2ZX=X~yW-qB zpEGk2rVG4dbpXE>3Yt7o2P~&7uX8bzmKKEU;5^T3d79vE_K=ivOIprxpgTRR`2 zj|7b?(in1USK%yquT~+q_78)`aTO`=VS~o!LP=YF7;jBGj*GL5n4SGe`T<1Z!$U?1 zB39?2Eo}02)qi3f-M+|@`Oa>E?wC&IJG+5NintfgD-3=QpXvWWJ->VgoU~I6Njt@m zTw*C{dx4jPk?3m4qUBqqnNA-ENjs?=xB$`qnK+zv(IsmhZy=tY;Brt(7sO} z%i@bbbqA~Af;M6)~cV9CaS(^d4}Gn6CF5xA~<*`)1JRfvwZ~R1(2BEFT%e7 zKJHm`&%QA7mm!(I47s(XK7pJZnEA*+smV#rEw?#1YoU*TYpvn4^A-=E#bOVX zAuAI@QrQg2ci1HDO@(7$c#}swFm3Y0gQ#uPoR`?c-dmi#Ys}%;his;bJWLr^@vIFP zv8Gu(*2u@;pav9aRLC8FeGz@A-9%@v!o@d zkXys{4B}xo&L3l}08 zugcP&phP*C&X62TXUMI2aF(=zDkOT>YLP70Cvn-C^Kg+~(e$+2hl^Gq1@`_Xd6+_$ zjM%m~3D-pZ%_&9GitAhHVCzjf4G=q3mceNMneHL*nf5HzANUPglO~KISy>p8?SQ1Q z9gsBi2WA|Z&RZ^A#&d4%-V;ZT87snRujMYz{IPI3>2*c>{J+*+#yvUw`)XfrU3>WO ztZ4tfJ!ks839BDkwQAKbU;4Mb_03z~_T4(Go#?c6er0jD_I*E?b<|pR;nLPE&T-Xc z9_qV!R$ES-wlz(h`i`p0jNLP0arW247iWL4DU+#Fk4_?Gi${MjVpHY^q>3n}A$xCK z<`*8MD!2BP<2Pm=Y9?YJXEk9P{77l_7ygMY7kunHq4o+4eMS45;}L7q$XsyiW}&5s ziSxHM5`)N%&9%Dbb+Z%dyz#Y%xgPG|#^_TtfA)`sbu<~;IPawKn7_r~n7?|jGBn5P z+Yv<1(5$9rhPE+Arg}R&b$Cl3olriWVTS~SE=A}LWKM#1CqkP^7tOky1bzs=HwoI~ zILk@ktq8HXPSD;)C`w5A1tB>~7mFBa)Uu4wRD?oLAkRc>C-BGOpqmOq#t)Vjd15y?Qcz$w-6no4R_68xWR{D$pHklXS`G9JsYUZ8oC>v!@$x zD1r;BQ&LibC~4Yc0|RB@Ba;Qwn^aLr=4)z9MRL!-{F*EfmYy-X#x}F1Pb!L@us)Q@ z?OoV_3*xX6l$tV31IM-b0{YZ}l|@zPX3NnwIhupjc6>a(U1fr?L7AB55oSQeuuQPQ zVSU=JXjfoVljWrbelPe}!aol_KH^rB0lyahX!r}@Pk?_7`~vuO@TbGS7XA$Qi{Z0p z`~44xYy9f>)9|kc{Wx=kZn4)IW8;LKV92d?##!RdRUx;Afh^H= zjMHcX*oky=jz)6{dE-^ctra8GOwdYI$jz6{giVRl-cTXTZX<+!U2xscRmiQS<2Uwp z0d0T^xwS_TlIeR=h1}X^gSOqE`9~$iF7Dsbf5DEl&0iydV(3}>h9MeQY+M54#+r^D zIbeohk2Gv*0-6UQv-6mLAdEsqD`@ygt#G=3>QOhf*LwyK803f}oktW7oex3b%rs^d zl@bH%A=MZomio38v|P}zj|gIY2(=NRg$Q9!5zv@nSL3)Hhg^A4J11VNj!s)QafAM< zuJcN_6Ci_5zYBZ+hRw-fTd$KmOgSq_P6wQXbJz|;uH5qG>u=KAN6B!Z5fi|wuyqqaa)Gm zV&yG4;tUb+0Ar9w$HibL0E|Zk_+gjPLxrod4*%zxtFJN1}co z>wo=gq)Zz*19KQ6#3>C_NW5@zB)I-=s_Ml0t8?Kpm`ItvniZ*cMgpG+dk;#eJlh|$ zr_+KX)nB1^fq@6TsDLQjLHK&PwpZ)V z34+t(?bUjxj5gxU)tct^9b3G;S|{UP?AtxCZDzHmzug$PXrf2t5HIBD_lLq*W1o}h zm29imy}H>6a-{ZtBv!p!u8-7m&O~hvrdRW7+?IDlxq7dMg-TEY!?~=kbo#_ip8P3( z>yPViDjGfNiDrOZmsd%EyDUnYfy?2;QfpVhPlSIZ{IlR+1)pYMK73A{Er34=z90St z@UMlR1OICHbKoz8Pcy*Z_rfP`Ieg+CQ1r*t@2B7szaD-a{I}r~|DKBfNYQsG`ff#M z9-IyXAg6yAl4gV$cDW&}25 zlz((fNEv})0cnQBOe-uwcZ(&6)nHb3(5(DwGb^#eSV*&i5rK^+dl4)0U)q6_ph;;5 zn75KfV=rlJZl!G)hfoFX)Y&$yLM)x$q}y%7eKOjJx7&trP5v3+ooC~>+lCHEncX%p zO|%X4w>G(LsHi9^D-74>2ib-mc2m&9-U;Z@)7}ZtZG)xS%Pv3#Zi^c+@_|(EJnLp4 z4RLfvhk)II+XP9Ts1w=&nv`o5Jsb6o-GLnVY)^*4?+AYc{A~E6;7^1<8a~^MvG6a3 zp9i1mBkmeS=W{9P*DLz1>i3=S$+?CNf3iL^B8F28eAJtL-HOw?!*tNE7O{bNyKVR#@pjw5G|@KD-`3=|!TCkr zu>FP}_HIJZ^MF1QWxV%E+d!EX+t9lWf6`g%K0DjG<2|$P^QqxsMZ6w$k#&Cw{BH1X zfj<=fJ@9kY?*jFkI=>C{f55*3{$1+#qww#>?fT=d$itxq+TYjykIEk|rJTdG zncmQtI-z?1F#f{h)U_Ou~>HCSgc!eIjXxfR{Ar zo$rI=@n`WI*WxT~QM_mV+t^ioQ?6VP%vHb9Vn~a*7_c;jkf1yE6zI%3!CKDWJWj?z zr^lPu`Vz-pF`XW7UNp8Jbe3p)PV$=MJr&2R|3^8gTS6`J_rrr;L}0q@Ik^lu$9rE6 zpZBvud(a;~8>`t?49^{&eaS~uUXIOgAY%uDqB}l*(CIgBu3~%yI$FdA;+e5}HZtS3;;?5NWwO|EeCyb@ zI0@H8kB*o+aN5gKFIbKl=QvNn!Au&!3LMsLw};3Ci!<+qnHdAWpQ8VwW?>J)r+$8g zPqiF^Po4b^pZCt+yuu)8U(S0oB03DoK;?>@yT62K^IKaSNmsDEb6JD3|#-ml&4=BiRL0zRMI zMygT)x-z>ANwdq4TRezMnh!Nn(n6TsXl;h3+guibfXO`tm$I7NBv5o`&rGw)rAd7O zhux%-hsFCe9LN11nN(a#IfuIHXi`PK1WgDr?aY{?;CE9J55P3?e*O!ert?Sme1C<% zd5`?ffovidS4tFNSKkS%G*D8Bm?>)+q^7vH4%7ld&sNL5?^u=tGOW5>wV z_gH$r$L&9^?pVB81Lq&iHTeEv33WLMn+DUcXqyJp{;1{n(PE12NBm9@A3?J&yDubA zIiK?ND$HCr_n=B_@#Y>BH8zX<-P@R=98;8Sm(!)HmnNR-6eR7jc( z(%c%GZieEtZYt!~h8VP=290JUJ63eyTA~BzHac({Om<{L0>2jj~M(lZUmA)@W!4oP=|j79KfjsC>a{gy?OJE-Nm>CVTlM=y?T?%;|EZ?bbh< zAm)fIFT0f$&6a!480Om(U=<4_IZkZ05(6}8B?iJj9@tFyC&1@#-UEL#Z@eOJn41hq zE5VSP8_y`(E)^2f#@6L;SMGfpk;`ysX|L5~?!#KRz#=&RWl3CnHu^+AzCu&o(mye= z?xhMWI`CiCsqQ782z1%Bz@wHS)V(xMkdo^%7y2_3>Ry^7es-%{Fob~xWT;z`%kUCP zsk^MEE_=Q|`*{Cl^XnE&AU(6DZb_a1khgBZbe>-t$n)Z%q%YXsDZoc4Cwy0jy8 zcaIXWlLfs5=Uy?b=W`jxo+v!;)%1%=s!m%pG{&`f+?zGOx0roG>$M;Huf2Od*68`O zqHFggV{x8uVAQXkJ*{efO=`U$2Ss+UXOC;Jr&mHu^}4>lwVr<|g!v~f^j{diIJ$RT z_QJlew7%xQfT0Zgw|z~`ee(l;`Zr=FUu*oT8~w$?(L2=hruvE(o;Md~?-1a{qj!v0 zoVhx8Q|2M^Zp^%1u9vHQHP(M{#;EBe&S3@0&mD+#7&(+@xjyF>^H_U$?%BJG}aFdqN5p4SeGP;bkKI8>Lq2F8dmvIMch5>rGn8+=1(_ z#;!4kSW7Kh**7C!+|g6fLN5y^9ugN2v@zoB-wgE}C8*Z>HQ$rYXS$`)tBthQUAEnR zJ6AE`NSBa{+u7sm{K^PD&ucFgOISYM6I*+!*ha8J)Wn5pM{3U3eA$bl&+nI1-EYyr z^IeN`->mtq#q2X$uU+S#zd#hbA<_Q$;Uh+(mdFHWE{w{HM%z1h&(Yv&u`p`D;5|`1 z*YrDItA5J15;J>W+P@?p_SE5%+0`hX<|URRpmS+NuRy3fViPnDQZEo84pPq-98Vy0 zrJ%iw5ZWt9`52+gM2JhDE)k)x5SlGQ-y`HhC_$`Ot`ea`28~NIC5@|>B#tYADh2L% zgVqtDiv^7azCwgNIRA)yNzkSlp(O~()IWldO#Sl+$<(uk%hdl1A({Gj5GuzJ!-h694!1(#>ztL;!@M6K*|a;#6%F5j8@{S7ge5$%5q=%lJF<_pEoDEx@>lF zS>e>`vI2ZPF)7_7;%}Gmr0)N_N$>W*oAk8*-K3}f?dqcn6!_aM6q|=X;V4E z^c4J|y$}%2q2sQMWuHC{21yLMtW&)7*sYN+9?b~XyzfJQ>R3&NlSLRSS=BmicIeBi zeHGP#kM428OngGlhdDO+5yK0RI&5^z#X521&=es>5YQCp1ioh(*XG0kAx#hx0|ZX$ z$F*V8qGWUzgiZkhr}pC7bO{jn-gaCYwmgc3>j2`~bPEuAYsY}V-t_bHMN0LRuN)3u z2y!-VpsLdJxi|LTbjN&1#P8EV;KLr>5H!6W_&)gi;OD~s8UAoK$-v-YvxdV0BjIyV z_;~o-3VQ@90MQd7#pxvcHZfy>FB1{!Vf%VH8F8ebxDa$(CqvwUh&kf zTGy@zTO1A?>C{!S3RX_LKRNFVqdkdsB1xi#wGq@unxECO5$HDt6O3n_`bQS!Xmrr*5%1YPPp}q)d@vQ-I{1n3Ur~d8*CRLN z%pF5==8hq^Sk@?Mc_>Sgh5i0Md#wTHHk&;+&Cg6e(nxB76Zv+Oq z8sVPR(*Np5HN2T89Uj#lGbc6VquSpkxk<@F$86N?ADUvmFrU!aYUlUGNw~;5exkp} zOw}EYnRM}}K3w(nhUSZZ>llw8KW57;;Z2HeYNH+6aoNyPU$~H+h z?t06`RuRbw=@>`t@V;V1-M?FeNXyZVIc9gOUcbKd^RUcC*(aU1rR$1zh|~)DpaCw* zFRd&xTI6$5yQXzbo-nHlP4tYS0$v{$)u4`e@l&O&AGns4YnS38#>&+q3|Did zT4JnRoOKLb>-)!^X&XpkSH(q)l?zKTLUN5(T*O$pSc?MJ8hh&$6dXOj<|!^>tXy2U z6N-xi#B{`1xj54p;7Z;1Y0tp5wkj@StX!?baP3!I#8|m#x&znR>799c;949?rX$A6 z#a>(}E|20O#>$24F>yWL>;1a}*J5v$juzX;)6wi3qRoW6h5Z7h_P~=1WJI*nqS)#7co{Yt|JX_S@Y{h#YK#j z>l6!@HNQ?)CYcy3SE7Z>nqL#b?h3mY$ zggc3lZkysF#>$ms;p+SBxbFg72NV}ERxTJ9ljeKQSP#3TU+V-mZg9j{x!4y8u~7co|@vn*T{%g;bj z)w!NiT*O$p&bDyv8pKgSo$Cw5MU0h;{jtD(-LQKm)U0#0WHSy&jFqbkC;_f@i|?oi zaP?GN#8|n`v2fLN=>BjlL{ zjFl_d!e!OQmx_xRD_4qz3qRoWYqevi296jjS1Kq09a^nTKgC6il`GA{Wwkbiii;R4 z7yE#LYgw%gb`TMc7%NwI3zyYy;PYX^5o6`*Vd1jg*Dl3HjFqdWh0A(hN3n|sM~syV zMLgtvbyi%&Sh;#zxU5!mxZ)zl%GJlhW!1)P#YK#j3r}#S6k6@!y^4z%D;J*kOk7rb zxJ_{pW92%}!ezDC2Nf4FR<83cT=)T}m)?%-Cc_b9<-(JwDTUTt9;CR4v2uAVT-IEk zskn#%m#=7!4^9|UTYD;{Ucxvcr={dFFUBq%OotXzWy7cZk$NTvT)H;y(N=8_a6PWLh_P}F6m$HoPI;p(Omo{fko7t0~#f35h_uVhZ)zZGp&HQWf@q9hL&*D^~UDY#gAT{wpS;F%UI8N~%xPXIudJkkiQQIbar$==eU(t?V) zz|-09Vl-$`E@m*Vb;acS*9Bh-HwH`+0DA6>Hm>!hy4GkR89>eatum{|#tJ!n4&t@S zulRO-@U`*;CLRF&zQ!7%Q&@=L#)@n4zN(6JJ8HkLall2n_!LiJ?WOJ_#6-E6 z82wt~j8K-k);Mu3bMA~6Tr6L7XJ0e;=U~Yb5EJG45ocZUcq3G)B##f04AT#;wm8#0 zb<8R61xucUm?*IZQx{dE0b*3ygX1h^{m?&4QE1>5BL-Kh? z3r4K~lA|m&w@7g5X})DFpPKDyo+>cr`c-5|zEMdo3Q997D$>K6OSfbAo_m8OPe+Wk z=1wytf2<@=3zA$cxO8Lm?@d=e6D)a#z#MPVMzJCJOgx>@6$eS432KxpyyOyrF-x9l zNUm0rX9h_w6-F47(4J;?i=teIOp-4)B)3y0=i(sARf0=T^VyDdkk(9E zT0I3-hU6Yfa#fJzYQfbWXS&o&2iz8%=2?h|a&>YAv{7wHu2Yh$gCyf|6kM$Q)IoLj zvde-c&k>k@kgS)X*@omDO7d(W89Qb2@lD_;Ifi>@cC%9W>lAiyl+$}M@+VudD3@*% zdY%3n2uvB>0L4X&wcWV{lqgp_oRLWFl8dj;2)>I;1;*U&Tw>fswUT^^xC?VzFi&u) z!lZS2JQ}9OURt0sT>V;HTF=vYM(AE8d0vp@%LNyoO~9y~@@5=v+AjGDfhjaezTA-9 zq75S9E)SAi18S6u&o6ZSZpd8`Ecr^rM7buLB-a>{$1BM-L6WZ$T;WSgt-zQ|%TqW&yjFsz#FkHVXE@I?e^h`idIcv$h z5!Ap~!OZrPdPp8~tM?CqF_)hkjl3A6B;RQ0r#j@dZW40z)@uBOPM-!}>t=z`kneg~ zy~zmOp(NiVu4T5FO9Yo*Qk;7-w+M{6_qD{3yk1FO5+wQ72qfPYB>7fDa_eId33qFd z4s{k zy5ZV#Lvqw{h=f}%B*Tv3qf~N(QA!qeEVUOxv<;GCF7x+;8s&$UCyL-KMZ`2qdDu&uaQ zG_6sxw9jb>(LPIx`M%H?AkBKcc%gdE_rX_RB`}9@)=LaluHhHmR(16UgYN4g#L7`e z;;QCun-?tkVS&lTed+QZGC~KG6rk6QGt>D;?2&~-Ao=(Hn>7GRzto?-5 zphme^J6N*ro^}^9*goXzyKLySAn_zb!o8qh9b3)H{ah(oTpfGOiWfA* z-W-xb8|+*xa+XS+(zT0K3zdH_v% zlq|Kuv|MUX%vWCrs#Ob0;E?e#`zj*`4SNb;+Kt253}h~|%?wYLdL!kX)i9 zZw``-<_eP8eo-4!qQ2Y_EP0#2(01!--fD!NRg$*`N!~8Fd`j}96ArBlmi#Y)c@vVG zBSg2|kQ|jL2%sb)ZRWD^IwEA*V4BZ;cr}VXL+1X^8v9oFuJefU*k|I!Q6Fo_z<@DA&0n z7W-F@|1nYOkc1mfmt{E{K**u}p)1Om^$(o~Yp^;=Dlt+{zM=#) zzY!F+VJc5e;|U*v8s(aRb8{TGzdhv>QyDu8BshT)p$=!uw+|%6T)#d-ytD}}gl;N$ z0B5GgT)&V#z|05WD1_)fGD4dmSyB?gXO_GZJWhQhEVUlkfXJj}Mg|)c8EkN5upyDbvLb_B z5E<;k$Y9u(*QWYw$YG!f8Y#}tOylRSZ zr(?T$2bKD!mgHlnlay2ss!lbw+~Rg8xU>3@*eIp4fO@MRTQ$9Wwoq|o(28=Hn+U~L zlt*$~B}G#s5m;F~ZF(d)W4D(2@29Xxl!JPdSzZvyWv3U-i9{;}#YJVl;;FI#)^p*h z#dC@ZBM^#9Pc13Wk0g~-%F9dgODd-4ME+vgHsw?XU;oBqigVK{x2)yFkrm`W!Crv%rObV|a zr>A>++9G@O_h6f=;?fFldU|rvoPweXUvYU^fH9;0aGiBTHwRvb9FdIor)^Q5UgBbG z9=*k7Q_DRbUWni{8&UvAq&iYlGCb+%J!WQj>WQ``T*_p!Y!Nb9BhqYSl?Es3VB3{P zXJqDP!}KJSGlb zHl601j?&`r>D!SRS*kn~$nWJkVsbME^1uH;akHi6vsfwWN6K5^dPK5l>2fR9@T^&) zaE3?bWn^GKGy(Kx6qZ-u(IN|*q2>F^E4?)2$wryY%k3{zkY80$T zVcMe2n3d6R!~OFURI6v-x&W@KS{ z3VLWGh1$J%l=Td>eH>amxfKzSB!xxl;=y}^XMayP1xBqB-rMt|RUtCtCTOOIE_)vpk!WyGE@da{e=(5VHiqXev zTt;M|1}a5+^Uy9dQk*ScWkcgFs;n%p43V!Ho(l%$WDOgd!N+;pw)F14^78cVCFKap z{4C9%Blcf*%uQvD(vz@x(`@uxJ)x`TxQwKv;oQx|Tqcq|85v_zl4ZR!3u#0y>9?vb z*Dy)egn2VcO3Dk^Q&q!H<1$!?all}By`!>HgZo*qHK}OzRhPu;9WZCksOk7DZKlza z!`DN-14d;y@iHQ0{|!dW)<>ar(+wErwawhN?uw^ZsLrG`f8Y)eV04(P>sBR1kJYfT zN$I@?8oKo6Ao2EskxW}GTBAnS3RE##VbPmtT!js^OQuGm5zT{aGN%>!|vX1cLeRSEq7HzYm(7W9n$i%D;&!5qZ=v)xEf{! z^d^f&D%F!EyW0VK*chS8a;kg^)m9o!Wm09DpdQv)i8x>7Zr6@Eh1(x$K5St9K-l`&uVHEr3 zV(zDWW^oZnrhV9&@FsXIG;@P0^Gl0{EK@29ENC8 zZ9=lIa_$tg*)x6lQ%Z`OTDZuls=1|2Di<4Wt0K_klBsIBpWR=ej&#{`^yaHQah;y$ zX`>stlOMYS-ofZVHL`(ZpF0b)jS$yF&jhk{Ko`bnBQQ=X2Lu~uZd9`)9yppbt@_YW zlM0mzXmY)(=Og(6zeeYMo*d9h@7CA`4tay|0=?5M2NoKa+xkdwlig{PXN7p8LLsN% zaNqiIvH*?#=z{2cna1P(b{|YIZ0!Ha=N+6XTPQwQXF240vmAS1Vbu1D>ut`DYGrKhE*1#Db;(ts=+7o>N`G#%Je zhL%sumg`Fb-$-8En{9hct{$^(Y~=7pa0?%diwy*u}|Pwy@^ zw@0U>dwO^7Z_f-@*D|h?Ixu5M#?YM1TzMIEV8n2HdUB+B$GCPxv`yfkLbCo`Mto+>J|O3 zD8Hy)D8hkjS>~>3VD)|HQ$!gL*^>QT(um#WL)65-OA15QzrRreL)5yzO$y!Trgra^ zXmTm3y}I}6k(`p!-9$tXo3!`n(IYW2HLZI}avI|%yN9~=yV^apVrcsOX4($5c;CD~ zI~S&3k7G?XLnh~rx4Z$sm~KV*szDBR`g%&@xc1(o#rHSA@4y(oNAQ5c@Hd?&KHlSm zTNwe4*Lg4qmmDOIxJM$yJrN=9nFw*uM~HhVLfk76;$Djowm7DtG? zF+$vu2ymNW=5M#-G>^ypE+<<8zRR5d4Bkk`LC1bxVtnpo^P8fie}SVKm~qeYmwZ1J z{lETpdEAWPUSQTJ9N#*1l9z}Jy$Q@dZfOC>_g#fN)4Rc>x5Uw7wWjsQLC1GJ1MQaF zk(%@b9Fu|ZDIBjWaHc($i8~R;LSR-X9Pbynb+R8DkQWd7qrj}S;#B`MfNKHVW?4bNrX5O{ zZsy0$z${g`Q2DzTxTlGGfn28iwaMel(O&}7id%rdF@K%P%RbP%0CVCRqU1ZvPUVm9 z^5!Uv0OAx%-WcEpy(Ce*el}rVNN0Jx-?_jQt(B-y@@66WR)q;CkGnV?{W3n& zx-PuD4v1c^FcKL$eQSYR^@>D=N*~MfPGEK`9FpOvKkmi$129n=!poyQ=nl*Xg$pH* z`#eklX3ncpo?#Dc<%RZYEijuEE|k0^M7#~m&##4-cLJjOZPc_eIOsyji$}y{U@A6A zTqyl<|C;+0Mk1Z{#|u3H+!Hj^aG~TyA?`m4BY-$LmFFKp{}Q;5wn$Vcd9*{^;mYhn z$?F8%iQ6PHl)N($oue?i%uw>Gfh*n~US3;7->ER+3#80RzErdw-C4o6&A^LOdspVQ^36cp1ek=`(1|U7T6SH6%M*k_I@QI)&et? zTTj5zE;-rLV$gjbYuYC`=t9XGiirKdoX0I6;EuuJB=1+yTVtz+*j)&~vA#Iv$3fih z8M`#?fA#N#0(_EBzAv ztFHx2;EelKJ7h5Cd>kJG)BYQY<8`Gxyuu|(;v9|hg}@9`IEaV-^nOkN$Z|POVRWif z`Rj(riU@F>fLq~&GwpK1>vX}f9k_!E%W~j!-8P`N{1zvZ6FAfEYK$6)<0KnSYnE); zyM#FEFCVyj6_$E&%8%8Eco3NUz2q|WUu^v_>iGd+9#S|%&$fEm54dN5*>A!*U6<|t z@4$G!=T$?OtCfhm5t!aT2$&Y?J_aIU05I3E0|ghVoYn&OJTUzZNSqs~?A0 zT1s3f{jr{3r!eAXadOIE?$`Pc;8qc|&laBt6E_M5GN;jdC*@ia38m=U*6H}>Q5h4+yS^VnNYY;>7#ub z2TXy&5$%*d$}0tC?lIxzvET5J!XPM|lRTP>M}b>)Y&oKyM;>4(!O^>yh``fCX}R|E48g$q^R`a#}5f%*3d^4g*7K|JK;cCe;T*aKU= z;Z1tY2oFygOJ;Sd063y zcDi4hjAwz_$OjC#Q2Jx~4l0ZQ;^ZXnT8N1`9p&_l@bZ`+uPRJ9dC3s73AkU*3@?xU zgR?q8FF5FUc1j=nYZn9a?pfjG(cU*dTVg1W&Pg82OB`_jRoHO)JH2!L@_GT12Heap z;nNq3>)x#}OdFk3`q+)UAGjsw)Gu$7!U$m@QZ2?sRwr=aCZXpTm-mnz-V=(h<0~dW4t9ageB<^~+ldNDJT|WWk0Db-$M)?qgua^p-fDo$mJ#A|?Yfp|8Yo zoW-gCTn_quz_ek52p38o3sMJQI-DO~9`hq#VT3@OoYKepEd(ywBjts<-;=@LLt(tyRxKPS7?3L|#i|y|R3Ztjb zseeV>9^eiuETuY?t6W6H4s~gH+48!f$`$M7B8Abf>m-lOnEK>B3fvj_;pIIHA$h<=Pmwt0w^MnJ zhrv4)m{fL<;X;k8@Hzfkg%LoUoaCJdF}DEsWKsC^wFmzf3KLEq%ikZsojxtRymSZ| zt1#i@O=kLl`+0hJd4nLNQ?W}c!$B9SUD%H3tANRw8D1Xib&bLZfjBwokN3L(xJOFD z%VYWbOku*wWBL0IxT3P~^5#Rxt-y3Bm$*>ng6fO zn4f?pg`D zmp+aQdWvBEl1tbl)cP% zVCLQvxUN(B_~oyMfcbc-#D%KAoR`d6hVe-pbkvKJJbtU{-1}Tw?FxxwKh!CGXCUG2 z?{{hGte|kT4^Hy-0{0m(+a8vjL^QkGixB9CSQ8$@3uMLSX!lNnEJ>z|^_+ z5-<-xE^&N5bdvWp?)MNdk3S`GY$u%3cM_t@P#FBrgqMd`yR?si@vfG*kov=QegdY$ z^Ag9iQ~IVO;&fmZzaVj;?zboSUk2u9g$pHb9wT0KY4g^Em-h`|j{=c-{8^~kO9tO4+KS?XisNuLOX+lj%O!% zoe)t6%oCd>E|mVpBKkkT^w}zLEknp#iHh?iFc-ZgahCdKvRAYRn}PX%+SiWoE~vYCw#!eRmhK?#H%6nKQ>1%la3URV?{Hei7mt*u)3rP{hLRjX*# z2C;zFw(f|E;*NqAH$YtS|NZ97-1pwidr3&r@BjHta^E@k%$d0}XU?2i?%bKESA5S^ z>2u5vod~{6%>z`qVDs6mAG5(%r+FcE=qbJfa?CSq1^xHnS@5bnH&i`;4G~-qp7J+@ zFQDA~@BxjoD}5f>fpmCA?1?#=;y6nL)Ie0*;bEPX>je;Pb{G#_IPR&I0P@f~>b zcF1!>l^f%`7(DlDzEJU{!{c%A?0Ku@_^4MWyd7qx;Gzo^AN6VkcnaTXIX*6H~={l>AOX_y@rAn&t}? z-x7Gd3!d>GwH)8&h;IdWqCOTrTVIMii)t1pO^3H~T)&Y7p8lV<93RW$9PpHDK5_@k z?;v=r0M8w}TaJ(NdjmXOKNG%C@!bfIc<|i+dCT#!UcLvOm_04W$L8-S@NC-Ka(ur* zeBXel?h7AZu>7+4{{o(?|KsBe)^5#5d|Sbjv`_e0FN4LG1n)`Usr;(-`2GN%Ce7DU ze5Zbm@y9nU$5(*#Tm+tXHD62dMSY8T%2cA<8v>aa+ z!p{ZI?=)Yi_-=*AP2d^zearEUKztS8xkvMbif9tBVG4=u-+iue|R=PJz?D!zH} zxEVZ$er!2DFX9{YQl3?lk7KUecmvHNyZo=0Oe8K7m`-zid!mUx=g)h`N1g+9|8{|=`!Nz9e}kp( z3D6V4vqSSyUxJm}I7Dz_uW+mIxR%q$dj2wae%5?!-&A~#^ih7v$A?=*xae9+-wN=g z^cKEQ>01Hs<>2{GAK?onKc;W~iQ(1;Ty!m^?|(6?i_-e73$g^lu#MxvO8eHTe|ZbM1P> zjA_UCYQgh~=4&aw9;b#|)B3j@-%`Z420UMCzLw%U`m}KCoB=JzcOK%q3_J%kU#R#d zAipOLM0pHqIX>Fm>%eowVBu>izMe5DP1l#eS=%n15kN5uyzZKv~ zW5W&?s@fuRi-nJJ4pzPwgT4ejpK3lkK1caxBbqLY!>!yB zi7!C^5QlLu0C@yF7cCV&$~jnmBjNENcpj+`zEJwY@zK!AaH|RzogJSezidD50MDD6 zkNF6eUyg_NgQv&&5?`qDeGMMHz_Yi?_gq__5r=WK8-1$7twlA$$9ckF`TYn5e-J$H z)CwQp&)f0&)eq+P(o4dv&A907eyk(EtRLNeh4R2f7pi<|@5{hbulYjdm-8D}gXf7l ziH~wt=@UJe!DrAB*`s+B0YBVVEip0i^zk_pCruomH*tDi&Wy1WvQBd6O&{x?l{;-z zN=9<>NkRN4&d8mXGh@m$_qg0KGtYES%AJ)vX%sof<&MvpIcdhEiDR-(Dyv>rSXt$D zQ1hnG8ar)Pf@wpCDwvs^EdE1N6dXQ0L&21E zfoaL$n|RV;mwicjVQEc~=cIN8F7TF?6&KEHV;s}Ron1X|c1d|r#q#QT%Z3d}&gqnp zb1Z12HDt&U&d<14Brl`N{l0l?O&t#YEOdMgU8qix2frlyO}!&cX6 zsW|t}rbpD`*|nNpQf?gw{vAkys}}rpDojQ?!x+DA3`3{F!4Kh%LAY08%pz5|^J?q| zCBWkejv;EB6jh=+#yTQCl|5GF)KS20_r&sItFKP)QPz3m3#z>n%e@)tGb+Z^6c>A{ zrW6-fd%P+clv1Lw7~knQ64eeKV+T)5H4Hj9Q~Dx0E8*6pDQ7Cf?#`VyZOSy21$spI zJjUnD$e9G2+BN=Kc5kdIPiX-TCAUtny2t-zjU*nsD=e>Y=S&|vaiUwD`dW=oh@~8n z!f_QfIHkuVL8b9{?b{1!_uVCdOk4lg*Sz%4F zb3N6VfbAN;T*-5CMNVNMc2dWF20{w6ra_7D`L^7KTeERsl1IhM5E05-Xngp!nBNSu z(8!=YvW^77_n_%HZa&MGA|??;r1B`6k*Net63W7tWGObCGRl+GFbh2sL<=X=tJ2*tgH(>jmme})Z@LG8iPKUCFk{deO5_dHlE}YxVOpIikHX1f4 zI{wDCJj6-?=iP1LWO76w(hy`tD?!HN*eo8pI<~Z;x~9s54J8n$v2`h#^8jEMqT@?~ zK14^UN`b=|NI4@N6(u_UWL-e|)|6LTDlAI0G8fIoXttbJ(Ix5#GF71#Ko^qS)xmTn z$?aL;ttuF^((9>qr({@3h(Cj>qq*5XEA@CiQx>t?2hs85M7%7Cjvo%2hjYIQNWkW@0G#u)Qfv0QZ#Lfxuy&0{C@--*qjg-6cN}TR%Xl`%8;z3OC zARPY7VpTVZ0|cBRdYu3{tFYxYWu7V=2wjR^F)|k@Al7uRNs)cp4oOo zqP8nha!RTs5$9hQRiI^59fQCsV=6rA%pfzWQ72ZT>IB}OBEq#}R|T3p8sqNh_*|G< zKYfNeW2hNeD8Y&S<{D_rVh@h&hN*#?lvgPI-fy(9S@O}bi;ic*Bsr}pF2*jK(eY2106d+z5WQk+ z8K_f3=trlPgG0~8;<+~)+34~>vtg@L>qU+dVvE|>D67K~E9D+-od}jE4GRu&cUpSu zWH20O7#wlv20$9BXHA8zUWqA|GTj=DLhuJnJ=NAXARjI37~8A`rk&HL#-kIp7_AEW zcr;RBAqvN~;HH(b394;oD>=vnRVGFYWHdZZ^r=BL6spA32VG5@Hy7H2)~_eR?=u;8 zPr(F|SGCrC0v={dZYtQ%GUaTV*pSVxNr1_dzW1{rXn)y*8Ekg|U@Z%md8JLD(nnyD zuN=n%ReI52TA8493z6HFOC}y6KZIVm$5d35y4lT85B|WYiqKKL*mYuW^qN2$1EDGt z++3K(z9b{iu|{f+{+1CyV4-qwaGsGpbhVP*Gi~UpNyANF1LxJ2dkacnFWeXjtXQd< zlShr7VXWe*f;ueMIy?qJzckSXmQj!zGl<<6$IobM5#p#Gsg0#M3cjLBm5UU&-9e;5 zZ$b7>Q?A7Y)nlh{1G=u-E)}8wTj;@jWJNi~ZqaIB?ar@&`Xk%b1;rk;wCqGhn<8`6 z?nNlr(bfQP#D(Cnr7yiCjK-tm`vs9PvWC$GtK53yiy1{R)#!3hfyYD)J5;(&hryQf z;fumzlNJ`(@ira57Gl#)+6nCl7|^8kXjcRQO&U9A#~7<%E3&aN78{3ijCU}jYV1U_ zw%bI3yt02i-c)^GC&_TA;m$5o@Xh`0ev}=6mHcK?zNQ%2W%SA17me0h%&SMo&o`-P zV<6K_WH+yuNufh|ZPhHTC|^9QEU9Q8x#% z&(|3dC7KRnCq@>kx0wOyxkf7;m}O-IN*v7&m>NY&k-ojuT;4o#l! z@tjvwQl2mWf@mf zR<_dZK}E9C5ziSR%AOS}G3a~;XU#5fbUd6RZB==cNI3X!FbOe3yYiwE)n3hnXPQwW zV-}S1`+C5KUk@$zMt?Fbd9Yq}3vr@!6A=6#XkhJj)s0@1>O%K4O6)L0DyOp%>}(@V z-*C3$4L;{MlP%o`Qs-kMVT7wKFY>4As>v z^&z_^s5v+jH74+*Z7;jm9f7$DqqS1?MRxV+mdn;EnnGVoZi$ z?oSNnE8uv{ZsN4TbX1vNlrcqxI~94_YkCL%1!y-wy5~vpL>i$w>LA0(sA!Vu;bV>l zy?@=kKM7$^4iQ%DoFt@Q2p&I!DDzS$8b;NkNp)lwSXqkr0G+k-A>EX7kd!k`#}3(W zFZOr?NBZsT?Ln3l(Zl|u1NANfZ(WwVWolWeV4khgz9ACRju~P$E?*fHbPi#BLLMHF zK_fs8&HiA-U$HD;e02)^?ll$7XCEDH!e}*sn2kvr(c-xURpokY$CM?T2xQ9J7OYkf zHq0EF_>KHjk#JD*catv6-YquM=>LGnd3dR#y9R~lp=(m@sq)Q(i+TJ7m`arW0%YbL zTPvrlNkiC<@@l{Abii2RrKtaGS~cGf)6A_l>Si~XRvE|>jD|P{^;*=Na>2Yo`-Z`e z&M0Syx?*-mYqS${4ep9!w^C9Sf12sZa7rALJTlN?P2_-MwCe5L9DFd^76EX2_Q`e! zw}-@h3v+J=q6runvl_27HQg8pbd9NPFt6G)OoruDwflUKkF!mdX{6gS>@!l7w_2*I zm{(kK6KdGR`O+wp5=WuheE^PJyN6)1^+Zf6JJr2gW3^R^`aUI4*fPV-SB@%AswNOK zeIfN2=sV{e#sp|=K*Pql!#t&MT(3}BQEhSR@-w4?Y^*SM?Dver?p`AeoRfImWVWQ) zYey>&{ui6KQYc}u6#9*-EjVTJn|JyG{W)4Y64B-OSMl>OS<5=dRSVK?`@a*Tl8FfL z0=O6=kg*-*aJ|1A*l7D?9jwLn`35NoB#h&fyNsF#vyw*j^?1o)_4*eozUI2TWV-o`D4!=o_kr={BR* z9MLI7Qv*cKB&cka<7$j0F4J&lr_nRDzjO%uV5qRzYc?qLS}w@FlrtKuO1W zstc=1Dlugoun25uvU>0TF>0w&WxGdzU27pzQ?RU478Ifk%Pa8el#_2OQRb!S4=z(n z+i+vCTL4dX6^5aHS9+JAyHr%R$TxZ@Y3*4%-yZ6g-ab~uWEn_ zmM>=aO*O?QAtv`sH2G<%Ud2+0l)A@K1T<0XEzCmXvW8BrwVY6b7bI1MOIG>>snSr^ zY8ukjJj3aBbYoBvRFr-(u}kYwF}1#KFH=d@gFd|5U6zuXsgiMDtI5bvBAkp8C@n22 zSq2fZMPLD`m2zI?&1KQkQ{q+l%(5;l4f@j9w53c%_*xAI%9m<&oRiKLwaXr;gtZF@f8iG z0uC-M#6lafhcZXSRnW@{-34Au0W88A+v=<=tc9LjA?sQ>X69mL2ZyY8ro@y0YrxT> zB}h$G8BI~yQY$@?QR?NDDx_1UIc%!}Oo`~_L@Jn1zxqOM%Tdp?x{YP*C0u5#S}L_{ zIcUr(&3Cny=Cl;Wx1lw@bW#3FeD<`g01Gd%iiyoNmEY~A`e&pgfz*;ST8k<*O$Fte zUH44erZ8x2t3l<3|EI9Ecq$48^JiE~Th13*>{VQf2pqOrP4_BG1SxUtcSu{r%1ryH z%_B9G)eJ8(q^8kU``2y`Ua8b&i`08EWPdOyBUB#rvus1vysRYn7s$$Eq~8 zUe{Keg;-7(zwA;@*U+ z&0A|{tghete#vXoAHwltihlX|WzU7JpPO~#y1x$i@`}elv8;b7`USfO^;rGWoYdv( z;?946)4iAghzn=@GkctT?z5*=9J;ma(3ex+J{9|6OjY#d_a1xGzz?rK?V;Nau1-nY zum_(tD*7W=KK108byIizb>+e8U;oKE58J9M`itRne(n=dHKSrzSkpZhd!NU)jS-B0 z^vTh4zdSPR-A^t!=U1=ZKB+IZcUAP;_ojR_=EZ%doZbE8XB#|2eur)16#b{Zk*hWh ze{bkjH|@A`{nsbmfNc&H{k$a;@~s(N?zt@Or~{8Ya_|7QPebL53#-idQ{jiN)sG)m z_1ntJ%b$J|+juGZ-#-0%;DBqQZkyca?k{p~PuYoWlN7z^h_1_5Tr&KN=X*|{c-i1j zKF2mSiaug()2~+Le_Fozgl)H5zu$!PC*s@9xUeJdi8$)HJ4%aA|I}T0+`Lbda4d(S z$8E{H^Q?(`&!08$nLpiJv{%8 zI~U)OTk$lul~eTFx7^y}^^EEFF8SA(Kg>A(iLY^-p`wpjaHwD2>h~wtELix#X_xFr z{G*|xDBps0kN13J<%f$_zFY9f+Ry)nV`3FO;_`p@J^r*FlP^5^d?(qj~hopMf4Kdi70vy4>)|CkK{Kdhu@?`n&?&>E&Yl zr`-7Q{f#f=Tvjsjv<*-GH3JoUuA;x+zxSD*%t6Eca-e?Y5&JLy0^6e~`kH6DO^Ez? z#Ib4De{of}b?;&Hu|v_H{c}T7#GU=FUh`D+_t7)|G6i~$Z@A;a7LNOB#O*)T&C5wB zJoVdt;n3%E6n*uq%HMr_aPfb_&t7}o{eR%s|2HW5uD{Ow@pAX=zu7VGlBP*h-}%I{ zK2Y?lWB332()vqZEqmkj0rNii*E`U|?u`E*=gs@^h1$z{JWyVL!s&xba`6UT(f@YZ z>mMIqc#1MWKWmfh%vEBdIr?#XPp>9h+5%{lg= zKmX%Tzri-JivH_mJs&*h)Z?CCIC%G^U-Zbh*|PR3diEW!Eh@RObkMygy_oVu&gG{; z&wDWbhNG7>+***`xPJG<}A8%|B_ zI`x&uN`CvdJ7Zr!!=~uZ{^`9Jmz90~dEUW>cQdzMjHdJvML+h7C;LwPes50q>}Ni> zrs-(Zqi+>`*BuMje09#k;m_E#2Xe~y^?Ft+JZ^fPCCd)nlE+b6$S757Q+AKx2^;|di0wyBp_6!mF%zx>PP zPyKqrk@wn zx!AJ!DlabV;HR!VS&^T<5k7fP*-s-+`mzPL_vU=I%9Q@$qoPR8oB+uz1T)Y(a*i&&9Q@DOZ|D*J8Spe zlkqOfHXe02F6@bCn%4ALzUKR@%C5P#_dT!OjcpLo{!TarKZRNRWLAALUaUSDFS9>O zUnZZ7<3n2elksKtC%^Lw^_*?{BTy3+?N5LTK4eMzBdA_piAg?h@sN`8()PzvR+d&& zUa`C*2|*%|kdDMqs9rj>KNI+9cWGH=M^c~?(2)r6$z4ieMOhgZ9k*Yls=UjqIwZ(t z_?Wx6xl;N}gj#`%Goe@cSXGBun8IhQm6zwlqZ)YT9Ij2)P z*6vhxMmjv55y^_qh@>;(kQv2}RGAfO$D;Nt#|rNIQ-bef+HH6W%L=?5=+iKCM+8tP z-&?mo{T&tnUey(2%cFJ+a7FR*s)EY)ho|8#sc3(Ad45X!BT&!pNExocr_h)-m9N^{ zpAJul6sc2^&{1Vv+0p8N*;VfC&~9Zc^OW&@ZM(y-FdIb_bYO(CqNAx`l_)J))c$O& z#P>HH>QvWMd)x)sBcmhLqOi(av}m!!aM&Gl8JTqC@z{w5tAINaLq`YPdO=zHi%~DD zX@3OJBkA3@KMFJt?GKDzy;|1O{`!b6238!kKLtpDtU7Fe6e}PCE)(fM4AN0*e*^(v z>UT((9UG+;sx=ku&&LY=f~zC7vP><^>PQSK6CH^_eYwz)2&A2r7!KPsLZ#JimmTP} zO8e509MHITaN?%AptM6Nzzb@%*JE`FwjHdfsVc;6c?CYN#Hu4Uen~Tu6O%lPDicQm zlvF12K0R?@;sQkgodmh5mYYoYj!JBIz{I4~H2svpDqvn--yZ<3k-6{Erq1BGgKuoCOeg#q8Xj2 zWR9qO=?tjTZEav}rRj{a5dH6rvIvaHPGqN)MQd?~kZ3z?n>>xXYpX`l&Puuwll{1% z#!Pp_-nFL0c$%chHX9vznnY!{CU)jBJFhok8woq|)Mk?7Chi^Xa&%trP|CnA@{S8w zZO-1|3`$}7;_?a9*2T_DYLMtb5-F#4imtb+efIM*P4(-94EkxG6tt~<_T$n5OmRC6 zheM0($UCL5bmW~;O&wAB(%E@3PqFI~VwdNo*kZ6Bn9?aqCDH#kqOub@wDZ)%PG|GT zL6HiQ(HW(zjfaT}k&B@G&9koCrh;_5uJMeCz*Z9nTlh%2|C?+pT8}Q4#Z!M{tezTk zS^os~ES8wXSTAb~i%G#FKUfrs4gTfAf>m`G5f&v|yuhxmC_r9Vq-$XztQw;$q|Yn8GhNgYH`ROd9d=*A`Q+z2%qPFZ_B;FSI5Q+IJw1JBdPe%N^vv|(Lz9Q1 z3Jy&hnm%;s(2SwOhGq^Oo{^l9l98H`mXV$@G$SKpSVm^X@L|crQii1tOBcbESI|7;{a^}uYvido|T)*T>3 zDIXF2??F4mA$rEiIPh(Rb-gWSh+ci&sy{pChpy%eWM^rZ#6X%TjU%k6_^S|2PkiK6 zQjLugq;Lj<AB9n|sI;oI00SM<02P5R1&7tV zetbjD$eCpeEgRy@&W68by@|^g8*@j;nBK+Z^C8uGUy&%`j}(RKiWxR zdf_fGG4u|`|0(EE_#)7+62tVn&FG86oDvmJ(PhuV@cy%w;`i(`ZJ7k7lI)D={8oNcQJOhk3ir z+6@+~?zu>9Q7B`PHd`@~Hul-De!`WYWJ$S?!)085jZn^Xv@J|K?|CKSqBH)qEjSTT z(O525diLD^!vUcKEXsm8RgPiMgyU*Xur%_VOfpL^Aoq^5?I!T zT_CL+t!c6^0+rTU)JCSk;SB%vb<1Xrse4P)sydrqLM% z5^k;0T0C9hFXAC4;vps#R%qM6FElDrUibQ$(X;An;%3+V99fl6A3h?irf1!kk#(CQ z>z<7St$Od;{odTz$HHSD8$NJrO-kL*VaqaN9~%=E``F4b5EAQt4qw&}1Td@&2O+lZ z=ZIwqAVkDIHZfx0rcDP=bk}VQTQGmKJFOAFPzR;9MNGJM%QQ6ggKFCYH1e`FUh42? z1&>s|!dK|q8@O}k*mPXW&dt8H{^#k+>r!E zYeRJQn&)f2ANZ`Vz!aT+aK{VKMbNw>eIfkEIRwrytkdkx9d9()3Mp{Ce`Cv*hen1a z;FGPAqv}BW+ZaBZg5>i}K0b$_c)tgbY1*p=7q0|22NYsbiHNzZr)*lI#+2aZe}+3% zM#q57*Myk|(U+q`I)4r4!y|D~LvO=1#vw3N$v3rI=YC$EQ z%vunUxq>%&_+V8z z)8IS1)(!A=3Y1|e&?9gy>Lh{2=_c2V6M zhZbNgAk&FmD3swCVhfO%2#}ad4c>%C6C$){r90-d#LPS$>ja&%v%LW{r%f4Y@9mj`Z&$XPQib`)QI><5esffuj@iT`KG#zoD#`QN(1Y}w!;K#qyoordPWJv*J z?Mkx+MN9-m%w@f(ePfi!gogUOGdFri<6ED-w`>1%<1XyF5vrw3+V{O!!s;e7vqemvMiX1t7b&rt+ zfW@n$2IY+Gvb;56o{C85j5<2&a25QV6F3aROmKSH+mbL#s#mB3d|Q!ccU^yJ>I(e~ zT{iBG<1?MYoB&}l9cKgf1)KzUvc6~9cu!%DwuMPdgh@<-)lH2+4b57ne4AYBB)|%YZr|#_#TQmE{XHsr_ZW1oK$&d^0rvNf7 z`C3k6Z8;GWIS~^%35{|RnwC@D!QrbT>KeP%?TQU9DRxZhLP_cZ_)TzBSB7B~% zmBvl5B}q&qNlXSzLTd!S&>+dWy=-XFwVz%;KWj%DttUfM5}RJDcxz;zdF6Fm z!t4GM{@GK8P^Af+#8ez!O}O3=PSOO%r8rI%!k!D&-8_9)R(nxz%Nseew)&KY3A<{) zU$DGi?L|$Nx0g0V$7n+o+c4p8wcmGH)^%NEpYc=nWYjf9t~$5&qF&Y$h~KK|qCo6p zFHM`;5ZOl$X*T5bf;`ZvtJ@N}E-$w3Kam@9W5=w^ZCXDwdc@3wvA;U_b5m1&ZoJi{B{ z?o6?9j@wwPi}6jGG&v;=Zy^H+sZK(QlaP#wG5;XL9ru~I_szRt#|SmCz%+Vs;hu+Y zAW|9GvgglPb2R}AIf#G4|{_3#-U zjKGfrCtn^hG|p4^GPoQ2q(YWZgqV1mEBcjG`}=U9cLa)r?g|u(J>R-pXzG_`M$5>K z$~&5VKL*#dln($>ryd4m+sk`C<`KZ*fR6*t0o({!0{8?VE&r2%^?=Zo+8Y6%0=x(C zX+X9$&jB(Gcy{f70RIm7E#Njln#Jb<9R7K&J5(K4Q zv6voWE-Mwktj{r4hQ?f~6=l7Tv6wDmE^7vUS=(dOFEN+p!7uB5j8&pBmsJCd79hr2 zsWHTd9=W9XOpUp$c{XjKkJc|at-_kOqF-|A3cl!u6|Lt`y8BX0Dsx(C>a=`S>UGcc zn!lNf$XJ69sr$m04*I8@v-kK2sLokthGE-&BCdzqU;(g5fO~s~p7mt?@4VV)Yd*Et zIHs9e<=>0i0gd7PTY${V+ggJbfls>b#H8&fCX*RLI|zQEp#Y}OsvnAbYj)Ec^}TSZ z7Z6)XvFdZ;ZCztz0}6n1y0cv09&RF+)$W*F_#gU@Za=!{*a zDiDXMQ>L=OcTT2 zf@|I&{3sWsvB3*WZ$(8=Ea%6oKVq1*# zia{qP2A!BoiG()ErqK)wjRs!$*ew%UsZCp9(^lEEbvErXn|7^DyV0iI zWz+7nX&Y_YQ#NgzO?%O%y=l|lv1xeWpwsuQO>38_=~CC!nPz03eAGq6sR2`HmX$gT(ADiYvMLUp4VI2n*; zAPJCWpdTR3z$t+22c8PZB=rYmQceS$0yqG0CgACSOwu4gCS@?-BETVli?u(?ryS3h zYE4Y4H8Gbp9KS*vr7@Q^(WbF4BYf;}2_O4%LSsWGv@)B<9+uE9vT5sWT7yly&ZgaD z)9$uu_uDk|Xmxz7%<^2-4eMT?r`8>88Gn>j_vPN%Ya3TZUEF`|^VLap2b)%%dvTY# z@Aog8@o@5hm)9Nb-ZH*vaKrc}tR846O0p0Vy*F3>RMm0Yur2)g@aO9fO>RgC+mII> z{>p$CYBwdX&y8L;Ijnx`+Qy4tS`}4yQM9#uo4a8=mmy65>wdKV19vR7o&aoG>Nsfze%H-mMH!$<5k&)`x+*-mehhpJzuhZU3q?WZ(-6emeI|b`;0(ZD1I_|`5O5A)Bj7oJ z?*pC-_%R@cCbjIh%?IRwZUG?W$9PzFoZ65IPE0B|F_)E$U!kRIOx{-IMWZKO(|ybM z7*wDAYoA|{x^Z!Faq)rAHXRDDe|FRE6CCMGH{cPMo}5as5@(jX#^nFs<#RJ>l?Y6KP_j^n+qs{CSi#D^MgKBdlJd9&{sLiZlk80vlXbH8s5|CP61;}Ql8W8VLEH7XVU=84S zz{>$A0A2vdUgs*n>3|mj&IVi!$X+P<*z8;a=mD$)To1Sw@Hc?J2K);kR*uv@4!9nW zWv~J88Nhl#%8l_ba~B}pU9D?1CQFV;b77lb@r|((G^Vt8Y10xgTSd3=H@|Lgx8*;xbx}9G2HPQ7Kbx(VH{rtwY`&XX5D(zW$B64`MeY zxYosO`Z;pK+Wi-QnO&dvZP9wgGZ%x#`n-K<|CDf;j*UXdYw-9eRe)D3EE}||6vo21 z5?F#Y3)pWIZ6PqWt5Ir|+Xm%(K4^li0LJz=!MX$(JJ`~A{90i*fOaXcD7D<29qiyU z7q5da8&@7tOhIn9ID-l(Vw8 zT4DVXu7aVSa5W$n`;V$@<2hILtk@hf3dH0H8a0HbDMF|x*7 zN{1ODMlB|nu=Tl(b-Ti1*Dxh@p2nY1hdu*pZLXh@6x}eUd;M8YrRiFA){h!vE-b~B z07NwT6kwvi$u>3=*!6f`l*K0c_rS<6?iNKKJ0W-M*@-+F%~O<>Sdut;RAO>gqUBK8 z{--4_FDUm`Cze-~4=(pC#;!NZJc)RJ=2`5isvZQgH_;k0WL}%LKBl!`5>D#!yJL}t zkdA(AwDQx?up<&9akf+f8u%z*QdC?#g&A? zMk+2hu4TCDaNUIKQC!<_$;9UD`itTk@|(6qcD2^NvLfj=rVV{%)laD35qsZPk#!%& zZs;Acu6Nd^FC))dxd+B;t9$-tHYx182OqbNW;Ad{#n}aAV~k`e$Wo#+{ujcwh%cro zfE~|UIOG3!>zP>G;$0&(>SbG_MsNB&a`MVOdK#7K z4y{p4HJy~P3~J(WPmN;awC;4qpWQt3IR^{jH0A5_XE!fQw{48)RENKFCgiv9cMfWp zCWfV@DISC$<$`FG)}%HMYTBerzJX1$c{Cu?MD3t9u;l6PL}~N>E_| zcd@x_k}sf5im2ZXTt9#jt;-Jwp?*7YO(w&qvFq}~Hgu15uZzZjnN}iDkBUGs?ken7yK4dctQiEL-S1Y2K6zttV|BE*L$jL4-b= z!z$osbAsy$)8y2Xd$pe22gtPEuk{3PD4{3Ufqa>D91g@5)(pmjeKRrjja^t$N zoCvIvgU=;DWRHops!zD&hg&ZVv#M8aoO{gUFO%~KaDwf#OBIv#{&!ufkGtfD+H0=0 zst0VWd-wRUWa=qQd$N3K7fQ)1)`_k|5pVf8L*=RDmBy#{HG$K9aA?kbZ#I$B&P;Po z=1qwz;;lUq5XOdt`AEODE`CEKC+8@~Eji&5K{R1 z+t>sf<1!5KEwQmG8)Jp}4%awb#n zV5^m9CfaUa?NJL|oo_`Mmv*(`cu{YUJ*sOKm3px$fEypU^RkZd`2~9P@_9%gJIGN! z9|Q?T)=yCn=o!E*5A~y&1fhMi6R8pcV`3AED#|@*^klq2J5Xc4Yini$R9B)_mjPu! z+0qCM2JY4Lov8Gb(I=z>`KH($lIzT0nfyJ0^kh5!GIj79tT(e z*bA@>5C_TCF4y#51D=5UD**cd{vPl|z}o;50q+Ft3wR&k$$*anCILPL*bfjU!8!%- zMZi-5{{=Vz@J+yhfbRl+fpmTX_#eQ1fL{R~0{j}V3-bC6U^L)&fShSK0C*hW_kc-& zhX79p`~i@Q6Mh2B0&D^t2N;IuOa=@GoCVkguo$o#AYbUX068&!1R(Xk2OxEr@}Y&^ z2wcAPCMMr+5_4HEz;~0PF<-=77IV_5XrF7$#iexC-xMtZzru2bC?Q-A!LZYdCpaj+DojR>rG!C zjkbz*N44n*d_Q58?5{0Z+_Y|LSj4*V^@ zl4M_EZuFL%ZfGLAA-fCQY5zQTH`C1pkzE00-i_l3(MtA|Z$x$y)T|3%Cd&-mKNLna zkj8Pfjoofz57-zxDZ4#MY!EPc8a138Yj7FIip!cnZJ=XqI1Z4!3Am1N z_;a12jLe0vhr_>tfpy&)3+y9(XX5`{`O6(^+ikd<4Kve3wvz!{9sRIj_6>jRhS}6^ zL}TX-sGeHmEGwth%+jTk;Z=i^WP=Q>{ocbKWMtYgjjVmWalcp7GEu8IA{+(C{>K@B zN%}q=a3Ss~6VmemvjNWm%mFL{91Bdf2ah?hqwXbZ+JQIq zD^vCP7`&$W-}lqcOR$F87ifb%qc5#-Kv76NtyECOV-9zfQQVnDV6O8^G}mH-aX^b}2J9!aNsUPk<4 z?TLxCCnnZjXtX6l(<{l39O?1Kj?DGOj2!6gI&!c#BCT;V&6u@0SaI})hre@vVYLFD z6RcRaNwza#5<&5Vw=sttBr_|A&eDa?`&TR7d7 z?PIa{T#6hsmiFiD|Awf@f`eg|h+hTdlp*gE0eMeRzJYKeN@5~PVlK62OK4ANKJ{)1 zZ%3n-4w+?^6QWYYuDuKldm=D-wINCiI}XC`4q-<_*pVX#*F=op^C4Dlc|BXAhHMxg zHeR#M0^2mOO$OUpD3kGP8ogs?*Z=Itk^q)CuyhAYG*}|nG}i2@-@;Go@jUZ6eRlq= z*(OQd-I(HF-nQY2QtS3u`F+!{MW7o;^Fv1+pkuWoZmv5N)#uO24s%xwEXU#Rob0$6 z{?1n|d?w?+3)l5)@S|Li$&PUzb!tP&1)gaIMI|emsfl0PfC@{SPm155hHH6P5$U)O z7VmG8Tg&$;F7;`NrV=oH&MN#m^o41DQ|k{7t5)wwcLI(9{Ug9!z)t}^fS&_0&OLzZ z0QUmk1^6W(%jRvAh)kFelL-@IF1728&<<%n=s$df=F*tUqG1sbe-Bcf8WmB zeRaeMr*?m`7Gzwyk$)`aV=Rrr`h}+tP!8 zoSZl|Qr>eM2Y43l4}m@x@CU&2w0}7u{Z|401p0cwp8>Db{#R*#mPrKo{t6fixD_xC za3^3-!2N)|04aOM$8z6=bcz8WCI*0*%VIxYXk4Ttw2?L~+onyjY56v-$fhl^Y5j%_ zSZobuJ%@Riig|fe1Dm#^A!9=E)+P7Hd|ml46yI?y#(Qk5j;o*fBVGp7^laMB74b1{ z)mvDgz7E5dJA_mQ&iqBGS8`GvsHW`P72z^&DiG3*@=)P9tR<}rt_d19{$Z%CW=frW z;~f5H!{5aA6|fg^jddtIpUJR!xNcm7ALW85e04#w$E_Bx7b|UNqKq>M!aZ6TGs;k( z3SoUZHJ)XejUYaa=a_^VuNSdXvB^Yd){m;>g zP$cHB4`2_#M8E-nNr1V4{Q#-hyr&F!&vbmL;<;91qIjgqR6Vg6s~3KS#m_05t_aE4*#zmHS<;YJ3n6HGuaevn;Xz*#zYP zz704Q@EgF1fRr`)D1>j2PHB3Gi3K3$vIgQ;Xq?v;+6bF=hE1Dc)8^Q;`kc7U)C+1} z5-#IJSIix318hGX>0jacBQBWIcmUg(FcF{})zc>H-7Tw23TdzLLEA{~qBcm8iRtq{ z6?L?b)k$Rq_#8=yiKDZ!+Oz{0_x6awll9&nev?PZc5);Sy&Vj`4Euw zj{qt4gOHSrG>OSblbFlet$kzE1eDO)D^2P_<^QBKt1&ujHZVgXv@;vzI%UcF)0!kd z)soz;CHa|_pH}Iu)}=lqhB_Ak!WPNW}~fH;PG2#7RuVDKv^xXq*k) zgcUsNqq&W9B9N7j<(dd>nNJaT9*IufYi&b@DzhdO!Sf%URTmb(b6?0A1`!FFYm@P zmpJOWzh18P>1FdN%@V!ELRMBaHcZ5*wxFu2V5KxV!Dwv|>Pnwb&6`DbUn->oBCGxq zk!ItROi_tYz0?~Y(wo9Wmfa~QwPu)@$dZ_B%_p>d;1^nbn7o9Yt86AdK1Fv#e8@oHN!0bMu=&vgarMY^N4V(7G$;c9@89! zdunIAEm2}3QDQFjag@+@X+D=#9~QLv;e-60Q-GJjbFM>xCJdfst!cji7kgUU=Z9UO zU*Q3MT_9&O!?ZXBc7hfdza?fG`7JR8hHsO#3KA265tIGQg!Yo=gTOY`tw@Ng3a=0T zdLjml{*HpQpied05KBI=kI==dI)y>#aB3e?&*uPohYRQ>aX*v+aJhs|fRT zK&Jlkym{RY?m&LQ{X8oPE1OJ7!KP3*Qtv3vc_a*`~HgdK4`>TYRX%}vTc;G2^y2RE}_Yo zGSOR6kyu)R-BO$-I}EW&$+Fw=iz(SEyovc=QL-QDlKohhYzm|(B}+_7mY9@ms-m%E ziAl+(DH=%Dko3q!CVF3bNJ0y1eusv-A2w<)^4lxl9F*z|pXwPXrHoVUUA1fOJ ziKi*&?8p2LRHt|thDqaf@V_b^bF{=g(5Ap0ZJi=xnw%p0qZZknT4dvqU=bNH5g9RA zwIZ}P5s%RP=NV*+BWEMZ@eWl>cOlNMcg{2z zKi1*SXmS6W(+wuAzwCUpp(5Xc0(8te@Y6YWenHh@OvKB(xdGJOe3>ail|g62sk_vp zhaA;?Fm#sv?9;XGo^9(cG0|OO*liBKLc=Bv3X{1A9DKH$`h_(K^Pi1YO8OISgAb(n z)_~4mm1%`&7QVv8#e&Wk`V2!JuE77%HUlzc<}iv`Sw$XAYRg=$pMf;HbaCRrosR*I z5o-;e+T0}g52l$ungpgX2^Za8AWq&t2FP?juEm=V(TQmwCgLR~yQ&NABk&8YOJY)%#ITVfq%O3D8gp48+C?e}9rQ;zXCLhEpkCxCKof=mQtSe> z0{UQ`QGjE4WKUZrPfqrU-?XFyK?66|MVb*a${f7-Ax1VlHxU zn;6i#YfRgt?%3qF=BT=rYF4G&hFl)}ur4xw{3RoOjiaO(hCErgPVb2y<;-kCZ$Wvr4CjRS|UnBXxKq6XxH1+9Ym;{vkol>b)2JQ zOc zCA&g<3j9K2V-be;RRhBg=Y18Q$23ucX=^Ta$cYA#JT!cRkvDOo!JTH|v$D)daD&@m z?ES2bSqZDGO^YXY1T*Z1(4~=*ODr?B}GgmMN9^VLVFJULhFd69zZNB9lGf+siRtw zR0m&~wpp^9*ahz#$yVEvB_@(3CUX)(32ZSPrn4 z6m2|yFIIfiZ>R1n2*a)AaKejdlm1PPc z1M_!SW7fobQ!3=&j!RAC;WF+7jnI#d zsz`&+dls4LnHhh6`w^jhMOCi`kMnpI#>qIaPR_bE4nNA7uHE6Ct*tw0erIc&hV2@} z>~?#Xpc_s_?@-_+m3RogrF!Z(@+gSedqlkK-QS6a3l4e znACe>ve%H%N>K(vW4-8xeg{`4wSCr*>7bI+{_^~y{f_eN0Xli8XG`qzG)nz{q&x=> zJiG!m&4L#~aSUl$&dIopqx@LTlwp!4rlWj$KNOI1MN6v68~f4e@+KzbO-wcw5ZW4) zkwi63#&&i)^n9X3OXHWjzu3@h!b zvs@`J&Yb#}>wJ_WWmpbKIaca&y%|KQ$Hb&uiMgywl!VZ{8dEbCbr;2{?ZLiZmS6AY z(HbLOtsY-LC86&7xT?tdu6x4kw?@3_chis_H{zS>Bstv)XFkL}(*rXc{wF`6#}_+( z#5YwR$l*q6=Hp^D9dbtfmVxS|226Lb({ch5;(Nbq*Le6`h>OlN=4>;GLkg<-ub?NK z@#p?E^6E#raAo3c`*V}A2tDu1YH*&zpPP(vX9+r*Ctl7DKhs2x<+x5VjkbQN(ZN1` zRu)gBbre`o6#!;rC3B9LJSKr5YH+#D91GfP|MRNZo=?*8 zn}cd`OVwMV$pp+Zr&%boc_hHyi3P1x#rpvvHtRt^Ha8CeW&{2ikn8JtzYy>*fJK0h z0W$7~0VzY?Gnuz5mEEW@`AnWPmpU+pSd4WMG(~7vX-u}U6dIZ%wN2ve`tR#!$Bp>9 zIy+E-v4^ss21o3J0{01_y52UZ?ieIBwCXxlld8+vD5@^6#klB9nNoGTDj%_k9`UyQ zsk+kV71dto@OP^2ckp-4*)mN`1J(Y&sk+#UvlaD4zrC~6HyfFuYe9XPZ>Rcx3$>%g zJOs#E{3GDWfIk7EwX}W)%+vQX0K+g_I0rBskX4`w{*)u{S%!Dn>Pt-2mzYZ_tb|xST8k_Lxrj?j9t;D2h6&jmXp~=v3L{4P&5yQilciRXLi&LXGDK^B*7!28! zqmiJa;b8iB&-UneM6umb-V8$?Eb6wV4Z@Fd(q;YyEZfIxgo)+VB}Hv{U7C#S>7q0( zUVS_oIKD2mC%dz?1PCY_mMtqgD>hvh{f$c$U;^&D0(osI%EVaPwrE>L;9_RA>HDOHu&ecX-ZaElMKSk2oz zwYtE}fSK`60MR#h%#Md~lpPBk;fhx z1x(CkaX2fqbsBS7v+B=}9+RfNvBnn`R2CGL1o@oKR1ZsSFT`%2pAEN7 zw*L$UW#Md&qa)NlhiW@V%81)J(nN1k1-(LJGVMs3%i=s0u^2Vx6&eaU@_(?PxlPz> z|JMpS=u7C%Ddcip$Q6Jr%^2$tR;ynkQ_%JTb6pZv?S3vU3oYw5?@Ez$#f+#DQ#l1@0QS# zP+~&cIPteh-8R$WaFQblmvO3MLf*UJGwXYmMvdmB41+iN>*q;f?sH&{w*&iF@qWB=(Gm0jC4qtyzDDe(s!)E zk8+~v?ulLx7J(Od)eH5+0j;ecG2?(gARb3IvDv7e&z*n=^VvpA-U*Xg%Xa~pp7#K0 zzu&VZL`)<^OqMwb?J3RYvL0&r15+a$=YZgHM3C(eju}MYS=L-L_Q#S6Z;|ii->6aY zDGOJ?wnadEe!y1*Mrr{>-{{G|@5S^u)e4*1)Pl_O#MM-YSr_>c5-ru1m^KBp(CkRI7(TyU-yyf3^Az>WVmRK#Pj1Jk`||#hvo~z~QaEnN?7#W+I#h zk?D0xmhWvSam-LEb*$7C_A^_u#6+^hWaW*}zC}2pQL?_3H)mh+Jq_gY;~FCWNtq1X z6ww&bXt!o+B~D)S)Zi;|W_~-(xf16T#IYLBPEf0EUdCM%mdBfwI8%YWq-eA7d$HnU zDLPH_0?=5|Ox<7!`>(_~2tQ{DGYokMKjUPqa@ug%D{(rfiBzv+nZV|*qf2=L<}BDj z!qlR2W+@LfC12ABnBT)$$#XjRxsoRZupi(#fc>>5eTfp0I!a75iI_{Rios_5puG)# zVlK6%)jmbr0~#@Df+Z}QU(wknDJ8$M`x73d?D1q*LT`XFhk89mB`F-1So{D%>hJCZE_{kk;t@r zEEe7bH`bJovxSQcw`!S$C_u^$TX(1y?mHBwC;~B21Y*)t78-lXLQ^KC`#_u>l^Yip zVqs~V&ZU7)qx}T@&vF=T^3ve-z;*8${3xeObX-Zbx1hYxld3xdgK97XbXN>Assif!twvAPGSwrFy*&KlG06z)+FCR2YjAoFvK7H$)6M3sq&aEVEGR%qBf%tP zK}^bmm?*l?sOUoL;6@{N;DOGa8fXKl99)~w>3d?Rt?$|(bH|n#&aNNRNC8uzNx10V zgaDcD9e_;xTUwwvuSN@$mwc;TA;*4pu|L=LZd*1#)i+VX$)>1Xy)lcSqFX-=A0^I7(7xbY3d+` zrW5P%i3XXfXzUnaR48z1x;eL??hkcRTP~ZG!aD7cgGV*L3<=`y1 z-n!sU0Hl0)au}P0UUtC|lY%2A1t&BXoX|LIz%eE`6={9mk85A4=`tcGZrKVRRk|{6 z#MbI10}qbazI+kS(6R=89r3gIda|K+7z#V~ndsS5r^}}#_1MO~``Z293>91Sw0zkf zn8Zf!U<{CBpNSv%Zo{e*n`TdISP&K%s^$e*rijrCRwZ(Gd;RGqwzyv~aMQU$&qX3+ z$=5t!-I1mQwKgvFGO+u=M}4DQ=-8Dw0+2NHL9Ht^Zu}ekUKRF&U%kVByYiPY6kjv` z+Tow3`YsY1M^zkFI}JS3#5DW~*MDUhm{K@X%kU68_jm<}Hm|c*evM_+a9sJtVf9M6 zwO4}C_^i-00_K~oFr`yU0^Bq#<6=tZ0J3{C7m#wD2Y3pg8!!v70B{=MBEZG^egj}J z?k@*i40sh_At2?-dp-ws14eA4#$;I-X|h^~Sd2R9PiVE!D50&5`(E7?4aBeKgxAd_Z7R}x$UX+Hdv!pdQ(iRvo}?R zWq3?~H6Zig)ywiu0#UlB#Kaa6ldTwqwh#P5(?bQeB01a+uiKW$FtuEZqIAw^QBCMV ziJ67&ta=Q?WWowq$8@%s-MJOjZIG_t_`pm^)F3(T$)4rv)h-(VRvmxy&vZLQew!Bg z9{`!3+qKAX0HhWs44?5jH7@3wwo zT*S5!|611dp|Ay1{M1GTOu>vpgvOcaHUEMkZmwaP(fIqHvO}BsIIe0(KY($Pe*~_y zPA|9+tKUolVKy;)M6>Bvc4qaPz1~|j+$^{WxQt`ES#YcqW{&(XC@4n#7$Bz%p8!k; zd=fAd@Nq!qllQb?gH(aik`j}*@5Ef{2{-RPCJY|cm3+Pt>Y8e!`Koz%))s}SV-3wcRWNdL7kY3RXxC%W>&&A zxQrXG5or;nePt(;yrj`~(;0u3wR~$JQ_IXRo$=?1N?r6F+h;CCp)>xs^x_?*BD0n+ z0y;;eOcT>E23JO>>&lFhqUKvxOM>vcV47lP##o``hWHX8;M1a_MvaOFF%Xa?C_zbZ z3noAS7l=TDfNW*~w1UwDB|KC2rEZm~b+1~NQnkvW35p9Stys0iYFj8&(Yl~e`G3FX z%-nbHeJ_ZZTK)ZYw}@mX z%BMGyZWct?qkY7toZ#%M_@jN;1gv9z1j`LeR_d5PMW)>H-Et$QD&17(*pTw?O!oMn^`5Yma&WI@muex;M~2=Cp*~ zED8N3w0ih3!&#JxaZ^qUg?D37=9yLPqwT2+aWq8n9DT+6L>boyRZ;g?_Y!OvX#R`v zykgtpR;*G*MRk_C#QJn0estEKVmn!Ub?7ovyMF6q}biz#W;mvPtobuk;0jd2g7op zRHBc8OZgTUDgpC=^_2D1mPJ{Ls@5X`nLVQbDSJi(9twCm;NgI00OkOW0py(USirG> z<$yB)#{pIWjt87&=zIt1b%xH5D3Er*?tz$g55&UGQ7Ap!{t6lwgAohMPU7Q*#%0&U z!p1rjzB4>~p_)6YQvXbUpxN`ad*w)gcI^Ln~q`r-51mALNl&yH-FKu%|ao>X3i!?$FlY= z2zeT`;DK4>VHm>g0d>MPFzC@N?pd`eb@`@v$6-|m-@)2FdIkx3B6U5dG+K2!AY|F? z(0LbiKv z(iZX{F0*lISRKet2SDo0nShLKGy-d5BBq&5Os`5%+A0$+ET{Li49di_BLAk$t8 z$c!E1W-KwySYlc`mB!ksG-C*gHjiqWBeyMQ7Bsw8`$bMm38n^&EnjT|S>WN0@0dlP z0u<|xG>EOblq-~_Ddu-@z~5^TU^pvQEWcN^{0RQ9;1{%>@}1;848N?l?t^xGCV)+* z_C?>=w4Qjjhu;${<=?@g%{+Vxkl*>Vv2c%H_qRVE%7<(>(;rkiF@`P@?OYK#w~xX%|O|njJ1d^sK=j>ppePKgj3Ib z)GcJya21D-P(u!c2F)xB;R*jVu%%B=T<`Gw!va!x` z%Z!+o8L_a#^%P2@kx*&U*S4~;Il5x?h9|jAAZPX1{8iN{c}q4XhiLzW2@#WT-iAGx zDKYNrrq;4eINR`pQ)^u09o+fsomwmDX5XX@{|B))s(eV*jM?QiGveB`&4rk5=BW&} zO?!rsF=gyTn+<@>A65`n6e}0Mgo@4Bw*qzn{0guq;C8@%fJv~?-bs zm`>pl({tXG#w7l~paFrChQZB#q9aGuRf zGanH%AhgAZi<>S@j61YIpflb%3xsD=W`e4dXj=)sF(_>K-8(WuKr3*K5bQOygCM5D zhFI8n7ojc|+TRQomN#7@w9h~z7IqFrjZ$8oXs^5lE^V+&llr!kn+;gvbU~Hk4$y+9 zSaXz)goqXU-UcAzj7niQ8+>|kBu6+{q_3i(y%PggNs=Rs#SHjc-a;CDj6+|D#H4MXsI&`oTDJMTFKIaB8$6fF#bmbW_ojxHJmY9{s&09+2 zl3JxvlTg~(F0I0)MVGb|$Wo1#0@hro*-32wLN56n?Oz;rutu=d{*2%Kfl?z6!*C?< z3_np_TS#MG3;nJ3(8tvdo4Q!v?pd1?>&SCs;b6hbLtiv(ftXRkI?h44#yIM*Q zWi6OCb<%V@9ON&%mB+WoAhX^yU)`ssc9+Fa!Pf^E@zWquNX6_491gnoV)Wn z78%|nMTR$VXQ9vWR2w@d%Od>?eh&nSlyNc+_V{gX(wx`UWy;E_F2Q=MgwmVe7c`W8 zgd*fOe+ zN@KsMG?TMcnXqJVQ6X1*%39j!QvWlvl)YUxe%2jfkk+#Mm++qvXawY8ve|&zJiB*p zeSaXcRWU3;daPp_S&`Yp^fJU!likArAq$-0fL!0jXMPKxDXSK_*-uQfpO|L9(wO~9 zqq0|+#`~tDC35BTFq}3#OvM(Lmau!@AKWn^<<0*r_|l~*h*JYwKo2gu%>oS(LWH9% z+q$~bI=>U0gJc~sITcoTep@jhzi+6q%Kr*P zZ4$(^Oo-|AF-qh91*M@(rfi=CcBf(y|CiKn>Vh2@g6BP7(p30K#T}$KR&I`d(Kwd{ zh}{;ibg2L8t63@0%^MGomPZ!ff8Txgeg608%GDcI|14z#=>p+D`s`#{UDt@_k+~z)>xRfaadFFdK^u#wxy6Y#;jwKlr@#D#nA+7 zNfj@qp?Fhc;rj(hRZ0EQ&dr6}lEnw{EM~CfQKYo?{pgsC`ES+iThGI%%~96FF{k9- z7?>eG>Cp~uV&K`_&S`AdI6Kl~7DtLc{JlmoFZB~hL1h#b(mJg6N%q*~u9gMo%x@5GQ z{vB7K26HTw>1KpnjBFE=L2E@4 zQvjO)8v#G~@T)p*#p3g0fL8$i7Vs)Sw%6+c-vPW4@O{9a1AYZ~6Cl)e)naGTPiBeK()j?ajmye4nOdVGoOk#aT=qk!dJrwD2Z zb|WB)RM{(cgU|{<^ST1>18`KT?Ic+UCUF)XyxTSVpn{1*YT_KjkdQAgZ!OOqDHSI+dn0PNgXg1)pfV{#jvKl3#0p&QP&|V&H2pVF#&(?3TyWGPvN&9Fpy!KjH5q) zZQTo>T|Hsk)Nxf=6_ryfYbH-W2ME^E*Yc9^!{Zce`&F%5U)VICmvWh7FdcD|CadO$ zN5`bG9JYQn%eQ8}D3ZUtx-%Bkm*@^9Om(l^Z^_ut*PcmjuWoLJQ!})FYi9LHqoVUN z^Z$a`vaR)7GOPA)WrGvm0);TP#VPLvZgR?BSssgX{#&(sG>*+=EU?m|)cvnyiFboE zN|l9|M+io{1LbIhW1Gn|z&VWD7w05Hud2S8((@dLe z^u+4^SV51MJ2vY=MSG%*c?J=?lI$*f#l#bLEj7r*wiSKq)?Os{@BrQdL&BI9L) zEFV!dd79XGX~3Z4qI&#RgMzF=@Km zekCwnZBI;B+rK0kN4nE!Ff3PfX?MCb$UoEe(8%gv*q*Z@f8}g%6U1n3 z?x>~#o$I#;n&!|*{;So!OGZUsS&wu&*wZoswgbd63UWxtBF z+xgpT*Ps#d{+IUA)beKRtZ&BL23j}S5tZiC75Ji7*$8x4_wdBXNd34A#TaK)I5WBVKm$id)g zfCm8%11ts{0XPP*3~(CYD8Taov5vTo>0`Ld44oqi(yuV|8_YAU0OV(VApfrno%yyJ zElj6%h-o_|7IwO$bYBx%PlG{22ll$qxa5kMF3VgaG%njC7Iv-yrtwk9*7)vlX?MG{ zr(N0-m!|qmbYv!W{HEo<(czNa5G9U{8y+2cZl#=$*d-a!E7X+frJ?v3)#63~(|&_; zL20vH+CpI3m#hJ%J1D;ZM(aUD_Sh;`fM@l6+{N}oLsJ^Ws=*#{u}v8vUf97A*p_{HqW{Jl%*_ksW4kRm!8e{h#(2K<8uF)&RK z$qr$1TkDKw-hM|~BXTxi1?!g=N9h+w=^ICh>&2}3OL{Th*Jt}MAq>^qqS+OBCJv~2 zGWR6Nuo+-tU)b4Fv@fJl&L!E+{&v@zMy@LBF!0gY4w8O!_W3n^lzpSL%^ioDNB38x ziqDS*p7$~3YyD~C_J)5b@chrf^MR)RSQYwXFtgrU$2!3NnUhhy41FF}z_ET@1W5YD zfZYKv0qg--56H1^1K_cM^8vZS?ovSZ-${9E^UrWYj9}`T-voR?M9dO zfJ=MWrHSsNORTDPy!c|waw^vx1;@q)gYjftH-k_P(^1wEx4*-Ls?S7&D{CJD?Sg=A z&p63{Bz^<)@lTvx|3>r5jPu*(DA@Q-3-&u4Ig!N5HaQ8_cU4=iO%@>28(f_TyFwk~ zLL05)cN73p5B@9amae8CrnVhoVeab_-*hKpFg@L(EG>F`CRW6KMAa;CP{No@9F(ve z>gd{5$D|z^IBafxTzY^zE`_p%p=s4(%Ibc{N2-pDhBtP_0Q7@I1JDf502Bw$z1XiP z0tHnRB`BoBOQHORR@j+I)jBY|?cf{Ug3mi}&5+}zw1elErx&VgsvL=+$_B-rDj>sw zDUAbHrA-E=3dmAms%)?TKE{#d}IE>!E7lCH#nGOnwSQ{m)PFKwb8C}+c&tIxNq=KhrY)IhP!=x zw>G*Bbo6=65!A= z*P*RBS%6eOphngm2zUr!SHNsQHr7J{+1a9_mT9-HfHio|0lWl|&({KW2fPvRXuw+x z{Z8{tBNfB10PF_H&X(cdHva1j{U3(D(a@Pc{}3Uu*kIbpk*0&?^}x~{4wi}OV0nYk zP5_OV4wnBZG!B-Dg`IK0HVTd19kH;(E}b!_JHIzr*m=RFz3kH7bZMMW)3kiz(zduX zbSw}fI7I8C`LETS9>o|cHh{`sRW-!(2s3nOOa7O$@<{s$#*D=or8%pHjWiZ9-7^a! zMyT;*vB1F`myy5<*P&q{a;{ZF+`a*UceV_WkA&=^u=_YB?9OaPEj0(noXPPK&IFN_ z6V1bi!E6v(W!Fu3#oL+I5~m^gbf%4@$P}nrznO^sFhZgX*#pJN|uFP{#dyVcu`KREX30{)a4=wrd7faN&jIWYI!EI9fD}*10X_y;0Qih~UJZBxp4R{} z9*QG|TW6l%2W0rq00#lKL%JBACk`<@>jml5O-SFz(3u6BkyzEqiK)0ErsC=&p;25B zQ*rgN&?v5mskr*L&?v5mg`I1GX?!;tEbP!4ue5ty8f|+@TjJ7;ew$!ZzRpWhxTMJB zH#uXPZ3Vu@y2A`Y#egno^*%t!qBsy`OR_UhtnJVn#94l?72zZJJb_=ZrSP5PJs7{| zzN406Te@nz+@|YUbs1OfbxMdMTCWDobh8#CGu>sULr_cj?I!{9drk&qZP|iA?HqQS z#B@70Fo5Tov2N@Zii*dwM-09iyu!>#Z9OX^(e)-Gk=(N7VmC=6i9R_Sh0x=c6I}#@Ja(@ zG4Bq@Z%hYdasLN_w77|BaT5zWEM%n>7|c#^XUJ$LO^(vu>OUH;Ff(VX9u1fOQSE_K zwuiRbX|>@~aJ<`kywT2{WjJv&ahN1;sqV^2a?6E{L>Tl;(m~Il2o2^O%2;*aA5;fm z-u6wt1;#$jqe3f7?fwO?E?`vw%+bXSb(m#3)ae2&Hq?O(Mx`ADnqnh>sV;B^Fx3yH z0aIPzDPXPZ0vq5<$6}xhO0aj8?D_}i?Wn5KS$^+Ohx@x;7vGqFaHzvG5rPtqX`+N9 zZ2O^3HSgVtYXvs_kZ^UudAq*3fv&%Aa3Zg-o}}avigw;^S4K9R6Q{HK!DxN-=?AL} zjez;YrpMmoITGOJ8p+Dbdmy>w@}4Zfi}8E};3a@LfDM301I`C50*nHl40t&p?fRDj z&H-Ei*kqo60myK705Tl)J%)S8JU`)WX_#QAAE)DH9=t6bU|mxkV@ z6jOdOURhFeDo&c@^jmVYeg4v_<8&rY=G-_|`67SItRua&vdFL;ZawEgKO;*@t?(Jk z_0^dUMhNiBU+ouP%Vf-AZ8pV``d2Z5nDa&cm;NclsOvO3QsC?$FvX8yj?m&?hQ zTnHZ85?U478d^Qd9)5}FaB08`IF=MvukDU8Q8$c>%;e5qLyVc+A9s+4dVl1oA}Ja|yyV49c)LRpatVDE1E z)+;2uGfw<4>-?fNFyquCZZ@fB+#FQTp1~QXo;`w=C99N*;*w~_i2<0^zQI}q1mUoQ zwe*hL+?Cuqku=48h850N1)f{Xvz-{C8cb)yS23&M=qrrZYDgLgUO0F`c>DLujKwBc?Mq?S;mf z8)9MSEnxZ%T$3wU*x{U&(l~3S@7?Osw!5_SWE-x7!NLybrGzWgm96)~0`GBk|dm=-0Wil~cnM_O%3RT)R z6HW#V!EImz7Qxrad%m%7^YD?ejbP}7^4^Mm)L6T?vGD1}F-y?7^_jF1Aty2Tlu%Rg ziUng@WDvnBtmNp5#<|-NSjZ(!#p>TuNa?Ztv*k%OX`R;j`qmUtLYsrTb$psrb84F7e5Vs zM7cOT#$=4`XR+YO(3`vD=hd$CYz@QCu;R^mFUz~ou`Y+4a>IgLkZc;P|Fik$}R772%_;`Xny z!Ji0v8h&*1&;cHa#>F(Up>zS$?#XtSkAI`r!0eM}OrEZ%B~E^S7nN>4tW{j_$Sa8ma8Rtx`EGRgA(C9(O|KPtX zx8(T2C4+W3tMUr4AFqSAD%4J&jm@qTYp3HZ(VFamKURmh2Jn5Z=50_NvU5d7JOUZA zPf`cB%cLBkTsabuwy5(ONTEw`;z|M$qDv4G3lYB`Z`x>!<3NH7mfIpu-I!$VfToDG zE~d(7UaT8QH>1DX8;UJAl|CRi*H5K(h0N`rCC4ewn)IA3X#kh`I{T~3~$IHcK10>8CG6ll;IQ8*1 zAg5~n49L2&4v-nt8U2oKc+3K(8y<;;ogq*Q*(;?xrx+~kT!?3Kq>IK+4CjsRroC*s zbA`chKM}e$4cEnB2v@kIeqB-ZFIcOWgZgIOKak1Hv7(IDg+}=bgU)l>F z22A_eTo>yN>=2|TRkldofbWYqC!AP#!YNr3$4#DES0IM6c-u&12` zFy;hW2%w=cSxqz1K-{*RoTHFc#o=NcG0W;akP9; zXS_spBsL<|b2vQXqV$M!H85R7MMK&}s1b<=1gwiJE0!|dThMd78`>K|yUg9q9Mp5L ziD0^JJ}W30H2B-^ZAT=zWfNyq%^p`(QEsoQDX$rKPC*a$vT)SBZbuo<3oPN{cd&jD z-rj(J;@W7C68lVZ2%0YAV!l}iX=9w-1^>1YSpJFL-oceFz4M^4dh|%M2Oi4ecbd28 zvRWBs$u9HO?uqA;S$_J{s5ZW9;W-#P+vErV%Y{;g#-|Y^z+I87o6oNWJOku5`IA~C(YkiO~8W)m*#oQ>L} z;VKLkcDP^QNC`)S12LYU6lsnSS#35E{S=`Gk`V0nT; zO4_6FzHXi7vJ|YLwn7HXaXV|fgGNU`I@%hD+aEgyI_n=?sks7v4S{CPI2oQQ)O>z` zIBn*!eN}Cvru6SGJ8Nge-y&yI?6}qm&!LmnSm;~A8MICCJGLMi$ZB`~dX1xYIjRQy zKFn}P_3n>wx`LCKuHYmVcDkZymDbH*Vw=DWLt6C2lxQaUFzhwTY{Zm7Q*j!Oi`mv# zwrxGL45u2FbI5%#aCZE$&S5aUjkCFJI|r5^TRRv8a&C#Z^*=ca4?T=hP6QFl|Mst6J|`CIb(X|^cq;FL1xNgnjj5Fd^d~6 z=z^}*G}p!r$TU*n^Ony0C=I^$Z-7ku-vJr>KoGTbh-v8%!+LJSptLlD>H6Bjw0Mi1 zuFYcnpW>H|pLMpAp&#A<-eQ+{d8ek1|J&ALw~w*dVNHG=%MN>TB;N-kL)2nNOf7cA z)MBSJs$)unTr+!Vv1vBAOmMA#nIKo%<-hJ?ibH^Z7`feK*g~mB~ zVmc>(iqJSGPYgE;0aIQMFqM}YmC|l^X)-&K$<@KKm7%26e`?4u+|6hX8K3_ zFH4Y4?U0FShfFLi^8-q|9A%+2qwwy;!cA7Mm{_d9o2)y`AP68XC>9S0_<#QwZYCCc zR%|Ei;^Tx`Y-OLfB$-#il3WDQz`VNykP7LYMpTr6s4Mx1=}JCgx^Pozw2di^&Alwb z>$EeYALV~pJ6L+yl&CCUVSinihNUVgc`s~C&RM~|@9tK3T`r⋘$k6yW=g1aSX>) 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 z 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