auser-poolparty 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION.yml +1 -1
- data/examples/monitored_cloud.rb +1 -1
- data/examples/thrift/thrift_example.rb +1 -1
- data/lib/proto/command_interface_handler.rb +1 -1
- data/vendor/gems/thrift/CHANGES +35 -0
- data/vendor/gems/thrift/CONTRIBUTORS +77 -0
- data/vendor/gems/thrift/DISCLAIMER +6 -0
- data/vendor/gems/thrift/LICENSE +202 -0
- data/vendor/gems/thrift/Makefile.am +28 -0
- data/vendor/gems/thrift/NEWS +79 -0
- data/vendor/gems/thrift/NOTICE +26 -0
- data/vendor/gems/thrift/README +137 -0
- data/vendor/gems/thrift/aclocal/ax_boost_base.m4 +198 -0
- data/vendor/gems/thrift/aclocal/ax_javac_and_java.m4 +107 -0
- data/vendor/gems/thrift/aclocal/ax_lib_event.m4 +194 -0
- data/vendor/gems/thrift/aclocal/ax_lib_zlib.m4 +173 -0
- data/vendor/gems/thrift/aclocal/ax_signed_right_shift.m4 +127 -0
- data/vendor/gems/thrift/aclocal/ax_thrift_internal.m4 +39 -0
- data/vendor/gems/thrift/bootstrap.sh +35 -0
- data/vendor/gems/thrift/cleanup.sh +58 -0
- data/vendor/gems/thrift/compiler/cpp/Makefile.am +136 -0
- data/vendor/gems/thrift/compiler/cpp/README +39 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_cocoa_generator.cc +2331 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_cpp_generator.cc +3003 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_csharp_generator.cc +1700 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_erl_generator.cc +932 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.cc +173 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.h +321 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_hs_generator.cc +1445 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_html_generator.cc +637 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_java_generator.cc +3069 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_ocaml_generator.cc +1673 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_oop_generator.h +77 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_perl_generator.cc +1812 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_php_generator.cc +2281 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_py_generator.cc +2310 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_rb_generator.cc +1114 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_st_generator.cc +1071 -0
- data/vendor/gems/thrift/compiler/cpp/src/generate/t_xsd_generator.cc +354 -0
- data/vendor/gems/thrift/compiler/cpp/src/globals.h +117 -0
- data/vendor/gems/thrift/compiler/cpp/src/main.cc +1207 -0
- data/vendor/gems/thrift/compiler/cpp/src/main.h +103 -0
- data/vendor/gems/thrift/compiler/cpp/src/md5.c +381 -0
- data/vendor/gems/thrift/compiler/cpp/src/md5.h +91 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_base_type.h +137 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_const.h +59 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_const_value.h +121 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_container.h +56 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_doc.h +51 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum.h +59 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum_value.h +64 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_field.h +150 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_function.h +93 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_list.h +56 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_map.h +64 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_program.h +223 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_scope.h +86 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_service.h +68 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_set.h +55 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_struct.h +127 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_type.h +176 -0
- data/vendor/gems/thrift/compiler/cpp/src/parse/t_typedef.h +70 -0
- data/vendor/gems/thrift/compiler/cpp/src/platform.h +36 -0
- data/vendor/gems/thrift/compiler/cpp/src/thriftl.ll +303 -0
- data/vendor/gems/thrift/compiler/cpp/src/thrifty.yy +1140 -0
- data/vendor/gems/thrift/configure.ac +255 -0
- data/vendor/gems/thrift/contrib/fb303/LICENSE +16 -0
- data/vendor/gems/thrift/contrib/fb303/Makefile.am +31 -0
- data/vendor/gems/thrift/contrib/fb303/README +37 -0
- data/vendor/gems/thrift/contrib/fb303/acinclude.m4 +258 -0
- data/vendor/gems/thrift/contrib/fb303/aclocal/ax_boost_base.m4 +198 -0
- data/vendor/gems/thrift/contrib/fb303/bootstrap.sh +26 -0
- data/vendor/gems/thrift/contrib/fb303/configure.ac +115 -0
- data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.cpp +124 -0
- data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.h +103 -0
- data/vendor/gems/thrift/contrib/fb303/cpp/Makefile.am +84 -0
- data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.cpp +481 -0
- data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.h +215 -0
- data/vendor/gems/thrift/contrib/fb303/global_footer.mk +21 -0
- data/vendor/gems/thrift/contrib/fb303/global_header.mk +38 -0
- data/vendor/gems/thrift/contrib/fb303/if/fb303.thrift +112 -0
- data/vendor/gems/thrift/contrib/fb303/java/FacebookBase.java +103 -0
- data/vendor/gems/thrift/contrib/fb303/java/build.xml +84 -0
- data/vendor/gems/thrift/contrib/fb303/php/FacebookBase.php +89 -0
- data/vendor/gems/thrift/contrib/fb303/py/Makefile.am +44 -0
- data/vendor/gems/thrift/contrib/fb303/py/fb303/FacebookBase.py +82 -0
- data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/__init__.py +20 -0
- data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +195 -0
- data/vendor/gems/thrift/contrib/fb303/py/setup.py +27 -0
- data/vendor/gems/thrift/contrib/thrift.el +126 -0
- data/vendor/gems/thrift/contrib/thrift.spec +206 -0
- data/vendor/gems/thrift/contrib/thrift.vim +91 -0
- data/vendor/gems/thrift/contrib/thrift_dump.cpp +91 -0
- data/vendor/gems/thrift/doc/lgpl-2.1.txt +504 -0
- data/vendor/gems/thrift/doc/otp-base-license.txt +20 -0
- data/vendor/gems/thrift/doc/thrift.bnf +96 -0
- data/vendor/gems/thrift/doc/thrift.tex +1057 -0
- data/vendor/gems/thrift/lib/Makefile.am +55 -0
- data/vendor/gems/thrift/lib/cocoa/README +21 -0
- data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.h +44 -0
- data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.m +130 -0
- data/vendor/gems/thrift/lib/cocoa/src/TException.h +34 -0
- data/vendor/gems/thrift/lib/cocoa/src/TException.m +64 -0
- data/vendor/gems/thrift/lib/cocoa/src/TProcessor.h +29 -0
- data/vendor/gems/thrift/lib/cocoa/src/TProcessorFactory.h +27 -0
- data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.h +27 -0
- data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.m +51 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.h +51 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.m +477 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocol.h +148 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.h +25 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.m +23 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolFactory.h +29 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.h +29 -0
- data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.m +104 -0
- data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.h +50 -0
- data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.m +153 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.h +42 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.m +159 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.h +35 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.m +91 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.h +38 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.m +89 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.h +32 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.m +58 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TTransport.h +36 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.h +30 -0
- data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.m +43 -0
- data/vendor/gems/thrift/lib/cpp/Makefile.am +158 -0
- data/vendor/gems/thrift/lib/cpp/README +67 -0
- data/vendor/gems/thrift/lib/cpp/src/TLogging.h +163 -0
- data/vendor/gems/thrift/lib/cpp/src/TProcessor.h +53 -0
- data/vendor/gems/thrift/lib/cpp/src/TReflectionLocal.h +96 -0
- data/vendor/gems/thrift/lib/cpp/src/Thrift.cpp +148 -0
- data/vendor/gems/thrift/lib/cpp/src/Thrift.h +191 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Exception.h +60 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/FunctionRunner.h +77 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.cpp +137 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.h +84 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.cpp +160 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.h +114 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.cpp +314 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.h +130 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Thread.h +125 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.cpp +493 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.h +169 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.cpp +284 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.h +122 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.cpp +55 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.h +100 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/test/Tests.cpp +155 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadFactoryTests.h +354 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadManagerTests.h +379 -0
- data/vendor/gems/thrift/lib/cpp/src/concurrency/test/TimerManagerTests.h +155 -0
- data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.cpp +122 -0
- data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.h +77 -0
- data/vendor/gems/thrift/lib/cpp/src/processor/StatsProcessor.h +264 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.cpp +79 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.h +42 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.cpp +394 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.h +254 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.cpp +736 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.h +279 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.cpp +346 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.h +225 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.cpp +762 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.h +253 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.cpp +998 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.h +340 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TOneWayProtocol.h +304 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocol.h +438 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolException.h +104 -0
- data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolTap.h +187 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.cpp +750 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.h +435 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TServer.cpp +38 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TServer.h +213 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.cpp +118 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.h +70 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.cpp +217 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.h +79 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.cpp +243 -0
- data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.h +74 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.cpp +370 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.h +667 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.cpp +77 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.h +73 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.cpp +953 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.h +442 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.cpp +348 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.h +111 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.cpp +368 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.h +76 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TServerTransport.h +92 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TShortReadTransport.h +96 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.cpp +54 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.h +41 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.cpp +591 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.h +242 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.cpp +235 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.h +191 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TTransport.h +224 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.cpp +31 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.h +117 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.cpp +178 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.h +287 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.cpp +299 -0
- data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.h +219 -0
- data/vendor/gems/thrift/lib/cpp/thrift-nb.pc.in +30 -0
- data/vendor/gems/thrift/lib/cpp/thrift-z.pc.in +30 -0
- data/vendor/gems/thrift/lib/cpp/thrift.pc.in +29 -0
- data/vendor/gems/thrift/lib/csharp/Makefile.am +70 -0
- data/vendor/gems/thrift/lib/csharp/README +26 -0
- data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs +55 -0
- data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs +242 -0
- data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj +62 -0
- data/vendor/gems/thrift/lib/csharp/src/Collections/THashSet.cs +142 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TBase.cs +34 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs +392 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TField.cs +58 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TList.cs +50 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TMap.cs +58 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessage.cs +58 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessageType.cs +31 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocol.cs +87 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolException.cs +61 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs +29 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs +94 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TSet.cs +50 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TStruct.cs +42 -0
- data/vendor/gems/thrift/lib/csharp/src/Protocol/TType.cs +40 -0
- data/vendor/gems/thrift/lib/csharp/src/Server/TServer.cs +135 -0
- data/vendor/gems/thrift/lib/csharp/src/Server/TSimpleServer.cs +148 -0
- data/vendor/gems/thrift/lib/csharp/src/Server/TThreadPoolServer.cs +186 -0
- data/vendor/gems/thrift/lib/csharp/src/Server/TThreadedServer.cs +234 -0
- data/vendor/gems/thrift/lib/csharp/src/TApplicationException.cs +131 -0
- data/vendor/gems/thrift/lib/csharp/src/TProcessor.cs +29 -0
- data/vendor/gems/thrift/lib/csharp/src/Thrift.csproj +73 -0
- data/vendor/gems/thrift/lib/csharp/src/Thrift.sln +35 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TBufferedTransport.cs +100 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TServerSocket.cs +157 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TServerTransport.cs +39 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TSocket.cs +144 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TStreamTransport.cs +103 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TTransport.cs +66 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportException.cs +64 -0
- data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportFactory.cs +38 -0
- data/vendor/gems/thrift/lib/erl/Makefile +37 -0
- data/vendor/gems/thrift/lib/erl/README +56 -0
- data/vendor/gems/thrift/lib/erl/build/beamver +59 -0
- data/vendor/gems/thrift/lib/erl/build/buildtargets.mk +15 -0
- data/vendor/gems/thrift/lib/erl/build/colors.mk +24 -0
- data/vendor/gems/thrift/lib/erl/build/docs.mk +12 -0
- data/vendor/gems/thrift/lib/erl/build/mime.types +98 -0
- data/vendor/gems/thrift/lib/erl/build/otp.mk +146 -0
- data/vendor/gems/thrift/lib/erl/build/otp_subdir.mk +85 -0
- data/vendor/gems/thrift/lib/erl/build/raw_test.mk +29 -0
- data/vendor/gems/thrift/lib/erl/include/thrift_constants.hrl +54 -0
- data/vendor/gems/thrift/lib/erl/include/thrift_protocol.hrl +31 -0
- data/vendor/gems/thrift/lib/erl/src/Makefile +116 -0
- data/vendor/gems/thrift/lib/erl/src/test_handler.erl +26 -0
- data/vendor/gems/thrift/lib/erl/src/test_service.erl +29 -0
- data/vendor/gems/thrift/lib/erl/src/thrift.app.src +44 -0
- data/vendor/gems/thrift/lib/erl/src/thrift.appup.src +1 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_base64_transport.erl +64 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_binary_protocol.erl +325 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_buffered_transport.erl +180 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_client.erl +384 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_disk_log_transport.erl +118 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_file_transport.erl +87 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_framed_transport.erl +208 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_http_transport.erl +199 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_memory_buffer.erl +164 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_processor.erl +188 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_protocol.erl +356 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_server.erl +183 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_service.erl +25 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_socket_server.erl +249 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_socket_transport.erl +119 -0
- data/vendor/gems/thrift/lib/erl/src/thrift_transport.erl +57 -0
- data/vendor/gems/thrift/lib/erl/vsn.mk +1 -0
- data/vendor/gems/thrift/lib/hs/README +82 -0
- data/vendor/gems/thrift/lib/hs/Setup.lhs +23 -0
- data/vendor/gems/thrift/lib/hs/TODO +2 -0
- data/vendor/gems/thrift/lib/hs/Thrift.cabal +20 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift.hs +111 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol.hs +191 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol/Binary.hs +147 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift/Server.hs +65 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift/Transport.hs +60 -0
- data/vendor/gems/thrift/lib/hs/src/Thrift/Transport/Handle.hs +58 -0
- data/vendor/gems/thrift/lib/java/Makefile.am +38 -0
- data/vendor/gems/thrift/lib/java/README +43 -0
- data/vendor/gems/thrift/lib/java/build.xml +195 -0
- data/vendor/gems/thrift/lib/java/ivy.xml +8 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/IntRangeSet.java +171 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TApplicationException.java +123 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBase.java +66 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBaseHelper.java +102 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java +46 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TDeserializer.java +94 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TException.java +45 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TFieldRequirementType.java +30 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessor.java +32 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessorFactory.java +39 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TSerializer.java +110 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldMetaData.java +69 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldValueMetaData.java +42 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/ListMetaData.java +29 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/MapMetaData.java +31 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/SetMetaData.java +29 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/StructMetaData.java +31 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBase64Utils.java +128 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java +331 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +741 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TField.java +48 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java +927 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TList.java +38 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMap.java +40 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessage.java +48 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessageType.java +31 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocol.java +146 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolException.java +81 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolFactory.java +30 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolUtil.java +158 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSet.java +42 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java +384 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TStruct.java +36 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TType.java +40 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/THsHaServer.java +304 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TNonblockingServer.java +772 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TServer.java +126 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TSimpleServer.java +145 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java +271 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TFramedTransport.java +126 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/THttpClient.java +157 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java +159 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java +98 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java +160 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerTransport.java +31 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java +213 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java +31 -0
- data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TServerSocket.java +145 -0
- metadata +348 -37
- data/vendor/gems/trollop/FAQ.txt +0 -35
- data/vendor/gems/trollop/History.txt +0 -84
- data/vendor/gems/trollop/Manifest.txt +0 -7
- data/vendor/gems/trollop/README.txt +0 -38
- data/vendor/gems/trollop/Rakefile +0 -36
- data/vendor/gems/trollop/lib/trollop.rb +0 -695
- data/vendor/gems/trollop/release-script.txt +0 -13
- data/vendor/gems/trollop/test/test_trollop.rb +0 -957
- data/vendor/gems/trollop/www/index.html +0 -167
|
@@ -0,0 +1,3003 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include <cassert>
|
|
21
|
+
|
|
22
|
+
#include <fstream>
|
|
23
|
+
#include <iostream>
|
|
24
|
+
#include <sstream>
|
|
25
|
+
#include <string>
|
|
26
|
+
#include <vector>
|
|
27
|
+
|
|
28
|
+
#include <sys/stat.h>
|
|
29
|
+
|
|
30
|
+
#include "platform.h"
|
|
31
|
+
#include "t_oop_generator.h"
|
|
32
|
+
using namespace std;
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* C++ code generator. This is legitimacy incarnate.
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
class t_cpp_generator : public t_oop_generator {
|
|
40
|
+
public:
|
|
41
|
+
t_cpp_generator(
|
|
42
|
+
t_program* program,
|
|
43
|
+
const std::map<std::string, std::string>& parsed_options,
|
|
44
|
+
const std::string& option_string)
|
|
45
|
+
: t_oop_generator(program)
|
|
46
|
+
{
|
|
47
|
+
std::map<std::string, std::string>::const_iterator iter;
|
|
48
|
+
|
|
49
|
+
iter = parsed_options.find("dense");
|
|
50
|
+
gen_dense_ = (iter != parsed_options.end());
|
|
51
|
+
|
|
52
|
+
iter = parsed_options.find("include_prefix");
|
|
53
|
+
use_include_prefix_ = (iter != parsed_options.end());
|
|
54
|
+
|
|
55
|
+
out_dir_base_ = "gen-cpp";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Init and close methods
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
void init_generator();
|
|
63
|
+
void close_generator();
|
|
64
|
+
|
|
65
|
+
void generate_consts(std::vector<t_const*> consts);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Program-level generation functions
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
void generate_typedef(t_typedef* ttypedef);
|
|
72
|
+
void generate_enum(t_enum* tenum);
|
|
73
|
+
void generate_struct(t_struct* tstruct) {
|
|
74
|
+
generate_cpp_struct(tstruct, false);
|
|
75
|
+
}
|
|
76
|
+
void generate_xception(t_struct* txception) {
|
|
77
|
+
generate_cpp_struct(txception, true);
|
|
78
|
+
}
|
|
79
|
+
void generate_cpp_struct(t_struct* tstruct, bool is_exception);
|
|
80
|
+
|
|
81
|
+
void generate_service(t_service* tservice);
|
|
82
|
+
|
|
83
|
+
void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
|
|
84
|
+
std::string render_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
|
|
85
|
+
|
|
86
|
+
void generate_struct_definition (std::ofstream& out, t_struct* tstruct, bool is_exception=false, bool pointers=false, bool read=true, bool write=true);
|
|
87
|
+
void generate_struct_fingerprint (std::ofstream& out, t_struct* tstruct, bool is_definition);
|
|
88
|
+
void generate_struct_reader (std::ofstream& out, t_struct* tstruct, bool pointers=false);
|
|
89
|
+
void generate_struct_writer (std::ofstream& out, t_struct* tstruct, bool pointers=false);
|
|
90
|
+
void generate_struct_result_writer (std::ofstream& out, t_struct* tstruct, bool pointers=false);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Service-level generation functions
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
void generate_service_interface (t_service* tservice);
|
|
97
|
+
void generate_service_null (t_service* tservice);
|
|
98
|
+
void generate_service_multiface (t_service* tservice);
|
|
99
|
+
void generate_service_helpers (t_service* tservice);
|
|
100
|
+
void generate_service_client (t_service* tservice);
|
|
101
|
+
void generate_service_processor (t_service* tservice);
|
|
102
|
+
void generate_service_skeleton (t_service* tservice);
|
|
103
|
+
void generate_process_function (t_service* tservice, t_function* tfunction);
|
|
104
|
+
void generate_function_helpers (t_service* tservice, t_function* tfunction);
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Serialization constructs
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
void generate_deserialize_field (std::ofstream& out,
|
|
111
|
+
t_field* tfield,
|
|
112
|
+
std::string prefix="",
|
|
113
|
+
std::string suffix="");
|
|
114
|
+
|
|
115
|
+
void generate_deserialize_struct (std::ofstream& out,
|
|
116
|
+
t_struct* tstruct,
|
|
117
|
+
std::string prefix="");
|
|
118
|
+
|
|
119
|
+
void generate_deserialize_container (std::ofstream& out,
|
|
120
|
+
t_type* ttype,
|
|
121
|
+
std::string prefix="");
|
|
122
|
+
|
|
123
|
+
void generate_deserialize_set_element (std::ofstream& out,
|
|
124
|
+
t_set* tset,
|
|
125
|
+
std::string prefix="");
|
|
126
|
+
|
|
127
|
+
void generate_deserialize_map_element (std::ofstream& out,
|
|
128
|
+
t_map* tmap,
|
|
129
|
+
std::string prefix="");
|
|
130
|
+
|
|
131
|
+
void generate_deserialize_list_element (std::ofstream& out,
|
|
132
|
+
t_list* tlist,
|
|
133
|
+
std::string prefix,
|
|
134
|
+
bool push_back,
|
|
135
|
+
std::string index);
|
|
136
|
+
|
|
137
|
+
void generate_serialize_field (std::ofstream& out,
|
|
138
|
+
t_field* tfield,
|
|
139
|
+
std::string prefix="",
|
|
140
|
+
std::string suffix="");
|
|
141
|
+
|
|
142
|
+
void generate_serialize_struct (std::ofstream& out,
|
|
143
|
+
t_struct* tstruct,
|
|
144
|
+
std::string prefix="");
|
|
145
|
+
|
|
146
|
+
void generate_serialize_container (std::ofstream& out,
|
|
147
|
+
t_type* ttype,
|
|
148
|
+
std::string prefix="");
|
|
149
|
+
|
|
150
|
+
void generate_serialize_map_element (std::ofstream& out,
|
|
151
|
+
t_map* tmap,
|
|
152
|
+
std::string iter);
|
|
153
|
+
|
|
154
|
+
void generate_serialize_set_element (std::ofstream& out,
|
|
155
|
+
t_set* tmap,
|
|
156
|
+
std::string iter);
|
|
157
|
+
|
|
158
|
+
void generate_serialize_list_element (std::ofstream& out,
|
|
159
|
+
t_list* tlist,
|
|
160
|
+
std::string iter);
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Helper rendering functions
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
std::string namespace_prefix(std::string ns);
|
|
167
|
+
std::string namespace_open(std::string ns);
|
|
168
|
+
std::string namespace_close(std::string ns);
|
|
169
|
+
std::string type_name(t_type* ttype, bool in_typedef=false, bool arg=false);
|
|
170
|
+
std::string base_type_name(t_base_type::t_base tbase);
|
|
171
|
+
std::string declare_field(t_field* tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false);
|
|
172
|
+
std::string function_signature(t_function* tfunction, std::string prefix="", bool name_params=true);
|
|
173
|
+
std::string argument_list(t_struct* tstruct, bool name_params=true);
|
|
174
|
+
std::string type_to_enum(t_type* ttype);
|
|
175
|
+
std::string local_reflection_name(const char*, t_type* ttype, bool external=false);
|
|
176
|
+
|
|
177
|
+
// These handles checking gen_dense_ and checking for duplicates.
|
|
178
|
+
void generate_local_reflection(std::ofstream& out, t_type* ttype, bool is_definition);
|
|
179
|
+
void generate_local_reflection_pointer(std::ofstream& out, t_type* ttype);
|
|
180
|
+
|
|
181
|
+
bool is_complex_type(t_type* ttype) {
|
|
182
|
+
ttype = get_true_type(ttype);
|
|
183
|
+
|
|
184
|
+
return
|
|
185
|
+
ttype->is_container() ||
|
|
186
|
+
ttype->is_struct() ||
|
|
187
|
+
ttype->is_xception() ||
|
|
188
|
+
(ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
void set_use_include_prefix(bool use_include_prefix) {
|
|
192
|
+
use_include_prefix_ = use_include_prefix;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private:
|
|
196
|
+
/**
|
|
197
|
+
* Returns the include prefix to use for a file generated by program, or the
|
|
198
|
+
* empty string if no include prefix should be used.
|
|
199
|
+
*/
|
|
200
|
+
std::string get_include_prefix(const t_program& program) const;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* True iff we should generate local reflection metadata for TDenseProtocol.
|
|
204
|
+
*/
|
|
205
|
+
bool gen_dense_;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* True iff we should use a path prefix in our #include statements for other
|
|
209
|
+
* thrift-generated header files.
|
|
210
|
+
*/
|
|
211
|
+
bool use_include_prefix_;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Strings for namespace, computed once up front then used directly
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
std::string ns_open_;
|
|
218
|
+
std::string ns_close_;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* File streams, stored here to avoid passing them as parameters to every
|
|
222
|
+
* function.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
std::ofstream f_types_;
|
|
226
|
+
std::ofstream f_types_impl_;
|
|
227
|
+
std::ofstream f_header_;
|
|
228
|
+
std::ofstream f_service_;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* When generating local reflections, make sure we don't generate duplicates.
|
|
232
|
+
*/
|
|
233
|
+
std::set<std::string> reflected_fingerprints_;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Prepares for file generation by opening up the necessary file output
|
|
239
|
+
* streams.
|
|
240
|
+
*
|
|
241
|
+
* @param tprogram The program to generate
|
|
242
|
+
*/
|
|
243
|
+
void t_cpp_generator::init_generator() {
|
|
244
|
+
// Make output directory
|
|
245
|
+
MKDIR(get_out_dir().c_str());
|
|
246
|
+
|
|
247
|
+
// Make output file
|
|
248
|
+
string f_types_name = get_out_dir()+program_name_+"_types.h";
|
|
249
|
+
f_types_.open(f_types_name.c_str());
|
|
250
|
+
|
|
251
|
+
string f_types_impl_name = get_out_dir()+program_name_+"_types.cpp";
|
|
252
|
+
f_types_impl_.open(f_types_impl_name.c_str());
|
|
253
|
+
|
|
254
|
+
// Print header
|
|
255
|
+
f_types_ <<
|
|
256
|
+
autogen_comment();
|
|
257
|
+
f_types_impl_ <<
|
|
258
|
+
autogen_comment();
|
|
259
|
+
|
|
260
|
+
// Start ifndef
|
|
261
|
+
f_types_ <<
|
|
262
|
+
"#ifndef " << program_name_ << "_TYPES_H" << endl <<
|
|
263
|
+
"#define " << program_name_ << "_TYPES_H" << endl <<
|
|
264
|
+
endl;
|
|
265
|
+
|
|
266
|
+
// Include base types
|
|
267
|
+
f_types_ <<
|
|
268
|
+
"#include <Thrift.h>" << endl <<
|
|
269
|
+
"#include <protocol/TProtocol.h>" << endl <<
|
|
270
|
+
"#include <transport/TTransport.h>" << endl <<
|
|
271
|
+
endl;
|
|
272
|
+
|
|
273
|
+
// Include other Thrift includes
|
|
274
|
+
const vector<t_program*>& includes = program_->get_includes();
|
|
275
|
+
for (size_t i = 0; i < includes.size(); ++i) {
|
|
276
|
+
f_types_ <<
|
|
277
|
+
"#include \"" << get_include_prefix(*(includes[i])) <<
|
|
278
|
+
includes[i]->get_name() << "_types.h\"" << endl;
|
|
279
|
+
}
|
|
280
|
+
f_types_ << endl;
|
|
281
|
+
|
|
282
|
+
// Include custom headers
|
|
283
|
+
const vector<string>& cpp_includes = program_->get_cpp_includes();
|
|
284
|
+
for (size_t i = 0; i < cpp_includes.size(); ++i) {
|
|
285
|
+
if (cpp_includes[i][0] == '<') {
|
|
286
|
+
f_types_ <<
|
|
287
|
+
"#include " << cpp_includes[i] << endl;
|
|
288
|
+
} else {
|
|
289
|
+
f_types_ <<
|
|
290
|
+
"#include \"" << cpp_includes[i] << "\"" << endl;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
f_types_ <<
|
|
294
|
+
endl;
|
|
295
|
+
|
|
296
|
+
// Include the types file
|
|
297
|
+
f_types_impl_ <<
|
|
298
|
+
"#include \"" << get_include_prefix(*get_program()) << program_name_ <<
|
|
299
|
+
"_types.h\"" << endl <<
|
|
300
|
+
endl;
|
|
301
|
+
|
|
302
|
+
// If we are generating local reflection metadata, we need to include
|
|
303
|
+
// the definition of TypeSpec.
|
|
304
|
+
if (gen_dense_) {
|
|
305
|
+
f_types_impl_ <<
|
|
306
|
+
"#include <TReflectionLocal.h>" << endl <<
|
|
307
|
+
endl;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Open namespace
|
|
311
|
+
ns_open_ = namespace_open(program_->get_namespace("cpp"));
|
|
312
|
+
ns_close_ = namespace_close(program_->get_namespace("cpp"));
|
|
313
|
+
|
|
314
|
+
f_types_ <<
|
|
315
|
+
ns_open_ << endl <<
|
|
316
|
+
endl;
|
|
317
|
+
|
|
318
|
+
f_types_impl_ <<
|
|
319
|
+
ns_open_ << endl <<
|
|
320
|
+
endl;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Closes the output files.
|
|
325
|
+
*/
|
|
326
|
+
void t_cpp_generator::close_generator() {
|
|
327
|
+
// Close namespace
|
|
328
|
+
f_types_ <<
|
|
329
|
+
ns_close_ << endl <<
|
|
330
|
+
endl;
|
|
331
|
+
f_types_impl_ <<
|
|
332
|
+
ns_close_ << endl;
|
|
333
|
+
|
|
334
|
+
// Close ifndef
|
|
335
|
+
f_types_ <<
|
|
336
|
+
"#endif" << endl;
|
|
337
|
+
|
|
338
|
+
// Close output file
|
|
339
|
+
f_types_.close();
|
|
340
|
+
f_types_impl_.close();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Generates a typedef. This is just a simple 1-liner in C++
|
|
345
|
+
*
|
|
346
|
+
* @param ttypedef The type definition
|
|
347
|
+
*/
|
|
348
|
+
void t_cpp_generator::generate_typedef(t_typedef* ttypedef) {
|
|
349
|
+
f_types_ <<
|
|
350
|
+
indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " << ttypedef->get_symbolic() << ";" << endl <<
|
|
351
|
+
endl;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Generates code for an enumerated type. In C++, this is essentially the same
|
|
356
|
+
* as the thrift definition itself, using the enum keyword in C++.
|
|
357
|
+
*
|
|
358
|
+
* @param tenum The enumeration
|
|
359
|
+
*/
|
|
360
|
+
void t_cpp_generator::generate_enum(t_enum* tenum) {
|
|
361
|
+
f_types_ <<
|
|
362
|
+
indent() << "enum " << tenum->get_name() << " {" << endl;
|
|
363
|
+
indent_up();
|
|
364
|
+
|
|
365
|
+
vector<t_enum_value*> constants = tenum->get_constants();
|
|
366
|
+
vector<t_enum_value*>::iterator c_iter;
|
|
367
|
+
bool first = true;
|
|
368
|
+
for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
|
|
369
|
+
if (first) {
|
|
370
|
+
first = false;
|
|
371
|
+
} else {
|
|
372
|
+
f_types_ <<
|
|
373
|
+
"," << endl;
|
|
374
|
+
}
|
|
375
|
+
f_types_ <<
|
|
376
|
+
indent() << (*c_iter)->get_name();
|
|
377
|
+
if ((*c_iter)->has_value()) {
|
|
378
|
+
f_types_ <<
|
|
379
|
+
" = " << (*c_iter)->get_value();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
indent_down();
|
|
384
|
+
f_types_ <<
|
|
385
|
+
endl <<
|
|
386
|
+
"};" << endl <<
|
|
387
|
+
endl;
|
|
388
|
+
|
|
389
|
+
generate_local_reflection(f_types_, tenum, false);
|
|
390
|
+
generate_local_reflection(f_types_impl_, tenum, true);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Generates a class that holds all the constants.
|
|
395
|
+
*/
|
|
396
|
+
void t_cpp_generator::generate_consts(std::vector<t_const*> consts) {
|
|
397
|
+
string f_consts_name = get_out_dir()+program_name_+"_constants.h";
|
|
398
|
+
ofstream f_consts;
|
|
399
|
+
f_consts.open(f_consts_name.c_str());
|
|
400
|
+
|
|
401
|
+
string f_consts_impl_name = get_out_dir()+program_name_+"_constants.cpp";
|
|
402
|
+
ofstream f_consts_impl;
|
|
403
|
+
f_consts_impl.open(f_consts_impl_name.c_str());
|
|
404
|
+
|
|
405
|
+
// Print header
|
|
406
|
+
f_consts <<
|
|
407
|
+
autogen_comment();
|
|
408
|
+
f_consts_impl <<
|
|
409
|
+
autogen_comment();
|
|
410
|
+
|
|
411
|
+
// Start ifndef
|
|
412
|
+
f_consts <<
|
|
413
|
+
"#ifndef " << program_name_ << "_CONSTANTS_H" << endl <<
|
|
414
|
+
"#define " << program_name_ << "_CONSTANTS_H" << endl <<
|
|
415
|
+
endl <<
|
|
416
|
+
"#include \"" << get_include_prefix(*get_program()) << program_name_ <<
|
|
417
|
+
"_types.h\"" << endl <<
|
|
418
|
+
endl <<
|
|
419
|
+
ns_open_ << endl <<
|
|
420
|
+
endl;
|
|
421
|
+
|
|
422
|
+
f_consts_impl <<
|
|
423
|
+
"#include \"" << get_include_prefix(*get_program()) << program_name_ <<
|
|
424
|
+
"_constants.h\"" << endl <<
|
|
425
|
+
endl <<
|
|
426
|
+
ns_open_ << endl <<
|
|
427
|
+
endl;
|
|
428
|
+
|
|
429
|
+
f_consts <<
|
|
430
|
+
"class " << program_name_ << "Constants {" << endl <<
|
|
431
|
+
" public:" << endl <<
|
|
432
|
+
" " << program_name_ << "Constants();" << endl <<
|
|
433
|
+
endl;
|
|
434
|
+
indent_up();
|
|
435
|
+
vector<t_const*>::iterator c_iter;
|
|
436
|
+
for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
|
|
437
|
+
string name = (*c_iter)->get_name();
|
|
438
|
+
t_type* type = (*c_iter)->get_type();
|
|
439
|
+
f_consts <<
|
|
440
|
+
indent() << type_name(type) << " " << name << ";" << endl;
|
|
441
|
+
}
|
|
442
|
+
indent_down();
|
|
443
|
+
f_consts <<
|
|
444
|
+
"};" << endl;
|
|
445
|
+
|
|
446
|
+
f_consts_impl <<
|
|
447
|
+
"const " << program_name_ << "Constants g_" << program_name_ << "_constants;" << endl <<
|
|
448
|
+
endl <<
|
|
449
|
+
program_name_ << "Constants::" << program_name_ << "Constants() {" << endl;
|
|
450
|
+
indent_up();
|
|
451
|
+
for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
|
|
452
|
+
print_const_value(f_consts_impl,
|
|
453
|
+
(*c_iter)->get_name(),
|
|
454
|
+
(*c_iter)->get_type(),
|
|
455
|
+
(*c_iter)->get_value());
|
|
456
|
+
}
|
|
457
|
+
indent_down();
|
|
458
|
+
indent(f_consts_impl) <<
|
|
459
|
+
"}" << endl;
|
|
460
|
+
|
|
461
|
+
f_consts <<
|
|
462
|
+
endl <<
|
|
463
|
+
"extern const " << program_name_ << "Constants g_" << program_name_ << "_constants;" << endl <<
|
|
464
|
+
endl <<
|
|
465
|
+
ns_close_ << endl <<
|
|
466
|
+
endl <<
|
|
467
|
+
"#endif" << endl;
|
|
468
|
+
f_consts.close();
|
|
469
|
+
|
|
470
|
+
f_consts_impl <<
|
|
471
|
+
endl <<
|
|
472
|
+
ns_close_ << endl <<
|
|
473
|
+
endl;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Prints the value of a constant with the given type. Note that type checking
|
|
478
|
+
* is NOT performed in this function as it is always run beforehand using the
|
|
479
|
+
* validate_types method in main.cc
|
|
480
|
+
*/
|
|
481
|
+
void t_cpp_generator::print_const_value(ofstream& out, string name, t_type* type, t_const_value* value) {
|
|
482
|
+
type = get_true_type(type);
|
|
483
|
+
if (type->is_base_type()) {
|
|
484
|
+
string v2 = render_const_value(out, name, type, value);
|
|
485
|
+
indent(out) << name << " = " << v2 << ";" << endl <<
|
|
486
|
+
endl;
|
|
487
|
+
} else if (type->is_enum()) {
|
|
488
|
+
indent(out) << name << " = (" << type_name(type) << ")" << value->get_integer() << ";" << endl <<
|
|
489
|
+
endl;
|
|
490
|
+
} else if (type->is_struct() || type->is_xception()) {
|
|
491
|
+
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
|
|
492
|
+
vector<t_field*>::const_iterator f_iter;
|
|
493
|
+
const map<t_const_value*, t_const_value*>& val = value->get_map();
|
|
494
|
+
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
|
495
|
+
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
|
496
|
+
t_type* field_type = NULL;
|
|
497
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
498
|
+
if ((*f_iter)->get_name() == v_iter->first->get_string()) {
|
|
499
|
+
field_type = (*f_iter)->get_type();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (field_type == NULL) {
|
|
503
|
+
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
|
|
504
|
+
}
|
|
505
|
+
string val = render_const_value(out, name, field_type, v_iter->second);
|
|
506
|
+
indent(out) << name << "." << v_iter->first->get_string() << " = " << val << ";" << endl;
|
|
507
|
+
indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << endl;
|
|
508
|
+
}
|
|
509
|
+
out << endl;
|
|
510
|
+
} else if (type->is_map()) {
|
|
511
|
+
t_type* ktype = ((t_map*)type)->get_key_type();
|
|
512
|
+
t_type* vtype = ((t_map*)type)->get_val_type();
|
|
513
|
+
const map<t_const_value*, t_const_value*>& val = value->get_map();
|
|
514
|
+
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
|
515
|
+
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
|
516
|
+
string key = render_const_value(out, name, ktype, v_iter->first);
|
|
517
|
+
string val = render_const_value(out, name, vtype, v_iter->second);
|
|
518
|
+
indent(out) << name << ".insert(std::make_pair(" << key << ", " << val << "));" << endl;
|
|
519
|
+
}
|
|
520
|
+
out << endl;
|
|
521
|
+
} else if (type->is_list()) {
|
|
522
|
+
t_type* etype = ((t_list*)type)->get_elem_type();
|
|
523
|
+
const vector<t_const_value*>& val = value->get_list();
|
|
524
|
+
vector<t_const_value*>::const_iterator v_iter;
|
|
525
|
+
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
|
526
|
+
string val = render_const_value(out, name, etype, *v_iter);
|
|
527
|
+
indent(out) << name << ".push_back(" << val << ");" << endl;
|
|
528
|
+
}
|
|
529
|
+
out << endl;
|
|
530
|
+
} else if (type->is_set()) {
|
|
531
|
+
t_type* etype = ((t_set*)type)->get_elem_type();
|
|
532
|
+
const vector<t_const_value*>& val = value->get_list();
|
|
533
|
+
vector<t_const_value*>::const_iterator v_iter;
|
|
534
|
+
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
|
535
|
+
string val = render_const_value(out, name, etype, *v_iter);
|
|
536
|
+
indent(out) << name << ".insert(" << val << ");" << endl;
|
|
537
|
+
}
|
|
538
|
+
out << endl;
|
|
539
|
+
} else {
|
|
540
|
+
throw "INVALID TYPE IN print_const_value: " + type->get_name();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
*
|
|
546
|
+
*/
|
|
547
|
+
string t_cpp_generator::render_const_value(ofstream& out, string name, t_type* type, t_const_value* value) {
|
|
548
|
+
std::ostringstream render;
|
|
549
|
+
|
|
550
|
+
if (type->is_base_type()) {
|
|
551
|
+
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
|
|
552
|
+
switch (tbase) {
|
|
553
|
+
case t_base_type::TYPE_STRING:
|
|
554
|
+
render << '"' << get_escaped_string(value) << '"';
|
|
555
|
+
break;
|
|
556
|
+
case t_base_type::TYPE_BOOL:
|
|
557
|
+
render << ((value->get_integer() > 0) ? "true" : "false");
|
|
558
|
+
break;
|
|
559
|
+
case t_base_type::TYPE_BYTE:
|
|
560
|
+
case t_base_type::TYPE_I16:
|
|
561
|
+
case t_base_type::TYPE_I32:
|
|
562
|
+
render << value->get_integer();
|
|
563
|
+
break;
|
|
564
|
+
case t_base_type::TYPE_I64:
|
|
565
|
+
render << value->get_integer() << "LL";
|
|
566
|
+
break;
|
|
567
|
+
case t_base_type::TYPE_DOUBLE:
|
|
568
|
+
if (value->get_type() == t_const_value::CV_INTEGER) {
|
|
569
|
+
render << value->get_integer();
|
|
570
|
+
} else {
|
|
571
|
+
render << value->get_double();
|
|
572
|
+
}
|
|
573
|
+
break;
|
|
574
|
+
default:
|
|
575
|
+
throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
|
|
576
|
+
}
|
|
577
|
+
} else if (type->is_enum()) {
|
|
578
|
+
render << "(" << type_name(type) << ")" << value->get_integer();
|
|
579
|
+
} else {
|
|
580
|
+
string t = tmp("tmp");
|
|
581
|
+
indent(out) << type_name(type) << " " << t << ";" << endl;
|
|
582
|
+
print_const_value(out, t, type, value);
|
|
583
|
+
render << t;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return render.str();
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Generates a struct definition for a thrift data type. This is a class
|
|
591
|
+
* with data members and a read/write() function, plus a mirroring isset
|
|
592
|
+
* inner class.
|
|
593
|
+
*
|
|
594
|
+
* @param tstruct The struct definition
|
|
595
|
+
*/
|
|
596
|
+
void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) {
|
|
597
|
+
generate_struct_definition(f_types_, tstruct, is_exception);
|
|
598
|
+
generate_struct_fingerprint(f_types_impl_, tstruct, true);
|
|
599
|
+
generate_local_reflection(f_types_, tstruct, false);
|
|
600
|
+
generate_local_reflection(f_types_impl_, tstruct, true);
|
|
601
|
+
generate_local_reflection_pointer(f_types_impl_, tstruct);
|
|
602
|
+
generate_struct_reader(f_types_impl_, tstruct);
|
|
603
|
+
generate_struct_writer(f_types_impl_, tstruct);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Writes the struct definition into the header file
|
|
608
|
+
*
|
|
609
|
+
* @param out Output stream
|
|
610
|
+
* @param tstruct The struct
|
|
611
|
+
*/
|
|
612
|
+
void t_cpp_generator::generate_struct_definition(ofstream& out,
|
|
613
|
+
t_struct* tstruct,
|
|
614
|
+
bool is_exception,
|
|
615
|
+
bool pointers,
|
|
616
|
+
bool read,
|
|
617
|
+
bool write) {
|
|
618
|
+
string extends = "";
|
|
619
|
+
if (is_exception) {
|
|
620
|
+
extends = " : public apache::thrift::TException";
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Open struct def
|
|
624
|
+
out <<
|
|
625
|
+
indent() << "class " << tstruct->get_name() << extends << " {" << endl <<
|
|
626
|
+
indent() << " public:" << endl <<
|
|
627
|
+
endl;
|
|
628
|
+
indent_up();
|
|
629
|
+
|
|
630
|
+
// Put the fingerprint up top for all to see.
|
|
631
|
+
generate_struct_fingerprint(out, tstruct, false);
|
|
632
|
+
|
|
633
|
+
// Get members
|
|
634
|
+
vector<t_field*>::const_iterator m_iter;
|
|
635
|
+
const vector<t_field*>& members = tstruct->get_members();
|
|
636
|
+
|
|
637
|
+
if (!pointers) {
|
|
638
|
+
// Default constructor
|
|
639
|
+
indent(out) <<
|
|
640
|
+
tstruct->get_name() << "()";
|
|
641
|
+
|
|
642
|
+
bool init_ctor = false;
|
|
643
|
+
|
|
644
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
645
|
+
t_type* t = get_true_type((*m_iter)->get_type());
|
|
646
|
+
if (t->is_base_type()) {
|
|
647
|
+
string dval;
|
|
648
|
+
if (t->is_enum()) {
|
|
649
|
+
dval += "(" + type_name(t) + ")";
|
|
650
|
+
}
|
|
651
|
+
dval += t->is_string() ? "\"\"" : "0";
|
|
652
|
+
t_const_value* cv = (*m_iter)->get_value();
|
|
653
|
+
if (cv != NULL) {
|
|
654
|
+
dval = render_const_value(out, (*m_iter)->get_name(), t, cv);
|
|
655
|
+
}
|
|
656
|
+
if (!init_ctor) {
|
|
657
|
+
init_ctor = true;
|
|
658
|
+
out << " : ";
|
|
659
|
+
out << (*m_iter)->get_name() << "(" << dval << ")";
|
|
660
|
+
} else {
|
|
661
|
+
out << ", " << (*m_iter)->get_name() << "(" << dval << ")";
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
out << " {" << endl;
|
|
666
|
+
indent_up();
|
|
667
|
+
// TODO(dreiss): When everything else in Thrift is perfect,
|
|
668
|
+
// do more of these in the initializer list.
|
|
669
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
670
|
+
t_type* t = get_true_type((*m_iter)->get_type());
|
|
671
|
+
|
|
672
|
+
if (!t->is_base_type()) {
|
|
673
|
+
t_const_value* cv = (*m_iter)->get_value();
|
|
674
|
+
if (cv != NULL) {
|
|
675
|
+
print_const_value(out, (*m_iter)->get_name(), t, cv);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
scope_down(out);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
|
|
683
|
+
out <<
|
|
684
|
+
endl <<
|
|
685
|
+
indent() << "virtual ~" << tstruct->get_name() << "() throw() {}" << endl << endl;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Pointer to this structure's reflection local typespec.
|
|
689
|
+
if (gen_dense_) {
|
|
690
|
+
indent(out) <<
|
|
691
|
+
"static apache::thrift::reflection::local::TypeSpec* local_reflection;" <<
|
|
692
|
+
endl << endl;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Declare all fields
|
|
696
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
697
|
+
indent(out) <<
|
|
698
|
+
declare_field(*m_iter, false, pointers && !(*m_iter)->get_type()->is_xception(), !read) << endl;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Isset struct has boolean fields, but only for non-required fields.
|
|
702
|
+
bool has_nonrequired_fields = false;
|
|
703
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
704
|
+
if ((*m_iter)->get_req() != t_field::T_REQUIRED)
|
|
705
|
+
has_nonrequired_fields = true;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (has_nonrequired_fields && (!pointers || read)) {
|
|
709
|
+
out <<
|
|
710
|
+
endl <<
|
|
711
|
+
indent() << "struct __isset {" << endl;
|
|
712
|
+
indent_up();
|
|
713
|
+
|
|
714
|
+
indent(out) <<
|
|
715
|
+
"__isset() : ";
|
|
716
|
+
bool first = true;
|
|
717
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
718
|
+
if ((*m_iter)->get_req() == t_field::T_REQUIRED) {
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
if (first) {
|
|
722
|
+
first = false;
|
|
723
|
+
out <<
|
|
724
|
+
(*m_iter)->get_name() << "(false)";
|
|
725
|
+
} else {
|
|
726
|
+
out <<
|
|
727
|
+
", " << (*m_iter)->get_name() << "(false)";
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
out << " {}" << endl;
|
|
731
|
+
|
|
732
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
733
|
+
if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
|
|
734
|
+
indent(out) <<
|
|
735
|
+
"bool " << (*m_iter)->get_name() << ";" << endl;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
indent_down();
|
|
740
|
+
indent(out) <<
|
|
741
|
+
"} __isset;" << endl;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
out << endl;
|
|
745
|
+
|
|
746
|
+
if (!pointers) {
|
|
747
|
+
// Generate an equality testing operator. Make it inline since the compiler
|
|
748
|
+
// will do a better job than we would when deciding whether to inline it.
|
|
749
|
+
out <<
|
|
750
|
+
indent() << "bool operator == (const " << tstruct->get_name() << " & " <<
|
|
751
|
+
(members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << endl;
|
|
752
|
+
scope_up(out);
|
|
753
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
754
|
+
// Most existing Thrift code does not use isset or optional/required,
|
|
755
|
+
// so we treat "default" fields as required.
|
|
756
|
+
if ((*m_iter)->get_req() != t_field::T_OPTIONAL) {
|
|
757
|
+
out <<
|
|
758
|
+
indent() << "if (!(" << (*m_iter)->get_name()
|
|
759
|
+
<< " == rhs." << (*m_iter)->get_name() << "))" << endl <<
|
|
760
|
+
indent() << " return false;" << endl;
|
|
761
|
+
} else {
|
|
762
|
+
out <<
|
|
763
|
+
indent() << "if (__isset." << (*m_iter)->get_name()
|
|
764
|
+
<< " != rhs.__isset." << (*m_iter)->get_name() << ")" << endl <<
|
|
765
|
+
indent() << " return false;" << endl <<
|
|
766
|
+
indent() << "else if (__isset." << (*m_iter)->get_name() << " && !("
|
|
767
|
+
<< (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name()
|
|
768
|
+
<< "))" << endl <<
|
|
769
|
+
indent() << " return false;" << endl;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
indent(out) << "return true;" << endl;
|
|
773
|
+
scope_down(out);
|
|
774
|
+
out <<
|
|
775
|
+
indent() << "bool operator != (const " << tstruct->get_name() << " &rhs) const {" << endl <<
|
|
776
|
+
indent() << " return !(*this == rhs);" << endl <<
|
|
777
|
+
indent() << "}" << endl << endl;
|
|
778
|
+
|
|
779
|
+
// Generate the declaration of a less-than operator. This must be
|
|
780
|
+
// implemented by the application developer if they wish to use it. (They
|
|
781
|
+
// will get a link error if they try to use it without an implementation.)
|
|
782
|
+
out <<
|
|
783
|
+
indent() << "bool operator < (const "
|
|
784
|
+
<< tstruct->get_name() << " & ) const;" << endl << endl;
|
|
785
|
+
}
|
|
786
|
+
if (read) {
|
|
787
|
+
out <<
|
|
788
|
+
indent() << "uint32_t read(apache::thrift::protocol::TProtocol* iprot);" << endl;
|
|
789
|
+
}
|
|
790
|
+
if (write) {
|
|
791
|
+
out <<
|
|
792
|
+
indent() << "uint32_t write(apache::thrift::protocol::TProtocol* oprot) const;" << endl;
|
|
793
|
+
}
|
|
794
|
+
out << endl;
|
|
795
|
+
|
|
796
|
+
indent_down();
|
|
797
|
+
indent(out) <<
|
|
798
|
+
"};" << endl <<
|
|
799
|
+
endl;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Writes the fingerprint of a struct to either the header or implementation.
|
|
804
|
+
*
|
|
805
|
+
* @param out Output stream
|
|
806
|
+
* @param tstruct The struct
|
|
807
|
+
*/
|
|
808
|
+
void t_cpp_generator::generate_struct_fingerprint(ofstream& out,
|
|
809
|
+
t_struct* tstruct,
|
|
810
|
+
bool is_definition) {
|
|
811
|
+
string stat, nspace, comment;
|
|
812
|
+
if (is_definition) {
|
|
813
|
+
stat = "";
|
|
814
|
+
nspace = tstruct->get_name() + "::";
|
|
815
|
+
comment = " ";
|
|
816
|
+
} else {
|
|
817
|
+
stat = "static ";
|
|
818
|
+
nspace = "";
|
|
819
|
+
comment = "; // ";
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
if (tstruct->has_fingerprint()) {
|
|
823
|
+
out <<
|
|
824
|
+
indent() << stat << "const char* " << nspace
|
|
825
|
+
<< "ascii_fingerprint" << comment << "= \"" <<
|
|
826
|
+
tstruct->get_ascii_fingerprint() << "\";" << endl <<
|
|
827
|
+
indent() << stat << "const uint8_t " << nspace <<
|
|
828
|
+
"binary_fingerprint[" << t_type::fingerprint_len << "]" << comment << "= {";
|
|
829
|
+
const char* comma = "";
|
|
830
|
+
for (int i = 0; i < t_type::fingerprint_len; i++) {
|
|
831
|
+
out << comma << "0x" << t_struct::byte_to_hex(tstruct->get_binary_fingerprint()[i]);
|
|
832
|
+
comma = ",";
|
|
833
|
+
}
|
|
834
|
+
out << "};" << endl << endl;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Writes the local reflection of a type (either declaration or definition).
|
|
840
|
+
*/
|
|
841
|
+
void t_cpp_generator::generate_local_reflection(std::ofstream& out,
|
|
842
|
+
t_type* ttype,
|
|
843
|
+
bool is_definition) {
|
|
844
|
+
if (!gen_dense_) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
ttype = get_true_type(ttype);
|
|
848
|
+
assert(ttype->has_fingerprint());
|
|
849
|
+
string key = ttype->get_ascii_fingerprint() + (is_definition ? "-defn" : "-decl");
|
|
850
|
+
// Note that we have generated this fingerprint. If we already did, bail out.
|
|
851
|
+
if (!reflected_fingerprints_.insert(key).second) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
// Let each program handle its own structures.
|
|
855
|
+
if (ttype->get_program() != NULL && ttype->get_program() != program_) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// Do dependencies.
|
|
860
|
+
if (ttype->is_list()) {
|
|
861
|
+
generate_local_reflection(out, ((t_list*)ttype)->get_elem_type(), is_definition);
|
|
862
|
+
} else if (ttype->is_set()) {
|
|
863
|
+
generate_local_reflection(out, ((t_set*)ttype)->get_elem_type(), is_definition);
|
|
864
|
+
} else if (ttype->is_map()) {
|
|
865
|
+
generate_local_reflection(out, ((t_map*)ttype)->get_key_type(), is_definition);
|
|
866
|
+
generate_local_reflection(out, ((t_map*)ttype)->get_val_type(), is_definition);
|
|
867
|
+
} else if (ttype->is_struct() || ttype->is_xception()) {
|
|
868
|
+
// Hacky hacky. For efficiency and convenience, we need a dummy "T_STOP"
|
|
869
|
+
// type at the end of our typespec array. Unfortunately, there is no
|
|
870
|
+
// T_STOP type, so we use the global void type, and special case it when
|
|
871
|
+
// generating its typespec.
|
|
872
|
+
|
|
873
|
+
const vector<t_field*>& members = ((t_struct*)ttype)->get_sorted_members();
|
|
874
|
+
vector<t_field*>::const_iterator m_iter;
|
|
875
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
876
|
+
generate_local_reflection(out, (**m_iter).get_type(), is_definition);
|
|
877
|
+
}
|
|
878
|
+
generate_local_reflection(out, g_type_void, is_definition);
|
|
879
|
+
|
|
880
|
+
// For definitions of structures, do the arrays of metas and field specs also.
|
|
881
|
+
if (is_definition) {
|
|
882
|
+
out <<
|
|
883
|
+
indent() << "apache::thrift::reflection::local::FieldMeta" << endl <<
|
|
884
|
+
indent() << local_reflection_name("metas", ttype) <<"[] = {" << endl;
|
|
885
|
+
indent_up();
|
|
886
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
887
|
+
indent(out) << "{ " << (*m_iter)->get_key() << ", " <<
|
|
888
|
+
(((*m_iter)->get_req() == t_field::T_OPTIONAL) ? "true" : "false") <<
|
|
889
|
+
" }," << endl;
|
|
890
|
+
}
|
|
891
|
+
// Zero for the T_STOP marker.
|
|
892
|
+
indent(out) << "{ 0, false }" << endl << "};" << endl;
|
|
893
|
+
indent_down();
|
|
894
|
+
|
|
895
|
+
out <<
|
|
896
|
+
indent() << "apache::thrift::reflection::local::TypeSpec*" << endl <<
|
|
897
|
+
indent() << local_reflection_name("specs", ttype) <<"[] = {" << endl;
|
|
898
|
+
indent_up();
|
|
899
|
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
|
900
|
+
indent(out) << "&" <<
|
|
901
|
+
local_reflection_name("typespec", (*m_iter)->get_type(), true) << "," << endl;
|
|
902
|
+
}
|
|
903
|
+
indent(out) << "&" <<
|
|
904
|
+
local_reflection_name("typespec", g_type_void) << "," << endl;
|
|
905
|
+
indent_down();
|
|
906
|
+
indent(out) << "};" << endl;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
out <<
|
|
911
|
+
indent() << "// " << ttype->get_fingerprint_material() << endl <<
|
|
912
|
+
indent() << (is_definition ? "" : "extern ") <<
|
|
913
|
+
"apache::thrift::reflection::local::TypeSpec" << endl <<
|
|
914
|
+
local_reflection_name("typespec", ttype) <<
|
|
915
|
+
(is_definition ? "(" : ";") << endl;
|
|
916
|
+
|
|
917
|
+
if (!is_definition) {
|
|
918
|
+
out << endl;
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
indent_up();
|
|
923
|
+
|
|
924
|
+
if (ttype->is_void()) {
|
|
925
|
+
indent(out) << "apache::thrift::protocol::T_STOP";
|
|
926
|
+
} else {
|
|
927
|
+
indent(out) << type_to_enum(ttype);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
if (ttype->is_struct()) {
|
|
931
|
+
out << "," << endl <<
|
|
932
|
+
indent() << type_name(ttype) << "::binary_fingerprint," << endl <<
|
|
933
|
+
indent() << local_reflection_name("metas", ttype) << "," << endl <<
|
|
934
|
+
indent() << local_reflection_name("specs", ttype);
|
|
935
|
+
} else if (ttype->is_list()) {
|
|
936
|
+
out << "," << endl <<
|
|
937
|
+
indent() << "&" << local_reflection_name("typespec", ((t_list*)ttype)->get_elem_type()) << "," << endl <<
|
|
938
|
+
indent() << "NULL";
|
|
939
|
+
} else if (ttype->is_set()) {
|
|
940
|
+
out << "," << endl <<
|
|
941
|
+
indent() << "&" << local_reflection_name("typespec", ((t_set*)ttype)->get_elem_type()) << "," << endl <<
|
|
942
|
+
indent() << "NULL";
|
|
943
|
+
} else if (ttype->is_map()) {
|
|
944
|
+
out << "," << endl <<
|
|
945
|
+
indent() << "&" << local_reflection_name("typespec", ((t_map*)ttype)->get_key_type()) << "," << endl <<
|
|
946
|
+
indent() << "&" << local_reflection_name("typespec", ((t_map*)ttype)->get_val_type());
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
out << ");" << endl << endl;
|
|
950
|
+
|
|
951
|
+
indent_down();
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* Writes the structure's static pointer to its local reflection typespec
|
|
956
|
+
* into the implementation file.
|
|
957
|
+
*/
|
|
958
|
+
void t_cpp_generator::generate_local_reflection_pointer(std::ofstream& out,
|
|
959
|
+
t_type* ttype) {
|
|
960
|
+
if (!gen_dense_) {
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
indent(out) <<
|
|
964
|
+
"apache::thrift::reflection::local::TypeSpec* " <<
|
|
965
|
+
ttype->get_name() << "::local_reflection = " << endl <<
|
|
966
|
+
indent() << " &" << local_reflection_name("typespec", ttype) << ";" <<
|
|
967
|
+
endl << endl;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Makes a helper function to gen a struct reader.
|
|
972
|
+
*
|
|
973
|
+
* @param out Stream to write to
|
|
974
|
+
* @param tstruct The struct
|
|
975
|
+
*/
|
|
976
|
+
void t_cpp_generator::generate_struct_reader(ofstream& out,
|
|
977
|
+
t_struct* tstruct,
|
|
978
|
+
bool pointers) {
|
|
979
|
+
indent(out) <<
|
|
980
|
+
"uint32_t " << tstruct->get_name() << "::read(apache::thrift::protocol::TProtocol* iprot) {" << endl;
|
|
981
|
+
indent_up();
|
|
982
|
+
|
|
983
|
+
const vector<t_field*>& fields = tstruct->get_members();
|
|
984
|
+
vector<t_field*>::const_iterator f_iter;
|
|
985
|
+
|
|
986
|
+
// Declare stack tmp variables
|
|
987
|
+
out <<
|
|
988
|
+
endl <<
|
|
989
|
+
indent() << "uint32_t xfer = 0;" << endl <<
|
|
990
|
+
indent() << "std::string fname;" << endl <<
|
|
991
|
+
indent() << "apache::thrift::protocol::TType ftype;" << endl <<
|
|
992
|
+
indent() << "int16_t fid;" << endl <<
|
|
993
|
+
endl <<
|
|
994
|
+
indent() << "xfer += iprot->readStructBegin(fname);" << endl <<
|
|
995
|
+
endl <<
|
|
996
|
+
indent() << "using apache::thrift::protocol::TProtocolException;" << endl <<
|
|
997
|
+
endl;
|
|
998
|
+
|
|
999
|
+
// Required variables aren't in __isset, so we need tmp vars to check them.
|
|
1000
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1001
|
+
if ((*f_iter)->get_req() == t_field::T_REQUIRED)
|
|
1002
|
+
indent(out) << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl;
|
|
1003
|
+
}
|
|
1004
|
+
out << endl;
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
// Loop over reading in fields
|
|
1008
|
+
indent(out) <<
|
|
1009
|
+
"while (true)" << endl;
|
|
1010
|
+
scope_up(out);
|
|
1011
|
+
|
|
1012
|
+
// Read beginning field marker
|
|
1013
|
+
indent(out) <<
|
|
1014
|
+
"xfer += iprot->readFieldBegin(fname, ftype, fid);" << endl;
|
|
1015
|
+
|
|
1016
|
+
// Check for field STOP marker
|
|
1017
|
+
out <<
|
|
1018
|
+
indent() << "if (ftype == apache::thrift::protocol::T_STOP) {" << endl <<
|
|
1019
|
+
indent() << " break;" << endl <<
|
|
1020
|
+
indent() << "}" << endl;
|
|
1021
|
+
|
|
1022
|
+
// Switch statement on the field we are reading
|
|
1023
|
+
indent(out) <<
|
|
1024
|
+
"switch (fid)" << endl;
|
|
1025
|
+
|
|
1026
|
+
scope_up(out);
|
|
1027
|
+
|
|
1028
|
+
// Generate deserialization code for known cases
|
|
1029
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1030
|
+
indent(out) <<
|
|
1031
|
+
"case " << (*f_iter)->get_key() << ":" << endl;
|
|
1032
|
+
indent_up();
|
|
1033
|
+
indent(out) <<
|
|
1034
|
+
"if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
|
|
1035
|
+
indent_up();
|
|
1036
|
+
|
|
1037
|
+
const char *isset_prefix =
|
|
1038
|
+
((*f_iter)->get_req() != t_field::T_REQUIRED) ? "this->__isset." : "isset_";
|
|
1039
|
+
|
|
1040
|
+
#if 0
|
|
1041
|
+
// This code throws an exception if the same field is encountered twice.
|
|
1042
|
+
// We've decided to leave it out for performance reasons.
|
|
1043
|
+
// TODO(dreiss): Generate this code and "if" it out to make it easier
|
|
1044
|
+
// for people recompiling thrift to include it.
|
|
1045
|
+
out <<
|
|
1046
|
+
indent() << "if (" << isset_prefix << (*f_iter)->get_name() << ")" << endl <<
|
|
1047
|
+
indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl;
|
|
1048
|
+
#endif
|
|
1049
|
+
|
|
1050
|
+
if (pointers && !(*f_iter)->get_type()->is_xception()) {
|
|
1051
|
+
generate_deserialize_field(out, *f_iter, "(*(this->", "))");
|
|
1052
|
+
} else {
|
|
1053
|
+
generate_deserialize_field(out, *f_iter, "this->");
|
|
1054
|
+
}
|
|
1055
|
+
out <<
|
|
1056
|
+
indent() << isset_prefix << (*f_iter)->get_name() << " = true;" << endl;
|
|
1057
|
+
indent_down();
|
|
1058
|
+
out <<
|
|
1059
|
+
indent() << "} else {" << endl <<
|
|
1060
|
+
indent() << " xfer += iprot->skip(ftype);" << endl <<
|
|
1061
|
+
// TODO(dreiss): Make this an option when thrift structs
|
|
1062
|
+
// have a common base class.
|
|
1063
|
+
// indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl <<
|
|
1064
|
+
indent() << "}" << endl <<
|
|
1065
|
+
indent() << "break;" << endl;
|
|
1066
|
+
indent_down();
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// In the default case we skip the field
|
|
1070
|
+
out <<
|
|
1071
|
+
indent() << "default:" << endl <<
|
|
1072
|
+
indent() << " xfer += iprot->skip(ftype);" << endl <<
|
|
1073
|
+
indent() << " break;" << endl;
|
|
1074
|
+
|
|
1075
|
+
scope_down(out);
|
|
1076
|
+
|
|
1077
|
+
// Read field end marker
|
|
1078
|
+
indent(out) <<
|
|
1079
|
+
"xfer += iprot->readFieldEnd();" << endl;
|
|
1080
|
+
|
|
1081
|
+
scope_down(out);
|
|
1082
|
+
|
|
1083
|
+
out <<
|
|
1084
|
+
endl <<
|
|
1085
|
+
indent() << "xfer += iprot->readStructEnd();" << endl;
|
|
1086
|
+
|
|
1087
|
+
// Throw if any required fields are missing.
|
|
1088
|
+
// We do this after reading the struct end so that
|
|
1089
|
+
// there might possibly be a chance of continuing.
|
|
1090
|
+
out << endl;
|
|
1091
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1092
|
+
if ((*f_iter)->get_req() == t_field::T_REQUIRED)
|
|
1093
|
+
out <<
|
|
1094
|
+
indent() << "if (!isset_" << (*f_iter)->get_name() << ')' << endl <<
|
|
1095
|
+
indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
indent(out) << "return xfer;" << endl;
|
|
1099
|
+
|
|
1100
|
+
indent_down();
|
|
1101
|
+
indent(out) <<
|
|
1102
|
+
"}" << endl << endl;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* Generates the write function.
|
|
1107
|
+
*
|
|
1108
|
+
* @param out Stream to write to
|
|
1109
|
+
* @param tstruct The struct
|
|
1110
|
+
*/
|
|
1111
|
+
void t_cpp_generator::generate_struct_writer(ofstream& out,
|
|
1112
|
+
t_struct* tstruct,
|
|
1113
|
+
bool pointers) {
|
|
1114
|
+
string name = tstruct->get_name();
|
|
1115
|
+
const vector<t_field*>& fields = tstruct->get_sorted_members();
|
|
1116
|
+
vector<t_field*>::const_iterator f_iter;
|
|
1117
|
+
|
|
1118
|
+
indent(out) <<
|
|
1119
|
+
"uint32_t " << tstruct->get_name() << "::write(apache::thrift::protocol::TProtocol* oprot) const {" << endl;
|
|
1120
|
+
indent_up();
|
|
1121
|
+
|
|
1122
|
+
out <<
|
|
1123
|
+
indent() << "uint32_t xfer = 0;" << endl;
|
|
1124
|
+
|
|
1125
|
+
indent(out) <<
|
|
1126
|
+
"xfer += oprot->writeStructBegin(\"" << name << "\");" << endl;
|
|
1127
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1128
|
+
if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
|
|
1129
|
+
indent(out) << "if (this->__isset." << (*f_iter)->get_name() << ") {" << endl;
|
|
1130
|
+
indent_up();
|
|
1131
|
+
}
|
|
1132
|
+
// Write field header
|
|
1133
|
+
out <<
|
|
1134
|
+
indent() << "xfer += oprot->writeFieldBegin(" <<
|
|
1135
|
+
"\"" << (*f_iter)->get_name() << "\", " <<
|
|
1136
|
+
type_to_enum((*f_iter)->get_type()) << ", " <<
|
|
1137
|
+
(*f_iter)->get_key() << ");" << endl;
|
|
1138
|
+
// Write field contents
|
|
1139
|
+
if (pointers) {
|
|
1140
|
+
generate_serialize_field(out, *f_iter, "(*(this->", "))");
|
|
1141
|
+
} else {
|
|
1142
|
+
generate_serialize_field(out, *f_iter, "this->");
|
|
1143
|
+
}
|
|
1144
|
+
// Write field closer
|
|
1145
|
+
indent(out) <<
|
|
1146
|
+
"xfer += oprot->writeFieldEnd();" << endl;
|
|
1147
|
+
if ((*f_iter)->get_req() == t_field::T_OPTIONAL) {
|
|
1148
|
+
indent_down();
|
|
1149
|
+
indent(out) << '}' << endl;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// Write the struct map
|
|
1154
|
+
out <<
|
|
1155
|
+
indent() << "xfer += oprot->writeFieldStop();" << endl <<
|
|
1156
|
+
indent() << "xfer += oprot->writeStructEnd();" << endl <<
|
|
1157
|
+
indent() << "return xfer;" << endl;
|
|
1158
|
+
|
|
1159
|
+
indent_down();
|
|
1160
|
+
indent(out) <<
|
|
1161
|
+
"}" << endl <<
|
|
1162
|
+
endl;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Struct writer for result of a function, which can have only one of its
|
|
1167
|
+
* fields set and does a conditional if else look up into the __isset field
|
|
1168
|
+
* of the struct.
|
|
1169
|
+
*
|
|
1170
|
+
* @param out Output stream
|
|
1171
|
+
* @param tstruct The result struct
|
|
1172
|
+
*/
|
|
1173
|
+
void t_cpp_generator::generate_struct_result_writer(ofstream& out,
|
|
1174
|
+
t_struct* tstruct,
|
|
1175
|
+
bool pointers) {
|
|
1176
|
+
string name = tstruct->get_name();
|
|
1177
|
+
const vector<t_field*>& fields = tstruct->get_sorted_members();
|
|
1178
|
+
vector<t_field*>::const_iterator f_iter;
|
|
1179
|
+
|
|
1180
|
+
indent(out) <<
|
|
1181
|
+
"uint32_t " << tstruct->get_name() << "::write(apache::thrift::protocol::TProtocol* oprot) const {" << endl;
|
|
1182
|
+
indent_up();
|
|
1183
|
+
|
|
1184
|
+
out <<
|
|
1185
|
+
endl <<
|
|
1186
|
+
indent() << "uint32_t xfer = 0;" << endl <<
|
|
1187
|
+
endl;
|
|
1188
|
+
|
|
1189
|
+
indent(out) <<
|
|
1190
|
+
"xfer += oprot->writeStructBegin(\"" << name << "\");" << endl;
|
|
1191
|
+
|
|
1192
|
+
bool first = true;
|
|
1193
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1194
|
+
if (first) {
|
|
1195
|
+
first = false;
|
|
1196
|
+
out <<
|
|
1197
|
+
endl <<
|
|
1198
|
+
indent() << "if ";
|
|
1199
|
+
} else {
|
|
1200
|
+
out <<
|
|
1201
|
+
" else if ";
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl;
|
|
1205
|
+
|
|
1206
|
+
indent_up();
|
|
1207
|
+
|
|
1208
|
+
// Write field header
|
|
1209
|
+
out <<
|
|
1210
|
+
indent() << "xfer += oprot->writeFieldBegin(" <<
|
|
1211
|
+
"\"" << (*f_iter)->get_name() << "\", " <<
|
|
1212
|
+
type_to_enum((*f_iter)->get_type()) << ", " <<
|
|
1213
|
+
(*f_iter)->get_key() << ");" << endl;
|
|
1214
|
+
// Write field contents
|
|
1215
|
+
if (pointers) {
|
|
1216
|
+
generate_serialize_field(out, *f_iter, "(*(this->", "))");
|
|
1217
|
+
} else {
|
|
1218
|
+
generate_serialize_field(out, *f_iter, "this->");
|
|
1219
|
+
}
|
|
1220
|
+
// Write field closer
|
|
1221
|
+
indent(out) << "xfer += oprot->writeFieldEnd();" << endl;
|
|
1222
|
+
|
|
1223
|
+
indent_down();
|
|
1224
|
+
indent(out) << "}";
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// Write the struct map
|
|
1228
|
+
out <<
|
|
1229
|
+
endl <<
|
|
1230
|
+
indent() << "xfer += oprot->writeFieldStop();" << endl <<
|
|
1231
|
+
indent() << "xfer += oprot->writeStructEnd();" << endl <<
|
|
1232
|
+
indent() << "return xfer;" << endl;
|
|
1233
|
+
|
|
1234
|
+
indent_down();
|
|
1235
|
+
indent(out) <<
|
|
1236
|
+
"}" << endl <<
|
|
1237
|
+
endl;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* Generates a thrift service. In C++, this comprises an entirely separate
|
|
1242
|
+
* header and source file. The header file defines the methods and includes
|
|
1243
|
+
* the data types defined in the main header file, and the implementation
|
|
1244
|
+
* file contains implementations of the basic printer and default interfaces.
|
|
1245
|
+
*
|
|
1246
|
+
* @param tservice The service definition
|
|
1247
|
+
*/
|
|
1248
|
+
void t_cpp_generator::generate_service(t_service* tservice) {
|
|
1249
|
+
string svcname = tservice->get_name();
|
|
1250
|
+
|
|
1251
|
+
// Make output files
|
|
1252
|
+
string f_header_name = get_out_dir()+svcname+".h";
|
|
1253
|
+
f_header_.open(f_header_name.c_str());
|
|
1254
|
+
|
|
1255
|
+
// Print header file includes
|
|
1256
|
+
f_header_ <<
|
|
1257
|
+
autogen_comment();
|
|
1258
|
+
f_header_ <<
|
|
1259
|
+
"#ifndef " << svcname << "_H" << endl <<
|
|
1260
|
+
"#define " << svcname << "_H" << endl <<
|
|
1261
|
+
endl <<
|
|
1262
|
+
"#include <TProcessor.h>" << endl <<
|
|
1263
|
+
"#include \"" << get_include_prefix(*get_program()) << program_name_ <<
|
|
1264
|
+
"_types.h\"" << endl;
|
|
1265
|
+
|
|
1266
|
+
t_service* extends_service = tservice->get_extends();
|
|
1267
|
+
if (extends_service != NULL) {
|
|
1268
|
+
f_header_ <<
|
|
1269
|
+
"#include \"" << get_include_prefix(*(extends_service->get_program())) <<
|
|
1270
|
+
extends_service->get_name() << ".h\"" << endl;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
f_header_ <<
|
|
1274
|
+
endl <<
|
|
1275
|
+
ns_open_ << endl <<
|
|
1276
|
+
endl;
|
|
1277
|
+
|
|
1278
|
+
// Service implementation file includes
|
|
1279
|
+
string f_service_name = get_out_dir()+svcname+".cpp";
|
|
1280
|
+
f_service_.open(f_service_name.c_str());
|
|
1281
|
+
f_service_ <<
|
|
1282
|
+
autogen_comment();
|
|
1283
|
+
f_service_ <<
|
|
1284
|
+
"#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" <<
|
|
1285
|
+
endl <<
|
|
1286
|
+
endl <<
|
|
1287
|
+
ns_open_ << endl <<
|
|
1288
|
+
endl;
|
|
1289
|
+
|
|
1290
|
+
// Generate all the components
|
|
1291
|
+
generate_service_interface(tservice);
|
|
1292
|
+
generate_service_null(tservice);
|
|
1293
|
+
generate_service_helpers(tservice);
|
|
1294
|
+
generate_service_client(tservice);
|
|
1295
|
+
generate_service_processor(tservice);
|
|
1296
|
+
generate_service_multiface(tservice);
|
|
1297
|
+
generate_service_skeleton(tservice);
|
|
1298
|
+
|
|
1299
|
+
// Close the namespace
|
|
1300
|
+
f_service_ <<
|
|
1301
|
+
ns_close_ << endl <<
|
|
1302
|
+
endl;
|
|
1303
|
+
f_header_ <<
|
|
1304
|
+
ns_close_ << endl <<
|
|
1305
|
+
endl;
|
|
1306
|
+
f_header_ <<
|
|
1307
|
+
"#endif" << endl;
|
|
1308
|
+
|
|
1309
|
+
// Close the files
|
|
1310
|
+
f_service_.close();
|
|
1311
|
+
f_header_.close();
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* Generates helper functions for a service. Basically, this generates types
|
|
1316
|
+
* for all the arguments and results to functions.
|
|
1317
|
+
*
|
|
1318
|
+
* @param tservice The service to generate a header definition for
|
|
1319
|
+
*/
|
|
1320
|
+
void t_cpp_generator::generate_service_helpers(t_service* tservice) {
|
|
1321
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1322
|
+
vector<t_function*>::iterator f_iter;
|
|
1323
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1324
|
+
t_struct* ts = (*f_iter)->get_arglist();
|
|
1325
|
+
string name_orig = ts->get_name();
|
|
1326
|
+
|
|
1327
|
+
ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_args");
|
|
1328
|
+
generate_struct_definition(f_header_, ts, false);
|
|
1329
|
+
generate_struct_reader(f_service_, ts);
|
|
1330
|
+
generate_struct_writer(f_service_, ts);
|
|
1331
|
+
ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs");
|
|
1332
|
+
generate_struct_definition(f_header_, ts, false, true, false, true);
|
|
1333
|
+
generate_struct_writer(f_service_, ts, true);
|
|
1334
|
+
ts->set_name(name_orig);
|
|
1335
|
+
|
|
1336
|
+
generate_function_helpers(tservice, *f_iter);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* Generates a service interface definition.
|
|
1342
|
+
*
|
|
1343
|
+
* @param tservice The service to generate a header definition for
|
|
1344
|
+
*/
|
|
1345
|
+
void t_cpp_generator::generate_service_interface(t_service* tservice) {
|
|
1346
|
+
string extends = "";
|
|
1347
|
+
if (tservice->get_extends() != NULL) {
|
|
1348
|
+
extends = " : virtual public " + type_name(tservice->get_extends()) + "If";
|
|
1349
|
+
}
|
|
1350
|
+
f_header_ <<
|
|
1351
|
+
"class " << service_name_ << "If" << extends << " {" << endl <<
|
|
1352
|
+
" public:" << endl;
|
|
1353
|
+
indent_up();
|
|
1354
|
+
f_header_ <<
|
|
1355
|
+
indent() << "virtual ~" << service_name_ << "If() {}" << endl;
|
|
1356
|
+
|
|
1357
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1358
|
+
vector<t_function*>::iterator f_iter;
|
|
1359
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1360
|
+
f_header_ <<
|
|
1361
|
+
indent() << "virtual " << function_signature(*f_iter) << " = 0;" << endl;
|
|
1362
|
+
}
|
|
1363
|
+
indent_down();
|
|
1364
|
+
f_header_ <<
|
|
1365
|
+
"};" << endl << endl;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Generates a null implementation of the service.
|
|
1370
|
+
*
|
|
1371
|
+
* @param tservice The service to generate a header definition for
|
|
1372
|
+
*/
|
|
1373
|
+
void t_cpp_generator::generate_service_null(t_service* tservice) {
|
|
1374
|
+
string extends = "";
|
|
1375
|
+
if (tservice->get_extends() != NULL) {
|
|
1376
|
+
extends = " , virtual public " + type_name(tservice->get_extends()) + "Null";
|
|
1377
|
+
}
|
|
1378
|
+
f_header_ <<
|
|
1379
|
+
"class " << service_name_ << "Null : virtual public " << service_name_ << "If" << extends << " {" << endl <<
|
|
1380
|
+
" public:" << endl;
|
|
1381
|
+
indent_up();
|
|
1382
|
+
f_header_ <<
|
|
1383
|
+
indent() << "virtual ~" << service_name_ << "Null() {}" << endl;
|
|
1384
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1385
|
+
vector<t_function*>::iterator f_iter;
|
|
1386
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1387
|
+
f_header_ <<
|
|
1388
|
+
indent() << function_signature(*f_iter, "", false) << " {" << endl;
|
|
1389
|
+
indent_up();
|
|
1390
|
+
t_type* returntype = (*f_iter)->get_returntype();
|
|
1391
|
+
if (returntype->is_void()) {
|
|
1392
|
+
f_header_ <<
|
|
1393
|
+
indent() << "return;" << endl;
|
|
1394
|
+
} else if (is_complex_type(returntype)) {
|
|
1395
|
+
f_header_ <<
|
|
1396
|
+
indent() << "return;" << endl;
|
|
1397
|
+
} else {
|
|
1398
|
+
t_field returnfield(returntype, "_return");
|
|
1399
|
+
f_header_ <<
|
|
1400
|
+
indent() << declare_field(&returnfield, true) << endl <<
|
|
1401
|
+
indent() << "return _return;" << endl;
|
|
1402
|
+
}
|
|
1403
|
+
indent_down();
|
|
1404
|
+
f_header_ <<
|
|
1405
|
+
indent() << "}" << endl;
|
|
1406
|
+
}
|
|
1407
|
+
indent_down();
|
|
1408
|
+
f_header_ <<
|
|
1409
|
+
"};" << endl << endl;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
/**
|
|
1414
|
+
* Generates a multiface, which is a single server that just takes a set
|
|
1415
|
+
* of objects implementing the interface and calls them all, returning the
|
|
1416
|
+
* value of the last one to be called.
|
|
1417
|
+
*
|
|
1418
|
+
* @param tservice The service to generate a multiserver for.
|
|
1419
|
+
*/
|
|
1420
|
+
void t_cpp_generator::generate_service_multiface(t_service* tservice) {
|
|
1421
|
+
// Generate the dispatch methods
|
|
1422
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1423
|
+
vector<t_function*>::iterator f_iter;
|
|
1424
|
+
|
|
1425
|
+
string extends = "";
|
|
1426
|
+
string extends_multiface = "";
|
|
1427
|
+
if (tservice->get_extends() != NULL) {
|
|
1428
|
+
extends = type_name(tservice->get_extends());
|
|
1429
|
+
extends_multiface = ", public " + extends + "Multiface";
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
string list_type = string("std::vector<boost::shared_ptr<") + service_name_ + "If> >";
|
|
1433
|
+
|
|
1434
|
+
// Generate the header portion
|
|
1435
|
+
f_header_ <<
|
|
1436
|
+
"class " << service_name_ << "Multiface : " <<
|
|
1437
|
+
"virtual public " << service_name_ << "If" <<
|
|
1438
|
+
extends_multiface << " {" << endl <<
|
|
1439
|
+
" public:" << endl;
|
|
1440
|
+
indent_up();
|
|
1441
|
+
f_header_ <<
|
|
1442
|
+
indent() << service_name_ << "Multiface(" << list_type << "& ifaces) : ifaces_(ifaces) {" << endl;
|
|
1443
|
+
if (!extends.empty()) {
|
|
1444
|
+
f_header_ <<
|
|
1445
|
+
indent() << " std::vector<boost::shared_ptr<" + service_name_ + "If> >::iterator iter;" << endl <<
|
|
1446
|
+
indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {" << endl <<
|
|
1447
|
+
indent() << " " << extends << "Multiface::add(*iter);" << endl <<
|
|
1448
|
+
indent() << " }" << endl;
|
|
1449
|
+
}
|
|
1450
|
+
f_header_ <<
|
|
1451
|
+
indent() << "}" << endl <<
|
|
1452
|
+
indent() << "virtual ~" << service_name_ << "Multiface() {}" << endl;
|
|
1453
|
+
indent_down();
|
|
1454
|
+
|
|
1455
|
+
// Protected data members
|
|
1456
|
+
f_header_ <<
|
|
1457
|
+
" protected:" << endl;
|
|
1458
|
+
indent_up();
|
|
1459
|
+
f_header_ <<
|
|
1460
|
+
indent() << list_type << " ifaces_;" << endl <<
|
|
1461
|
+
indent() << service_name_ << "Multiface() {}" << endl <<
|
|
1462
|
+
indent() << "void add(boost::shared_ptr<" << service_name_ << "If> iface) {" << endl;
|
|
1463
|
+
if (!extends.empty()) {
|
|
1464
|
+
f_header_ <<
|
|
1465
|
+
indent() << " " << extends << "Multiface::add(iface);" << endl;
|
|
1466
|
+
}
|
|
1467
|
+
f_header_ <<
|
|
1468
|
+
indent() << " ifaces_.push_back(iface);" << endl <<
|
|
1469
|
+
indent() << "}" << endl;
|
|
1470
|
+
indent_down();
|
|
1471
|
+
|
|
1472
|
+
f_header_ <<
|
|
1473
|
+
indent() << " public:" << endl;
|
|
1474
|
+
indent_up();
|
|
1475
|
+
|
|
1476
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1477
|
+
t_struct* arglist = (*f_iter)->get_arglist();
|
|
1478
|
+
const vector<t_field*>& args = arglist->get_members();
|
|
1479
|
+
vector<t_field*>::const_iterator a_iter;
|
|
1480
|
+
|
|
1481
|
+
string call = string("ifaces_[i]->") + (*f_iter)->get_name() + "(";
|
|
1482
|
+
bool first = true;
|
|
1483
|
+
if (is_complex_type((*f_iter)->get_returntype())) {
|
|
1484
|
+
call += "_return";
|
|
1485
|
+
first = false;
|
|
1486
|
+
}
|
|
1487
|
+
for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
|
|
1488
|
+
if (first) {
|
|
1489
|
+
first = false;
|
|
1490
|
+
} else {
|
|
1491
|
+
call += ", ";
|
|
1492
|
+
}
|
|
1493
|
+
call += (*a_iter)->get_name();
|
|
1494
|
+
}
|
|
1495
|
+
call += ")";
|
|
1496
|
+
|
|
1497
|
+
f_header_ <<
|
|
1498
|
+
indent() << function_signature(*f_iter) << " {" << endl;
|
|
1499
|
+
indent_up();
|
|
1500
|
+
f_header_ <<
|
|
1501
|
+
indent() << "uint32_t sz = ifaces_.size();" << endl <<
|
|
1502
|
+
indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl;
|
|
1503
|
+
if (!(*f_iter)->get_returntype()->is_void()) {
|
|
1504
|
+
f_header_ <<
|
|
1505
|
+
indent() << " if (i == sz - 1) {" << endl;
|
|
1506
|
+
if (is_complex_type((*f_iter)->get_returntype())) {
|
|
1507
|
+
f_header_ <<
|
|
1508
|
+
indent() << " " << call << ";" << endl <<
|
|
1509
|
+
indent() << " return;" << endl;
|
|
1510
|
+
} else {
|
|
1511
|
+
f_header_ <<
|
|
1512
|
+
indent() << " return " << call << ";" << endl;
|
|
1513
|
+
}
|
|
1514
|
+
f_header_ <<
|
|
1515
|
+
indent() << " } else {" << endl <<
|
|
1516
|
+
indent() << " " << call << ";" << endl <<
|
|
1517
|
+
indent() << " }" << endl;
|
|
1518
|
+
} else {
|
|
1519
|
+
f_header_ <<
|
|
1520
|
+
indent() << " " << call << ";" << endl;
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
f_header_ <<
|
|
1524
|
+
indent() << "}" << endl;
|
|
1525
|
+
|
|
1526
|
+
indent_down();
|
|
1527
|
+
f_header_ <<
|
|
1528
|
+
indent() << "}" << endl <<
|
|
1529
|
+
endl;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
indent_down();
|
|
1533
|
+
f_header_ <<
|
|
1534
|
+
indent() << "};" << endl <<
|
|
1535
|
+
endl;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* Generates a service client definition.
|
|
1540
|
+
*
|
|
1541
|
+
* @param tservice The service to generate a server for.
|
|
1542
|
+
*/
|
|
1543
|
+
void t_cpp_generator::generate_service_client(t_service* tservice) {
|
|
1544
|
+
string extends = "";
|
|
1545
|
+
string extends_client = "";
|
|
1546
|
+
if (tservice->get_extends() != NULL) {
|
|
1547
|
+
extends = type_name(tservice->get_extends());
|
|
1548
|
+
extends_client = ", public " + extends + "Client";
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
// Generate the header portion
|
|
1552
|
+
f_header_ <<
|
|
1553
|
+
"class " << service_name_ << "Client : " <<
|
|
1554
|
+
"virtual public " << service_name_ << "If" <<
|
|
1555
|
+
extends_client << " {" << endl <<
|
|
1556
|
+
" public:" << endl;
|
|
1557
|
+
|
|
1558
|
+
indent_up();
|
|
1559
|
+
f_header_ <<
|
|
1560
|
+
indent() << service_name_ << "Client(boost::shared_ptr<apache::thrift::protocol::TProtocol> prot) :" << endl;
|
|
1561
|
+
if (extends.empty()) {
|
|
1562
|
+
f_header_ <<
|
|
1563
|
+
indent() << " piprot_(prot)," << endl <<
|
|
1564
|
+
indent() << " poprot_(prot) {" << endl <<
|
|
1565
|
+
indent() << " iprot_ = prot.get();" << endl <<
|
|
1566
|
+
indent() << " oprot_ = prot.get();" << endl <<
|
|
1567
|
+
indent() << "}" << endl;
|
|
1568
|
+
} else {
|
|
1569
|
+
f_header_ <<
|
|
1570
|
+
indent() << " " << extends << "Client(prot, prot) {}" << endl;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
f_header_ <<
|
|
1574
|
+
indent() << service_name_ << "Client(boost::shared_ptr<apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr<apache::thrift::protocol::TProtocol> oprot) :" << endl;
|
|
1575
|
+
if (extends.empty()) {
|
|
1576
|
+
f_header_ <<
|
|
1577
|
+
indent() << " piprot_(iprot)," << endl <<
|
|
1578
|
+
indent() << " poprot_(oprot) {" << endl <<
|
|
1579
|
+
indent() << " iprot_ = iprot.get();" << endl <<
|
|
1580
|
+
indent() << " oprot_ = oprot.get();" << endl <<
|
|
1581
|
+
indent() << "}" << endl;
|
|
1582
|
+
} else {
|
|
1583
|
+
f_header_ <<
|
|
1584
|
+
indent() << " " << extends << "Client(iprot, oprot) {}" << endl;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
// Generate getters for the protocols.
|
|
1588
|
+
f_header_ <<
|
|
1589
|
+
indent() << "boost::shared_ptr<apache::thrift::protocol::TProtocol> getInputProtocol() {" << endl <<
|
|
1590
|
+
indent() << " return piprot_;" << endl <<
|
|
1591
|
+
indent() << "}" << endl;
|
|
1592
|
+
|
|
1593
|
+
f_header_ <<
|
|
1594
|
+
indent() << "boost::shared_ptr<apache::thrift::protocol::TProtocol> getOutputProtocol() {" << endl <<
|
|
1595
|
+
indent() << " return poprot_;" << endl <<
|
|
1596
|
+
indent() << "}" << endl;
|
|
1597
|
+
|
|
1598
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1599
|
+
vector<t_function*>::const_iterator f_iter;
|
|
1600
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1601
|
+
t_function send_function(g_type_void,
|
|
1602
|
+
string("send_") + (*f_iter)->get_name(),
|
|
1603
|
+
(*f_iter)->get_arglist());
|
|
1604
|
+
indent(f_header_) << function_signature(*f_iter) << ";" << endl;
|
|
1605
|
+
indent(f_header_) << function_signature(&send_function) << ";" << endl;
|
|
1606
|
+
if (!(*f_iter)->is_oneway()) {
|
|
1607
|
+
t_struct noargs(program_);
|
|
1608
|
+
t_function recv_function((*f_iter)->get_returntype(),
|
|
1609
|
+
string("recv_") + (*f_iter)->get_name(),
|
|
1610
|
+
&noargs);
|
|
1611
|
+
indent(f_header_) << function_signature(&recv_function) << ";" << endl;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
indent_down();
|
|
1615
|
+
|
|
1616
|
+
if (extends.empty()) {
|
|
1617
|
+
f_header_ <<
|
|
1618
|
+
" protected:" << endl;
|
|
1619
|
+
indent_up();
|
|
1620
|
+
f_header_ <<
|
|
1621
|
+
indent() << "boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;" << endl <<
|
|
1622
|
+
indent() << "boost::shared_ptr<apache::thrift::protocol::TProtocol> poprot_;" << endl <<
|
|
1623
|
+
indent() << "apache::thrift::protocol::TProtocol* iprot_;" << endl <<
|
|
1624
|
+
indent() << "apache::thrift::protocol::TProtocol* oprot_;" << endl;
|
|
1625
|
+
indent_down();
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
f_header_ <<
|
|
1629
|
+
"};" << endl <<
|
|
1630
|
+
endl;
|
|
1631
|
+
|
|
1632
|
+
string scope = service_name_ + "Client::";
|
|
1633
|
+
|
|
1634
|
+
// Generate client method implementations
|
|
1635
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1636
|
+
string funname = (*f_iter)->get_name();
|
|
1637
|
+
|
|
1638
|
+
// Open function
|
|
1639
|
+
indent(f_service_) <<
|
|
1640
|
+
function_signature(*f_iter, scope) << endl;
|
|
1641
|
+
scope_up(f_service_);
|
|
1642
|
+
indent(f_service_) <<
|
|
1643
|
+
"send_" << funname << "(";
|
|
1644
|
+
|
|
1645
|
+
// Get the struct of function call params
|
|
1646
|
+
t_struct* arg_struct = (*f_iter)->get_arglist();
|
|
1647
|
+
|
|
1648
|
+
// Declare the function arguments
|
|
1649
|
+
const vector<t_field*>& fields = arg_struct->get_members();
|
|
1650
|
+
vector<t_field*>::const_iterator fld_iter;
|
|
1651
|
+
bool first = true;
|
|
1652
|
+
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
|
|
1653
|
+
if (first) {
|
|
1654
|
+
first = false;
|
|
1655
|
+
} else {
|
|
1656
|
+
f_service_ << ", ";
|
|
1657
|
+
}
|
|
1658
|
+
f_service_ << (*fld_iter)->get_name();
|
|
1659
|
+
}
|
|
1660
|
+
f_service_ << ");" << endl;
|
|
1661
|
+
|
|
1662
|
+
if (!(*f_iter)->is_oneway()) {
|
|
1663
|
+
f_service_ << indent();
|
|
1664
|
+
if (!(*f_iter)->get_returntype()->is_void()) {
|
|
1665
|
+
if (is_complex_type((*f_iter)->get_returntype())) {
|
|
1666
|
+
f_service_ << "recv_" << funname << "(_return);" << endl;
|
|
1667
|
+
} else {
|
|
1668
|
+
f_service_ << "return recv_" << funname << "();" << endl;
|
|
1669
|
+
}
|
|
1670
|
+
} else {
|
|
1671
|
+
f_service_ <<
|
|
1672
|
+
"recv_" << funname << "();" << endl;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
scope_down(f_service_);
|
|
1676
|
+
f_service_ << endl;
|
|
1677
|
+
|
|
1678
|
+
// Function for sending
|
|
1679
|
+
t_function send_function(g_type_void,
|
|
1680
|
+
string("send_") + (*f_iter)->get_name(),
|
|
1681
|
+
(*f_iter)->get_arglist());
|
|
1682
|
+
|
|
1683
|
+
// Open the send function
|
|
1684
|
+
indent(f_service_) <<
|
|
1685
|
+
function_signature(&send_function, scope) << endl;
|
|
1686
|
+
scope_up(f_service_);
|
|
1687
|
+
|
|
1688
|
+
// Function arguments and results
|
|
1689
|
+
string argsname = tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs";
|
|
1690
|
+
string resultname = tservice->get_name() + "_" + (*f_iter)->get_name() + "_presult";
|
|
1691
|
+
|
|
1692
|
+
// Serialize the request
|
|
1693
|
+
f_service_ <<
|
|
1694
|
+
indent() << "int32_t cseqid = 0;" << endl <<
|
|
1695
|
+
indent() << "oprot_->writeMessageBegin(\"" << (*f_iter)->get_name() << "\", apache::thrift::protocol::T_CALL, cseqid);" << endl <<
|
|
1696
|
+
endl <<
|
|
1697
|
+
indent() << argsname << " args;" << endl;
|
|
1698
|
+
|
|
1699
|
+
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
|
|
1700
|
+
f_service_ <<
|
|
1701
|
+
indent() << "args." << (*fld_iter)->get_name() << " = &" << (*fld_iter)->get_name() << ";" << endl;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
f_service_ <<
|
|
1705
|
+
indent() << "args.write(oprot_);" << endl <<
|
|
1706
|
+
endl <<
|
|
1707
|
+
indent() << "oprot_->writeMessageEnd();" << endl <<
|
|
1708
|
+
indent() << "oprot_->getTransport()->flush();" << endl <<
|
|
1709
|
+
indent() << "oprot_->getTransport()->writeEnd();" << endl;
|
|
1710
|
+
|
|
1711
|
+
scope_down(f_service_);
|
|
1712
|
+
f_service_ << endl;
|
|
1713
|
+
|
|
1714
|
+
// Generate recv function only if not an oneway function
|
|
1715
|
+
if (!(*f_iter)->is_oneway()) {
|
|
1716
|
+
t_struct noargs(program_);
|
|
1717
|
+
t_function recv_function((*f_iter)->get_returntype(),
|
|
1718
|
+
string("recv_") + (*f_iter)->get_name(),
|
|
1719
|
+
&noargs);
|
|
1720
|
+
// Open function
|
|
1721
|
+
indent(f_service_) <<
|
|
1722
|
+
function_signature(&recv_function, scope) << endl;
|
|
1723
|
+
scope_up(f_service_);
|
|
1724
|
+
|
|
1725
|
+
f_service_ <<
|
|
1726
|
+
endl <<
|
|
1727
|
+
indent() << "int32_t rseqid = 0;" << endl <<
|
|
1728
|
+
indent() << "std::string fname;" << endl <<
|
|
1729
|
+
indent() << "apache::thrift::protocol::TMessageType mtype;" << endl <<
|
|
1730
|
+
endl <<
|
|
1731
|
+
indent() << "iprot_->readMessageBegin(fname, mtype, rseqid);" << endl <<
|
|
1732
|
+
indent() << "if (mtype == apache::thrift::protocol::T_EXCEPTION) {" << endl <<
|
|
1733
|
+
indent() << " apache::thrift::TApplicationException x;" << endl <<
|
|
1734
|
+
indent() << " x.read(iprot_);" << endl <<
|
|
1735
|
+
indent() << " iprot_->readMessageEnd();" << endl <<
|
|
1736
|
+
indent() << " iprot_->getTransport()->readEnd();" << endl <<
|
|
1737
|
+
indent() << " throw x;" << endl <<
|
|
1738
|
+
indent() << "}" << endl <<
|
|
1739
|
+
indent() << "if (mtype != apache::thrift::protocol::T_REPLY) {" << endl <<
|
|
1740
|
+
indent() << " iprot_->skip(apache::thrift::protocol::T_STRUCT);" << endl <<
|
|
1741
|
+
indent() << " iprot_->readMessageEnd();" << endl <<
|
|
1742
|
+
indent() << " iprot_->getTransport()->readEnd();" << endl <<
|
|
1743
|
+
indent() << " throw apache::thrift::TApplicationException(apache::thrift::TApplicationException::INVALID_MESSAGE_TYPE);" << endl <<
|
|
1744
|
+
indent() << "}" << endl <<
|
|
1745
|
+
indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << endl <<
|
|
1746
|
+
indent() << " iprot_->skip(apache::thrift::protocol::T_STRUCT);" << endl <<
|
|
1747
|
+
indent() << " iprot_->readMessageEnd();" << endl <<
|
|
1748
|
+
indent() << " iprot_->getTransport()->readEnd();" << endl <<
|
|
1749
|
+
indent() << " throw apache::thrift::TApplicationException(apache::thrift::TApplicationException::WRONG_METHOD_NAME);" << endl <<
|
|
1750
|
+
indent() << "}" << endl;
|
|
1751
|
+
|
|
1752
|
+
if (!(*f_iter)->get_returntype()->is_void() &&
|
|
1753
|
+
!is_complex_type((*f_iter)->get_returntype())) {
|
|
1754
|
+
t_field returnfield((*f_iter)->get_returntype(), "_return");
|
|
1755
|
+
f_service_ <<
|
|
1756
|
+
indent() << declare_field(&returnfield) << endl;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
f_service_ <<
|
|
1760
|
+
indent() << resultname << " result;" << endl;
|
|
1761
|
+
|
|
1762
|
+
if (!(*f_iter)->get_returntype()->is_void()) {
|
|
1763
|
+
f_service_ <<
|
|
1764
|
+
indent() << "result.success = &_return;" << endl;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
f_service_ <<
|
|
1768
|
+
indent() << "result.read(iprot_);" << endl <<
|
|
1769
|
+
indent() << "iprot_->readMessageEnd();" << endl <<
|
|
1770
|
+
indent() << "iprot_->getTransport()->readEnd();" << endl <<
|
|
1771
|
+
endl;
|
|
1772
|
+
|
|
1773
|
+
// Careful, only look for _result if not a void function
|
|
1774
|
+
if (!(*f_iter)->get_returntype()->is_void()) {
|
|
1775
|
+
if (is_complex_type((*f_iter)->get_returntype())) {
|
|
1776
|
+
f_service_ <<
|
|
1777
|
+
indent() << "if (result.__isset.success) {" << endl <<
|
|
1778
|
+
indent() << " // _return pointer has now been filled" << endl <<
|
|
1779
|
+
indent() << " return;" << endl <<
|
|
1780
|
+
indent() << "}" << endl;
|
|
1781
|
+
} else {
|
|
1782
|
+
f_service_ <<
|
|
1783
|
+
indent() << "if (result.__isset.success) {" << endl <<
|
|
1784
|
+
indent() << " return _return;" << endl <<
|
|
1785
|
+
indent() << "}" << endl;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
t_struct* xs = (*f_iter)->get_xceptions();
|
|
1790
|
+
const std::vector<t_field*>& xceptions = xs->get_members();
|
|
1791
|
+
vector<t_field*>::const_iterator x_iter;
|
|
1792
|
+
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
|
|
1793
|
+
f_service_ <<
|
|
1794
|
+
indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
|
|
1795
|
+
indent() << " throw result." << (*x_iter)->get_name() << ";" << endl <<
|
|
1796
|
+
indent() << "}" << endl;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
// We only get here if we are a void function
|
|
1800
|
+
if ((*f_iter)->get_returntype()->is_void()) {
|
|
1801
|
+
indent(f_service_) <<
|
|
1802
|
+
"return;" << endl;
|
|
1803
|
+
} else {
|
|
1804
|
+
f_service_ <<
|
|
1805
|
+
indent() << "throw apache::thrift::TApplicationException(apache::thrift::TApplicationException::MISSING_RESULT, \"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
// Close function
|
|
1809
|
+
scope_down(f_service_);
|
|
1810
|
+
f_service_ << endl;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
/**
|
|
1816
|
+
* Generates a service server definition.
|
|
1817
|
+
*
|
|
1818
|
+
* @param tservice The service to generate a server for.
|
|
1819
|
+
*/
|
|
1820
|
+
void t_cpp_generator::generate_service_processor(t_service* tservice) {
|
|
1821
|
+
// Generate the dispatch methods
|
|
1822
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
1823
|
+
vector<t_function*>::iterator f_iter;
|
|
1824
|
+
|
|
1825
|
+
string extends = "";
|
|
1826
|
+
string extends_processor = "";
|
|
1827
|
+
if (tservice->get_extends() != NULL) {
|
|
1828
|
+
extends = type_name(tservice->get_extends());
|
|
1829
|
+
extends_processor = ", public " + extends + "Processor";
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// Generate the header portion
|
|
1833
|
+
f_header_ <<
|
|
1834
|
+
"class " << service_name_ << "Processor : " <<
|
|
1835
|
+
"virtual public apache::thrift::TProcessor" <<
|
|
1836
|
+
extends_processor << " {" << endl;
|
|
1837
|
+
|
|
1838
|
+
// Protected data members
|
|
1839
|
+
f_header_ <<
|
|
1840
|
+
" protected:" << endl;
|
|
1841
|
+
indent_up();
|
|
1842
|
+
f_header_ <<
|
|
1843
|
+
indent() << "boost::shared_ptr<" << service_name_ << "If> iface_;" << endl;
|
|
1844
|
+
f_header_ <<
|
|
1845
|
+
indent() << "virtual bool process_fn(apache::thrift::protocol::TProtocol* iprot, apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid);" << endl;
|
|
1846
|
+
indent_down();
|
|
1847
|
+
|
|
1848
|
+
// Process function declarations
|
|
1849
|
+
f_header_ <<
|
|
1850
|
+
" private:" << endl;
|
|
1851
|
+
indent_up();
|
|
1852
|
+
f_header_ <<
|
|
1853
|
+
indent() << "std::map<std::string, void (" << service_name_ << "Processor::*)(int32_t, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*)> processMap_;" << endl;
|
|
1854
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1855
|
+
indent(f_header_) <<
|
|
1856
|
+
"void process_" << (*f_iter)->get_name() << "(int32_t seqid, apache::thrift::protocol::TProtocol* iprot, apache::thrift::protocol::TProtocol* oprot);" << endl;
|
|
1857
|
+
}
|
|
1858
|
+
indent_down();
|
|
1859
|
+
|
|
1860
|
+
indent_up();
|
|
1861
|
+
string declare_map = "";
|
|
1862
|
+
indent_up();
|
|
1863
|
+
|
|
1864
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1865
|
+
declare_map += indent();
|
|
1866
|
+
declare_map += "processMap_[\"";
|
|
1867
|
+
declare_map += (*f_iter)->get_name();
|
|
1868
|
+
declare_map += "\"] = &";
|
|
1869
|
+
declare_map += service_name_;
|
|
1870
|
+
declare_map += "Processor::process_";
|
|
1871
|
+
declare_map += (*f_iter)->get_name();
|
|
1872
|
+
declare_map += ";\n";
|
|
1873
|
+
}
|
|
1874
|
+
indent_down();
|
|
1875
|
+
|
|
1876
|
+
f_header_ <<
|
|
1877
|
+
" public:" << endl <<
|
|
1878
|
+
indent() << service_name_ << "Processor(boost::shared_ptr<" << service_name_ << "If> iface) :" << endl;
|
|
1879
|
+
if (extends.empty()) {
|
|
1880
|
+
f_header_ <<
|
|
1881
|
+
indent() << " iface_(iface) {" << endl;
|
|
1882
|
+
} else {
|
|
1883
|
+
f_header_ <<
|
|
1884
|
+
indent() << " " << extends << "Processor(iface)," << endl <<
|
|
1885
|
+
indent() << " iface_(iface) {" << endl;
|
|
1886
|
+
}
|
|
1887
|
+
f_header_ <<
|
|
1888
|
+
declare_map <<
|
|
1889
|
+
indent() << "}" << endl <<
|
|
1890
|
+
endl <<
|
|
1891
|
+
indent() << "virtual bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr<apache::thrift::protocol::TProtocol> poprot);" << endl <<
|
|
1892
|
+
indent() << "virtual ~" << service_name_ << "Processor() {}" << endl;
|
|
1893
|
+
indent_down();
|
|
1894
|
+
f_header_ <<
|
|
1895
|
+
"};" << endl << endl;
|
|
1896
|
+
|
|
1897
|
+
// Generate the server implementation
|
|
1898
|
+
f_service_ <<
|
|
1899
|
+
"bool " << service_name_ << "Processor::process(boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr<apache::thrift::protocol::TProtocol> poprot) {" << endl;
|
|
1900
|
+
indent_up();
|
|
1901
|
+
|
|
1902
|
+
f_service_ <<
|
|
1903
|
+
endl <<
|
|
1904
|
+
indent() << "apache::thrift::protocol::TProtocol* iprot = piprot.get();" << endl <<
|
|
1905
|
+
indent() << "apache::thrift::protocol::TProtocol* oprot = poprot.get();" << endl <<
|
|
1906
|
+
indent() << "std::string fname;" << endl <<
|
|
1907
|
+
indent() << "apache::thrift::protocol::TMessageType mtype;" << endl <<
|
|
1908
|
+
indent() << "int32_t seqid;" << endl <<
|
|
1909
|
+
endl <<
|
|
1910
|
+
indent() << "iprot->readMessageBegin(fname, mtype, seqid);" << endl <<
|
|
1911
|
+
endl <<
|
|
1912
|
+
indent() << "if (mtype != apache::thrift::protocol::T_CALL && mtype != apache::thrift::protocol::T_ONEWAY) {" << endl <<
|
|
1913
|
+
indent() << " iprot->skip(apache::thrift::protocol::T_STRUCT);" << endl <<
|
|
1914
|
+
indent() << " iprot->readMessageEnd();" << endl <<
|
|
1915
|
+
indent() << " iprot->getTransport()->readEnd();" << endl <<
|
|
1916
|
+
indent() << " apache::thrift::TApplicationException x(apache::thrift::TApplicationException::INVALID_MESSAGE_TYPE);" << endl <<
|
|
1917
|
+
indent() << " oprot->writeMessageBegin(fname, apache::thrift::protocol::T_EXCEPTION, seqid);" << endl <<
|
|
1918
|
+
indent() << " x.write(oprot);" << endl <<
|
|
1919
|
+
indent() << " oprot->writeMessageEnd();" << endl <<
|
|
1920
|
+
indent() << " oprot->getTransport()->flush();" << endl <<
|
|
1921
|
+
indent() << " oprot->getTransport()->writeEnd();" << endl <<
|
|
1922
|
+
indent() << " return true;" << endl <<
|
|
1923
|
+
indent() << "}" << endl <<
|
|
1924
|
+
endl <<
|
|
1925
|
+
indent() << "return process_fn(iprot, oprot, fname, seqid);" <<
|
|
1926
|
+
endl;
|
|
1927
|
+
|
|
1928
|
+
indent_down();
|
|
1929
|
+
f_service_ <<
|
|
1930
|
+
indent() << "}" << endl <<
|
|
1931
|
+
endl;
|
|
1932
|
+
|
|
1933
|
+
f_service_ <<
|
|
1934
|
+
"bool " << service_name_ << "Processor::process_fn(apache::thrift::protocol::TProtocol* iprot, apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid) {" << endl;
|
|
1935
|
+
indent_up();
|
|
1936
|
+
|
|
1937
|
+
// HOT: member function pointer map
|
|
1938
|
+
f_service_ <<
|
|
1939
|
+
indent() << "std::map<std::string, void (" << service_name_ << "Processor::*)(int32_t, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*)>::iterator pfn;" << endl <<
|
|
1940
|
+
indent() << "pfn = processMap_.find(fname);" << endl <<
|
|
1941
|
+
indent() << "if (pfn == processMap_.end()) {" << endl;
|
|
1942
|
+
if (extends.empty()) {
|
|
1943
|
+
f_service_ <<
|
|
1944
|
+
indent() << " iprot->skip(apache::thrift::protocol::T_STRUCT);" << endl <<
|
|
1945
|
+
indent() << " iprot->readMessageEnd();" << endl <<
|
|
1946
|
+
indent() << " iprot->getTransport()->readEnd();" << endl <<
|
|
1947
|
+
indent() << " apache::thrift::TApplicationException x(apache::thrift::TApplicationException::UNKNOWN_METHOD, \"Invalid method name: '\"+fname+\"'\");" << endl <<
|
|
1948
|
+
indent() << " oprot->writeMessageBegin(fname, apache::thrift::protocol::T_EXCEPTION, seqid);" << endl <<
|
|
1949
|
+
indent() << " x.write(oprot);" << endl <<
|
|
1950
|
+
indent() << " oprot->writeMessageEnd();" << endl <<
|
|
1951
|
+
indent() << " oprot->getTransport()->flush();" << endl <<
|
|
1952
|
+
indent() << " oprot->getTransport()->writeEnd();" << endl <<
|
|
1953
|
+
indent() << " return true;" << endl;
|
|
1954
|
+
} else {
|
|
1955
|
+
f_service_ <<
|
|
1956
|
+
indent() << " return " << extends << "Processor::process_fn(iprot, oprot, fname, seqid);" << endl;
|
|
1957
|
+
}
|
|
1958
|
+
f_service_ <<
|
|
1959
|
+
indent() << "}" << endl <<
|
|
1960
|
+
indent() << "(this->*(pfn->second))(seqid, iprot, oprot);" << endl <<
|
|
1961
|
+
indent() << "return true;" << endl;
|
|
1962
|
+
|
|
1963
|
+
indent_down();
|
|
1964
|
+
f_service_ <<
|
|
1965
|
+
"}" << endl <<
|
|
1966
|
+
endl;
|
|
1967
|
+
|
|
1968
|
+
// Generate the process subfunctions
|
|
1969
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
1970
|
+
generate_process_function(tservice, *f_iter);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
/**
|
|
1975
|
+
* Generates a struct and helpers for a function.
|
|
1976
|
+
*
|
|
1977
|
+
* @param tfunction The function
|
|
1978
|
+
*/
|
|
1979
|
+
void t_cpp_generator::generate_function_helpers(t_service* tservice,
|
|
1980
|
+
t_function* tfunction) {
|
|
1981
|
+
if (tfunction->is_oneway()) {
|
|
1982
|
+
return;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result");
|
|
1986
|
+
t_field success(tfunction->get_returntype(), "success", 0);
|
|
1987
|
+
if (!tfunction->get_returntype()->is_void()) {
|
|
1988
|
+
result.append(&success);
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
t_struct* xs = tfunction->get_xceptions();
|
|
1992
|
+
const vector<t_field*>& fields = xs->get_members();
|
|
1993
|
+
vector<t_field*>::const_iterator f_iter;
|
|
1994
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
1995
|
+
result.append(*f_iter);
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
generate_struct_definition(f_header_, &result, false);
|
|
1999
|
+
generate_struct_reader(f_service_, &result);
|
|
2000
|
+
generate_struct_result_writer(f_service_, &result);
|
|
2001
|
+
|
|
2002
|
+
result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult");
|
|
2003
|
+
generate_struct_definition(f_header_, &result, false, true, true, false);
|
|
2004
|
+
generate_struct_reader(f_service_, &result, true);
|
|
2005
|
+
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
/**
|
|
2009
|
+
* Generates a process function definition.
|
|
2010
|
+
*
|
|
2011
|
+
* @param tfunction The function to write a dispatcher for
|
|
2012
|
+
*/
|
|
2013
|
+
void t_cpp_generator::generate_process_function(t_service* tservice,
|
|
2014
|
+
t_function* tfunction) {
|
|
2015
|
+
// Open function
|
|
2016
|
+
f_service_ <<
|
|
2017
|
+
"void " << tservice->get_name() << "Processor::" <<
|
|
2018
|
+
"process_" << tfunction->get_name() <<
|
|
2019
|
+
"(int32_t seqid, apache::thrift::protocol::TProtocol* iprot, apache::thrift::protocol::TProtocol* oprot)" << endl;
|
|
2020
|
+
scope_up(f_service_);
|
|
2021
|
+
|
|
2022
|
+
string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args";
|
|
2023
|
+
string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result";
|
|
2024
|
+
|
|
2025
|
+
f_service_ <<
|
|
2026
|
+
indent() << argsname << " args;" << endl <<
|
|
2027
|
+
indent() << "args.read(iprot);" << endl <<
|
|
2028
|
+
indent() << "iprot->readMessageEnd();" << endl <<
|
|
2029
|
+
indent() << "iprot->getTransport()->readEnd();" << endl <<
|
|
2030
|
+
endl;
|
|
2031
|
+
|
|
2032
|
+
t_struct* xs = tfunction->get_xceptions();
|
|
2033
|
+
const std::vector<t_field*>& xceptions = xs->get_members();
|
|
2034
|
+
vector<t_field*>::const_iterator x_iter;
|
|
2035
|
+
|
|
2036
|
+
// Declare result
|
|
2037
|
+
if (!tfunction->is_oneway()) {
|
|
2038
|
+
f_service_ <<
|
|
2039
|
+
indent() << resultname << " result;" << endl;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
// Try block for functions with exceptions
|
|
2043
|
+
f_service_ <<
|
|
2044
|
+
indent() << "try {" << endl;
|
|
2045
|
+
indent_up();
|
|
2046
|
+
|
|
2047
|
+
// Generate the function call
|
|
2048
|
+
t_struct* arg_struct = tfunction->get_arglist();
|
|
2049
|
+
const std::vector<t_field*>& fields = arg_struct->get_members();
|
|
2050
|
+
vector<t_field*>::const_iterator f_iter;
|
|
2051
|
+
|
|
2052
|
+
bool first = true;
|
|
2053
|
+
f_service_ << indent();
|
|
2054
|
+
if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
|
|
2055
|
+
if (is_complex_type(tfunction->get_returntype())) {
|
|
2056
|
+
first = false;
|
|
2057
|
+
f_service_ << "iface_->" << tfunction->get_name() << "(result.success";
|
|
2058
|
+
} else {
|
|
2059
|
+
f_service_ << "result.success = iface_->" << tfunction->get_name() << "(";
|
|
2060
|
+
}
|
|
2061
|
+
} else {
|
|
2062
|
+
f_service_ <<
|
|
2063
|
+
"iface_->" << tfunction->get_name() << "(";
|
|
2064
|
+
}
|
|
2065
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
2066
|
+
if (first) {
|
|
2067
|
+
first = false;
|
|
2068
|
+
} else {
|
|
2069
|
+
f_service_ << ", ";
|
|
2070
|
+
}
|
|
2071
|
+
f_service_ << "args." << (*f_iter)->get_name();
|
|
2072
|
+
}
|
|
2073
|
+
f_service_ << ");" << endl;
|
|
2074
|
+
|
|
2075
|
+
// Set isset on success field
|
|
2076
|
+
if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
|
|
2077
|
+
f_service_ <<
|
|
2078
|
+
indent() << "result.__isset.success = true;" << endl;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
indent_down();
|
|
2082
|
+
f_service_ << indent() << "}";
|
|
2083
|
+
|
|
2084
|
+
if (!tfunction->is_oneway()) {
|
|
2085
|
+
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
|
|
2086
|
+
f_service_ << " catch (" << type_name((*x_iter)->get_type()) << " &" << (*x_iter)->get_name() << ") {" << endl;
|
|
2087
|
+
if (!tfunction->is_oneway()) {
|
|
2088
|
+
indent_up();
|
|
2089
|
+
f_service_ <<
|
|
2090
|
+
indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() << ";" << endl <<
|
|
2091
|
+
indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << endl;
|
|
2092
|
+
indent_down();
|
|
2093
|
+
f_service_ << indent() << "}";
|
|
2094
|
+
} else {
|
|
2095
|
+
f_service_ << "}";
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
f_service_ << " catch (const std::exception& e) {" << endl;
|
|
2101
|
+
|
|
2102
|
+
if (!tfunction->is_oneway()) {
|
|
2103
|
+
indent_up();
|
|
2104
|
+
f_service_ <<
|
|
2105
|
+
indent() << "apache::thrift::TApplicationException x(e.what());" << endl <<
|
|
2106
|
+
indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() << "\", apache::thrift::protocol::T_EXCEPTION, seqid);" << endl <<
|
|
2107
|
+
indent() << "x.write(oprot);" << endl <<
|
|
2108
|
+
indent() << "oprot->writeMessageEnd();" << endl <<
|
|
2109
|
+
indent() << "oprot->getTransport()->flush();" << endl <<
|
|
2110
|
+
indent() << "oprot->getTransport()->writeEnd();" << endl <<
|
|
2111
|
+
indent() << "return;" << endl;
|
|
2112
|
+
indent_down();
|
|
2113
|
+
}
|
|
2114
|
+
f_service_ << indent() << "}" << endl;
|
|
2115
|
+
|
|
2116
|
+
// Shortcut out here for oneway functions
|
|
2117
|
+
if (tfunction->is_oneway()) {
|
|
2118
|
+
f_service_ <<
|
|
2119
|
+
indent() << "return;" << endl;
|
|
2120
|
+
indent_down();
|
|
2121
|
+
f_service_ << "}" << endl <<
|
|
2122
|
+
endl;
|
|
2123
|
+
return;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
// Serialize the result into a struct
|
|
2127
|
+
f_service_ <<
|
|
2128
|
+
endl <<
|
|
2129
|
+
indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() << "\", apache::thrift::protocol::T_REPLY, seqid);" << endl <<
|
|
2130
|
+
indent() << "result.write(oprot);" << endl <<
|
|
2131
|
+
indent() << "oprot->writeMessageEnd();" << endl <<
|
|
2132
|
+
indent() << "oprot->getTransport()->flush();" << endl <<
|
|
2133
|
+
indent() << "oprot->getTransport()->writeEnd();" << endl;
|
|
2134
|
+
|
|
2135
|
+
// Close function
|
|
2136
|
+
scope_down(f_service_);
|
|
2137
|
+
f_service_ << endl;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
/**
|
|
2141
|
+
* Generates a skeleton file of a server
|
|
2142
|
+
*
|
|
2143
|
+
* @param tservice The service to generate a server for.
|
|
2144
|
+
*/
|
|
2145
|
+
void t_cpp_generator::generate_service_skeleton(t_service* tservice) {
|
|
2146
|
+
string svcname = tservice->get_name();
|
|
2147
|
+
|
|
2148
|
+
// Service implementation file includes
|
|
2149
|
+
string f_skeleton_name = get_out_dir()+svcname+"_server.skeleton.cpp";
|
|
2150
|
+
|
|
2151
|
+
string ns = namespace_prefix(tservice->get_program()->get_namespace("cpp"));
|
|
2152
|
+
|
|
2153
|
+
ofstream f_skeleton;
|
|
2154
|
+
f_skeleton.open(f_skeleton_name.c_str());
|
|
2155
|
+
f_skeleton <<
|
|
2156
|
+
"// This autogenerated skeleton file illustrates how to build a server." << endl <<
|
|
2157
|
+
"// You should copy it to another filename to avoid overwriting it." << endl <<
|
|
2158
|
+
endl <<
|
|
2159
|
+
"#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl <<
|
|
2160
|
+
"#include <protocol/TBinaryProtocol.h>" << endl <<
|
|
2161
|
+
"#include <server/TSimpleServer.h>" << endl <<
|
|
2162
|
+
"#include <transport/TServerSocket.h>" << endl <<
|
|
2163
|
+
"#include <transport/TBufferTransports.h>" << endl <<
|
|
2164
|
+
endl <<
|
|
2165
|
+
"using namespace apache::thrift;" << endl <<
|
|
2166
|
+
"using namespace apache::thrift::protocol;" << endl <<
|
|
2167
|
+
"using namespace apache::thrift::transport;" << endl <<
|
|
2168
|
+
"using namespace apache::thrift::server;" << endl <<
|
|
2169
|
+
endl <<
|
|
2170
|
+
"using boost::shared_ptr;" << endl <<
|
|
2171
|
+
endl;
|
|
2172
|
+
|
|
2173
|
+
if (!ns.empty()) {
|
|
2174
|
+
f_skeleton <<
|
|
2175
|
+
"using namespace " << string(ns, 0, ns.size()-2) << ";" << endl <<
|
|
2176
|
+
endl;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
f_skeleton <<
|
|
2180
|
+
"class " << svcname << "Handler : virtual public " << svcname << "If {" << endl <<
|
|
2181
|
+
" public:" << endl;
|
|
2182
|
+
indent_up();
|
|
2183
|
+
f_skeleton <<
|
|
2184
|
+
indent() << svcname << "Handler() {" << endl <<
|
|
2185
|
+
indent() << " // Your initialization goes here" << endl <<
|
|
2186
|
+
indent() << "}" << endl <<
|
|
2187
|
+
endl;
|
|
2188
|
+
|
|
2189
|
+
vector<t_function*> functions = tservice->get_functions();
|
|
2190
|
+
vector<t_function*>::iterator f_iter;
|
|
2191
|
+
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
|
|
2192
|
+
f_skeleton <<
|
|
2193
|
+
indent() << function_signature(*f_iter) << " {" << endl <<
|
|
2194
|
+
indent() << " // Your implementation goes here" << endl <<
|
|
2195
|
+
indent() << " printf(\"" << (*f_iter)->get_name() << "\\n\");" << endl <<
|
|
2196
|
+
indent() << "}" << endl <<
|
|
2197
|
+
endl;
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
indent_down();
|
|
2201
|
+
f_skeleton <<
|
|
2202
|
+
"};" << endl <<
|
|
2203
|
+
endl;
|
|
2204
|
+
|
|
2205
|
+
f_skeleton <<
|
|
2206
|
+
indent() << "int main(int argc, char **argv) {" << endl;
|
|
2207
|
+
indent_up();
|
|
2208
|
+
f_skeleton <<
|
|
2209
|
+
indent() << "int port = 9090;" << endl <<
|
|
2210
|
+
indent() << "shared_ptr<" << svcname << "Handler> handler(new " << svcname << "Handler());" << endl <<
|
|
2211
|
+
indent() << "shared_ptr<TProcessor> processor(new " << svcname << "Processor(handler));" << endl <<
|
|
2212
|
+
indent() << "shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));" << endl <<
|
|
2213
|
+
indent() << "shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());" << endl <<
|
|
2214
|
+
indent() << "shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());" << endl <<
|
|
2215
|
+
endl <<
|
|
2216
|
+
indent() << "TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);" << endl <<
|
|
2217
|
+
indent() << "server.serve();" << endl <<
|
|
2218
|
+
indent() << "return 0;" << endl;
|
|
2219
|
+
indent_down();
|
|
2220
|
+
f_skeleton <<
|
|
2221
|
+
"}" << endl <<
|
|
2222
|
+
endl;
|
|
2223
|
+
|
|
2224
|
+
// Close the files
|
|
2225
|
+
f_skeleton.close();
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
/**
|
|
2229
|
+
* Deserializes a field of any type.
|
|
2230
|
+
*/
|
|
2231
|
+
void t_cpp_generator::generate_deserialize_field(ofstream& out,
|
|
2232
|
+
t_field* tfield,
|
|
2233
|
+
string prefix,
|
|
2234
|
+
string suffix) {
|
|
2235
|
+
t_type* type = get_true_type(tfield->get_type());
|
|
2236
|
+
|
|
2237
|
+
if (type->is_void()) {
|
|
2238
|
+
throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
|
|
2239
|
+
prefix + tfield->get_name();
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
string name = prefix + tfield->get_name() + suffix;
|
|
2243
|
+
|
|
2244
|
+
if (type->is_struct() || type->is_xception()) {
|
|
2245
|
+
generate_deserialize_struct(out, (t_struct*)type, name);
|
|
2246
|
+
} else if (type->is_container()) {
|
|
2247
|
+
generate_deserialize_container(out, type, name);
|
|
2248
|
+
} else if (type->is_base_type()) {
|
|
2249
|
+
indent(out) <<
|
|
2250
|
+
"xfer += iprot->";
|
|
2251
|
+
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
|
|
2252
|
+
switch (tbase) {
|
|
2253
|
+
case t_base_type::TYPE_VOID:
|
|
2254
|
+
throw "compiler error: cannot serialize void field in a struct: " + name;
|
|
2255
|
+
break;
|
|
2256
|
+
case t_base_type::TYPE_STRING:
|
|
2257
|
+
if (((t_base_type*)type)->is_binary()) {
|
|
2258
|
+
out << "readBinary(" << name << ");";
|
|
2259
|
+
}
|
|
2260
|
+
else {
|
|
2261
|
+
out << "readString(" << name << ");";
|
|
2262
|
+
}
|
|
2263
|
+
break;
|
|
2264
|
+
case t_base_type::TYPE_BOOL:
|
|
2265
|
+
out << "readBool(" << name << ");";
|
|
2266
|
+
break;
|
|
2267
|
+
case t_base_type::TYPE_BYTE:
|
|
2268
|
+
out << "readByte(" << name << ");";
|
|
2269
|
+
break;
|
|
2270
|
+
case t_base_type::TYPE_I16:
|
|
2271
|
+
out << "readI16(" << name << ");";
|
|
2272
|
+
break;
|
|
2273
|
+
case t_base_type::TYPE_I32:
|
|
2274
|
+
out << "readI32(" << name << ");";
|
|
2275
|
+
break;
|
|
2276
|
+
case t_base_type::TYPE_I64:
|
|
2277
|
+
out << "readI64(" << name << ");";
|
|
2278
|
+
break;
|
|
2279
|
+
case t_base_type::TYPE_DOUBLE:
|
|
2280
|
+
out << "readDouble(" << name << ");";
|
|
2281
|
+
break;
|
|
2282
|
+
default:
|
|
2283
|
+
throw "compiler error: no C++ reader for base type " + t_base_type::t_base_name(tbase) + name;
|
|
2284
|
+
}
|
|
2285
|
+
out <<
|
|
2286
|
+
endl;
|
|
2287
|
+
} else if (type->is_enum()) {
|
|
2288
|
+
string t = tmp("ecast");
|
|
2289
|
+
out <<
|
|
2290
|
+
indent() << "int32_t " << t << ";" << endl <<
|
|
2291
|
+
indent() << "xfer += iprot->readI32(" << t << ");" << endl <<
|
|
2292
|
+
indent() << name << " = (" << type_name(type) << ")" << t << ";" << endl;
|
|
2293
|
+
} else {
|
|
2294
|
+
printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
|
|
2295
|
+
tfield->get_name().c_str(), type_name(type).c_str());
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
/**
|
|
2300
|
+
* Generates an unserializer for a variable. This makes two key assumptions,
|
|
2301
|
+
* first that there is a const char* variable named data that points to the
|
|
2302
|
+
* buffer for deserialization, and that there is a variable protocol which
|
|
2303
|
+
* is a reference to a TProtocol serialization object.
|
|
2304
|
+
*/
|
|
2305
|
+
void t_cpp_generator::generate_deserialize_struct(ofstream& out,
|
|
2306
|
+
t_struct* tstruct,
|
|
2307
|
+
string prefix) {
|
|
2308
|
+
indent(out) <<
|
|
2309
|
+
"xfer += " << prefix << ".read(iprot);" << endl;
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
void t_cpp_generator::generate_deserialize_container(ofstream& out,
|
|
2313
|
+
t_type* ttype,
|
|
2314
|
+
string prefix) {
|
|
2315
|
+
scope_up(out);
|
|
2316
|
+
|
|
2317
|
+
string size = tmp("_size");
|
|
2318
|
+
string ktype = tmp("_ktype");
|
|
2319
|
+
string vtype = tmp("_vtype");
|
|
2320
|
+
string etype = tmp("_etype");
|
|
2321
|
+
|
|
2322
|
+
t_container* tcontainer = (t_container*)ttype;
|
|
2323
|
+
bool use_push = tcontainer->has_cpp_name();
|
|
2324
|
+
|
|
2325
|
+
indent(out) <<
|
|
2326
|
+
prefix << ".clear();" << endl <<
|
|
2327
|
+
indent() << "uint32_t " << size << ";" << endl;
|
|
2328
|
+
|
|
2329
|
+
// Declare variables, read header
|
|
2330
|
+
if (ttype->is_map()) {
|
|
2331
|
+
out <<
|
|
2332
|
+
indent() << "apache::thrift::protocol::TType " << ktype << ";" << endl <<
|
|
2333
|
+
indent() << "apache::thrift::protocol::TType " << vtype << ";" << endl <<
|
|
2334
|
+
indent() << "iprot->readMapBegin(" <<
|
|
2335
|
+
ktype << ", " << vtype << ", " << size << ");" << endl;
|
|
2336
|
+
} else if (ttype->is_set()) {
|
|
2337
|
+
out <<
|
|
2338
|
+
indent() << "apache::thrift::protocol::TType " << etype << ";" << endl <<
|
|
2339
|
+
indent() << "iprot->readSetBegin(" <<
|
|
2340
|
+
etype << ", " << size << ");" << endl;
|
|
2341
|
+
} else if (ttype->is_list()) {
|
|
2342
|
+
out <<
|
|
2343
|
+
indent() << "apache::thrift::protocol::TType " << etype << ";" << endl <<
|
|
2344
|
+
indent() << "iprot->readListBegin(" <<
|
|
2345
|
+
etype << ", " << size << ");" << endl;
|
|
2346
|
+
if (!use_push) {
|
|
2347
|
+
indent(out) << prefix << ".resize(" << size << ");" << endl;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
// For loop iterates over elements
|
|
2353
|
+
string i = tmp("_i");
|
|
2354
|
+
out <<
|
|
2355
|
+
indent() << "uint32_t " << i << ";" << endl <<
|
|
2356
|
+
indent() << "for (" << i << " = 0; " << i << " < " << size << "; ++" << i << ")" << endl;
|
|
2357
|
+
|
|
2358
|
+
scope_up(out);
|
|
2359
|
+
|
|
2360
|
+
if (ttype->is_map()) {
|
|
2361
|
+
generate_deserialize_map_element(out, (t_map*)ttype, prefix);
|
|
2362
|
+
} else if (ttype->is_set()) {
|
|
2363
|
+
generate_deserialize_set_element(out, (t_set*)ttype, prefix);
|
|
2364
|
+
} else if (ttype->is_list()) {
|
|
2365
|
+
generate_deserialize_list_element(out, (t_list*)ttype, prefix, use_push, i);
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
scope_down(out);
|
|
2369
|
+
|
|
2370
|
+
// Read container end
|
|
2371
|
+
if (ttype->is_map()) {
|
|
2372
|
+
indent(out) << "iprot->readMapEnd();" << endl;
|
|
2373
|
+
} else if (ttype->is_set()) {
|
|
2374
|
+
indent(out) << "iprot->readSetEnd();" << endl;
|
|
2375
|
+
} else if (ttype->is_list()) {
|
|
2376
|
+
indent(out) << "iprot->readListEnd();" << endl;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
scope_down(out);
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
/**
|
|
2384
|
+
* Generates code to deserialize a map
|
|
2385
|
+
*/
|
|
2386
|
+
void t_cpp_generator::generate_deserialize_map_element(ofstream& out,
|
|
2387
|
+
t_map* tmap,
|
|
2388
|
+
string prefix) {
|
|
2389
|
+
string key = tmp("_key");
|
|
2390
|
+
string val = tmp("_val");
|
|
2391
|
+
t_field fkey(tmap->get_key_type(), key);
|
|
2392
|
+
t_field fval(tmap->get_val_type(), val);
|
|
2393
|
+
|
|
2394
|
+
out <<
|
|
2395
|
+
indent() << declare_field(&fkey) << endl;
|
|
2396
|
+
|
|
2397
|
+
generate_deserialize_field(out, &fkey);
|
|
2398
|
+
indent(out) <<
|
|
2399
|
+
declare_field(&fval, false, false, false, true) << " = " <<
|
|
2400
|
+
prefix << "[" << key << "];" << endl;
|
|
2401
|
+
|
|
2402
|
+
generate_deserialize_field(out, &fval);
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
void t_cpp_generator::generate_deserialize_set_element(ofstream& out,
|
|
2406
|
+
t_set* tset,
|
|
2407
|
+
string prefix) {
|
|
2408
|
+
string elem = tmp("_elem");
|
|
2409
|
+
t_field felem(tset->get_elem_type(), elem);
|
|
2410
|
+
|
|
2411
|
+
indent(out) <<
|
|
2412
|
+
declare_field(&felem) << endl;
|
|
2413
|
+
|
|
2414
|
+
generate_deserialize_field(out, &felem);
|
|
2415
|
+
|
|
2416
|
+
indent(out) <<
|
|
2417
|
+
prefix << ".insert(" << elem << ");" << endl;
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
void t_cpp_generator::generate_deserialize_list_element(ofstream& out,
|
|
2421
|
+
t_list* tlist,
|
|
2422
|
+
string prefix,
|
|
2423
|
+
bool use_push,
|
|
2424
|
+
string index) {
|
|
2425
|
+
if (use_push) {
|
|
2426
|
+
string elem = tmp("_elem");
|
|
2427
|
+
t_field felem(tlist->get_elem_type(), elem);
|
|
2428
|
+
indent(out) << declare_field(&felem) << endl;
|
|
2429
|
+
generate_deserialize_field(out, &felem);
|
|
2430
|
+
indent(out) << prefix << ".push_back(" << elem << ");" << endl;
|
|
2431
|
+
} else {
|
|
2432
|
+
t_field felem(tlist->get_elem_type(), prefix + "[" + index + "]");
|
|
2433
|
+
generate_deserialize_field(out, &felem);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
|
|
2438
|
+
/**
|
|
2439
|
+
* Serializes a field of any type.
|
|
2440
|
+
*
|
|
2441
|
+
* @param tfield The field to serialize
|
|
2442
|
+
* @param prefix Name to prepend to field name
|
|
2443
|
+
*/
|
|
2444
|
+
void t_cpp_generator::generate_serialize_field(ofstream& out,
|
|
2445
|
+
t_field* tfield,
|
|
2446
|
+
string prefix,
|
|
2447
|
+
string suffix) {
|
|
2448
|
+
t_type* type = get_true_type(tfield->get_type());
|
|
2449
|
+
|
|
2450
|
+
string name = prefix + tfield->get_name() + suffix;
|
|
2451
|
+
|
|
2452
|
+
// Do nothing for void types
|
|
2453
|
+
if (type->is_void()) {
|
|
2454
|
+
throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + name;
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
|
|
2458
|
+
|
|
2459
|
+
if (type->is_struct() || type->is_xception()) {
|
|
2460
|
+
generate_serialize_struct(out,
|
|
2461
|
+
(t_struct*)type,
|
|
2462
|
+
name);
|
|
2463
|
+
} else if (type->is_container()) {
|
|
2464
|
+
generate_serialize_container(out, type, name);
|
|
2465
|
+
} else if (type->is_base_type() || type->is_enum()) {
|
|
2466
|
+
|
|
2467
|
+
indent(out) <<
|
|
2468
|
+
"xfer += oprot->";
|
|
2469
|
+
|
|
2470
|
+
if (type->is_base_type()) {
|
|
2471
|
+
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
|
|
2472
|
+
switch (tbase) {
|
|
2473
|
+
case t_base_type::TYPE_VOID:
|
|
2474
|
+
throw
|
|
2475
|
+
"compiler error: cannot serialize void field in a struct: " + name;
|
|
2476
|
+
break;
|
|
2477
|
+
case t_base_type::TYPE_STRING:
|
|
2478
|
+
if (((t_base_type*)type)->is_binary()) {
|
|
2479
|
+
out << "writeBinary(" << name << ");";
|
|
2480
|
+
}
|
|
2481
|
+
else {
|
|
2482
|
+
out << "writeString(" << name << ");";
|
|
2483
|
+
}
|
|
2484
|
+
break;
|
|
2485
|
+
case t_base_type::TYPE_BOOL:
|
|
2486
|
+
out << "writeBool(" << name << ");";
|
|
2487
|
+
break;
|
|
2488
|
+
case t_base_type::TYPE_BYTE:
|
|
2489
|
+
out << "writeByte(" << name << ");";
|
|
2490
|
+
break;
|
|
2491
|
+
case t_base_type::TYPE_I16:
|
|
2492
|
+
out << "writeI16(" << name << ");";
|
|
2493
|
+
break;
|
|
2494
|
+
case t_base_type::TYPE_I32:
|
|
2495
|
+
out << "writeI32(" << name << ");";
|
|
2496
|
+
break;
|
|
2497
|
+
case t_base_type::TYPE_I64:
|
|
2498
|
+
out << "writeI64(" << name << ");";
|
|
2499
|
+
break;
|
|
2500
|
+
case t_base_type::TYPE_DOUBLE:
|
|
2501
|
+
out << "writeDouble(" << name << ");";
|
|
2502
|
+
break;
|
|
2503
|
+
default:
|
|
2504
|
+
throw "compiler error: no C++ writer for base type " + t_base_type::t_base_name(tbase) + name;
|
|
2505
|
+
}
|
|
2506
|
+
} else if (type->is_enum()) {
|
|
2507
|
+
out << "writeI32((int32_t)" << name << ");";
|
|
2508
|
+
}
|
|
2509
|
+
out << endl;
|
|
2510
|
+
} else {
|
|
2511
|
+
printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n",
|
|
2512
|
+
name.c_str(),
|
|
2513
|
+
type_name(type).c_str());
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
/**
|
|
2518
|
+
* Serializes all the members of a struct.
|
|
2519
|
+
*
|
|
2520
|
+
* @param tstruct The struct to serialize
|
|
2521
|
+
* @param prefix String prefix to attach to all fields
|
|
2522
|
+
*/
|
|
2523
|
+
void t_cpp_generator::generate_serialize_struct(ofstream& out,
|
|
2524
|
+
t_struct* tstruct,
|
|
2525
|
+
string prefix) {
|
|
2526
|
+
indent(out) <<
|
|
2527
|
+
"xfer += " << prefix << ".write(oprot);" << endl;
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
void t_cpp_generator::generate_serialize_container(ofstream& out,
|
|
2531
|
+
t_type* ttype,
|
|
2532
|
+
string prefix) {
|
|
2533
|
+
scope_up(out);
|
|
2534
|
+
|
|
2535
|
+
if (ttype->is_map()) {
|
|
2536
|
+
indent(out) <<
|
|
2537
|
+
"xfer += oprot->writeMapBegin(" <<
|
|
2538
|
+
type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
|
|
2539
|
+
type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
|
|
2540
|
+
prefix << ".size());" << endl;
|
|
2541
|
+
} else if (ttype->is_set()) {
|
|
2542
|
+
indent(out) <<
|
|
2543
|
+
"xfer += oprot->writeSetBegin(" <<
|
|
2544
|
+
type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
|
|
2545
|
+
prefix << ".size());" << endl;
|
|
2546
|
+
} else if (ttype->is_list()) {
|
|
2547
|
+
indent(out) <<
|
|
2548
|
+
"xfer += oprot->writeListBegin(" <<
|
|
2549
|
+
type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
|
|
2550
|
+
prefix << ".size());" << endl;
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
string iter = tmp("_iter");
|
|
2554
|
+
out <<
|
|
2555
|
+
indent() << type_name(ttype) << "::const_iterator " << iter << ";" << endl <<
|
|
2556
|
+
indent() << "for (" << iter << " = " << prefix << ".begin(); " << iter << " != " << prefix << ".end(); ++" << iter << ")" << endl;
|
|
2557
|
+
scope_up(out);
|
|
2558
|
+
if (ttype->is_map()) {
|
|
2559
|
+
generate_serialize_map_element(out, (t_map*)ttype, iter);
|
|
2560
|
+
} else if (ttype->is_set()) {
|
|
2561
|
+
generate_serialize_set_element(out, (t_set*)ttype, iter);
|
|
2562
|
+
} else if (ttype->is_list()) {
|
|
2563
|
+
generate_serialize_list_element(out, (t_list*)ttype, iter);
|
|
2564
|
+
}
|
|
2565
|
+
scope_down(out);
|
|
2566
|
+
|
|
2567
|
+
if (ttype->is_map()) {
|
|
2568
|
+
indent(out) <<
|
|
2569
|
+
"xfer += oprot->writeMapEnd();" << endl;
|
|
2570
|
+
} else if (ttype->is_set()) {
|
|
2571
|
+
indent(out) <<
|
|
2572
|
+
"xfer += oprot->writeSetEnd();" << endl;
|
|
2573
|
+
} else if (ttype->is_list()) {
|
|
2574
|
+
indent(out) <<
|
|
2575
|
+
"xfer += oprot->writeListEnd();" << endl;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
scope_down(out);
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
/**
|
|
2582
|
+
* Serializes the members of a map.
|
|
2583
|
+
*
|
|
2584
|
+
*/
|
|
2585
|
+
void t_cpp_generator::generate_serialize_map_element(ofstream& out,
|
|
2586
|
+
t_map* tmap,
|
|
2587
|
+
string iter) {
|
|
2588
|
+
t_field kfield(tmap->get_key_type(), iter + "->first");
|
|
2589
|
+
generate_serialize_field(out, &kfield, "");
|
|
2590
|
+
|
|
2591
|
+
t_field vfield(tmap->get_val_type(), iter + "->second");
|
|
2592
|
+
generate_serialize_field(out, &vfield, "");
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
/**
|
|
2596
|
+
* Serializes the members of a set.
|
|
2597
|
+
*/
|
|
2598
|
+
void t_cpp_generator::generate_serialize_set_element(ofstream& out,
|
|
2599
|
+
t_set* tset,
|
|
2600
|
+
string iter) {
|
|
2601
|
+
t_field efield(tset->get_elem_type(), "(*" + iter + ")");
|
|
2602
|
+
generate_serialize_field(out, &efield, "");
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
/**
|
|
2606
|
+
* Serializes the members of a list.
|
|
2607
|
+
*/
|
|
2608
|
+
void t_cpp_generator::generate_serialize_list_element(ofstream& out,
|
|
2609
|
+
t_list* tlist,
|
|
2610
|
+
string iter) {
|
|
2611
|
+
t_field efield(tlist->get_elem_type(), "(*" + iter + ")");
|
|
2612
|
+
generate_serialize_field(out, &efield, "");
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
/**
|
|
2616
|
+
* Makes a :: prefix for a namespace
|
|
2617
|
+
*
|
|
2618
|
+
* @param ns The namepsace, w/ periods in it
|
|
2619
|
+
* @return Namespaces
|
|
2620
|
+
*/
|
|
2621
|
+
string t_cpp_generator::namespace_prefix(string ns) {
|
|
2622
|
+
if (ns.size() == 0) {
|
|
2623
|
+
return "";
|
|
2624
|
+
}
|
|
2625
|
+
string result = "";
|
|
2626
|
+
string::size_type loc;
|
|
2627
|
+
while ((loc = ns.find(".")) != string::npos) {
|
|
2628
|
+
result += ns.substr(0, loc);
|
|
2629
|
+
result += "::";
|
|
2630
|
+
ns = ns.substr(loc+1);
|
|
2631
|
+
}
|
|
2632
|
+
if (ns.size() > 0) {
|
|
2633
|
+
result += ns + "::";
|
|
2634
|
+
}
|
|
2635
|
+
return result;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* Opens namespace.
|
|
2640
|
+
*
|
|
2641
|
+
* @param ns The namepsace, w/ periods in it
|
|
2642
|
+
* @return Namespaces
|
|
2643
|
+
*/
|
|
2644
|
+
string t_cpp_generator::namespace_open(string ns) {
|
|
2645
|
+
if (ns.size() == 0) {
|
|
2646
|
+
return "";
|
|
2647
|
+
}
|
|
2648
|
+
string result = "";
|
|
2649
|
+
string separator = "";
|
|
2650
|
+
string::size_type loc;
|
|
2651
|
+
while ((loc = ns.find(".")) != string::npos) {
|
|
2652
|
+
result += separator;
|
|
2653
|
+
result += "namespace ";
|
|
2654
|
+
result += ns.substr(0, loc);
|
|
2655
|
+
result += " {";
|
|
2656
|
+
separator = " ";
|
|
2657
|
+
ns = ns.substr(loc+1);
|
|
2658
|
+
}
|
|
2659
|
+
if (ns.size() > 0) {
|
|
2660
|
+
result += separator + "namespace " + ns + " {";
|
|
2661
|
+
}
|
|
2662
|
+
return result;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
/**
|
|
2666
|
+
* Closes namespace.
|
|
2667
|
+
*
|
|
2668
|
+
* @param ns The namepsace, w/ periods in it
|
|
2669
|
+
* @return Namespaces
|
|
2670
|
+
*/
|
|
2671
|
+
string t_cpp_generator::namespace_close(string ns) {
|
|
2672
|
+
if (ns.size() == 0) {
|
|
2673
|
+
return "";
|
|
2674
|
+
}
|
|
2675
|
+
string result = "}";
|
|
2676
|
+
string::size_type loc;
|
|
2677
|
+
while ((loc = ns.find(".")) != string::npos) {
|
|
2678
|
+
result += "}";
|
|
2679
|
+
ns = ns.substr(loc+1);
|
|
2680
|
+
}
|
|
2681
|
+
result += " // namespace";
|
|
2682
|
+
return result;
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
/**
|
|
2686
|
+
* Returns a C++ type name
|
|
2687
|
+
*
|
|
2688
|
+
* @param ttype The type
|
|
2689
|
+
* @return String of the type name, i.e. std::set<type>
|
|
2690
|
+
*/
|
|
2691
|
+
string t_cpp_generator::type_name(t_type* ttype, bool in_typedef, bool arg) {
|
|
2692
|
+
if (ttype->is_base_type()) {
|
|
2693
|
+
string bname = base_type_name(((t_base_type*)ttype)->get_base());
|
|
2694
|
+
if (!arg) {
|
|
2695
|
+
return bname;
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
if (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) {
|
|
2699
|
+
return "const " + bname + "&";
|
|
2700
|
+
} else {
|
|
2701
|
+
return "const " + bname;
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
// Check for a custom overloaded C++ name
|
|
2706
|
+
if (ttype->is_container()) {
|
|
2707
|
+
string cname;
|
|
2708
|
+
|
|
2709
|
+
t_container* tcontainer = (t_container*) ttype;
|
|
2710
|
+
if (tcontainer->has_cpp_name()) {
|
|
2711
|
+
cname = tcontainer->get_cpp_name();
|
|
2712
|
+
} else if (ttype->is_map()) {
|
|
2713
|
+
t_map* tmap = (t_map*) ttype;
|
|
2714
|
+
cname = "std::map<" +
|
|
2715
|
+
type_name(tmap->get_key_type(), in_typedef) + ", " +
|
|
2716
|
+
type_name(tmap->get_val_type(), in_typedef) + "> ";
|
|
2717
|
+
} else if (ttype->is_set()) {
|
|
2718
|
+
t_set* tset = (t_set*) ttype;
|
|
2719
|
+
cname = "std::set<" + type_name(tset->get_elem_type(), in_typedef) + "> ";
|
|
2720
|
+
} else if (ttype->is_list()) {
|
|
2721
|
+
t_list* tlist = (t_list*) ttype;
|
|
2722
|
+
cname = "std::vector<" + type_name(tlist->get_elem_type(), in_typedef) + "> ";
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
if (arg) {
|
|
2726
|
+
return "const " + cname + "&";
|
|
2727
|
+
} else {
|
|
2728
|
+
return cname;
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
string class_prefix;
|
|
2733
|
+
if (in_typedef && (ttype->is_struct() || ttype->is_xception())) {
|
|
2734
|
+
class_prefix = "class ";
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
// Check if it needs to be namespaced
|
|
2738
|
+
string pname;
|
|
2739
|
+
t_program* program = ttype->get_program();
|
|
2740
|
+
if (program != NULL && program != program_) {
|
|
2741
|
+
pname =
|
|
2742
|
+
class_prefix +
|
|
2743
|
+
namespace_prefix(program->get_namespace("cpp")) +
|
|
2744
|
+
ttype->get_name();
|
|
2745
|
+
} else {
|
|
2746
|
+
pname = class_prefix + ttype->get_name();
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
if (arg) {
|
|
2750
|
+
if (is_complex_type(ttype)) {
|
|
2751
|
+
return "const " + pname + "&";
|
|
2752
|
+
} else {
|
|
2753
|
+
return "const " + pname;
|
|
2754
|
+
}
|
|
2755
|
+
} else {
|
|
2756
|
+
return pname;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
/**
|
|
2761
|
+
* Returns the C++ type that corresponds to the thrift type.
|
|
2762
|
+
*
|
|
2763
|
+
* @param tbase The base type
|
|
2764
|
+
* @return Explicit C++ type, i.e. "int32_t"
|
|
2765
|
+
*/
|
|
2766
|
+
string t_cpp_generator::base_type_name(t_base_type::t_base tbase) {
|
|
2767
|
+
switch (tbase) {
|
|
2768
|
+
case t_base_type::TYPE_VOID:
|
|
2769
|
+
return "void";
|
|
2770
|
+
case t_base_type::TYPE_STRING:
|
|
2771
|
+
return "std::string";
|
|
2772
|
+
case t_base_type::TYPE_BOOL:
|
|
2773
|
+
return "bool";
|
|
2774
|
+
case t_base_type::TYPE_BYTE:
|
|
2775
|
+
return "int8_t";
|
|
2776
|
+
case t_base_type::TYPE_I16:
|
|
2777
|
+
return "int16_t";
|
|
2778
|
+
case t_base_type::TYPE_I32:
|
|
2779
|
+
return "int32_t";
|
|
2780
|
+
case t_base_type::TYPE_I64:
|
|
2781
|
+
return "int64_t";
|
|
2782
|
+
case t_base_type::TYPE_DOUBLE:
|
|
2783
|
+
return "double";
|
|
2784
|
+
default:
|
|
2785
|
+
throw "compiler error: no C++ base type name for base type " + t_base_type::t_base_name(tbase);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
/**
|
|
2790
|
+
* Declares a field, which may include initialization as necessary.
|
|
2791
|
+
*
|
|
2792
|
+
* @param ttype The type
|
|
2793
|
+
* @return Field declaration, i.e. int x = 0;
|
|
2794
|
+
*/
|
|
2795
|
+
string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, bool constant, bool reference) {
|
|
2796
|
+
// TODO(mcslee): do we ever need to initialize the field?
|
|
2797
|
+
string result = "";
|
|
2798
|
+
if (constant) {
|
|
2799
|
+
result += "const ";
|
|
2800
|
+
}
|
|
2801
|
+
result += type_name(tfield->get_type());
|
|
2802
|
+
if (pointer) {
|
|
2803
|
+
result += "*";
|
|
2804
|
+
}
|
|
2805
|
+
if (reference) {
|
|
2806
|
+
result += "&";
|
|
2807
|
+
}
|
|
2808
|
+
result += " " + tfield->get_name();
|
|
2809
|
+
if (init) {
|
|
2810
|
+
t_type* type = get_true_type(tfield->get_type());
|
|
2811
|
+
|
|
2812
|
+
if (type->is_base_type()) {
|
|
2813
|
+
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
|
|
2814
|
+
switch (tbase) {
|
|
2815
|
+
case t_base_type::TYPE_VOID:
|
|
2816
|
+
break;
|
|
2817
|
+
case t_base_type::TYPE_STRING:
|
|
2818
|
+
result += " = \"\"";
|
|
2819
|
+
break;
|
|
2820
|
+
case t_base_type::TYPE_BOOL:
|
|
2821
|
+
result += " = false";
|
|
2822
|
+
break;
|
|
2823
|
+
case t_base_type::TYPE_BYTE:
|
|
2824
|
+
case t_base_type::TYPE_I16:
|
|
2825
|
+
case t_base_type::TYPE_I32:
|
|
2826
|
+
case t_base_type::TYPE_I64:
|
|
2827
|
+
result += " = 0";
|
|
2828
|
+
break;
|
|
2829
|
+
case t_base_type::TYPE_DOUBLE:
|
|
2830
|
+
result += " = (double)0";
|
|
2831
|
+
break;
|
|
2832
|
+
default:
|
|
2833
|
+
throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
|
|
2834
|
+
}
|
|
2835
|
+
} else if (type->is_enum()) {
|
|
2836
|
+
result += " = (" + type_name(type) + ")0";
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
if (!reference) {
|
|
2840
|
+
result += ";";
|
|
2841
|
+
}
|
|
2842
|
+
return result;
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
/**
|
|
2846
|
+
* Renders a function signature of the form 'type name(args)'
|
|
2847
|
+
*
|
|
2848
|
+
* @param tfunction Function definition
|
|
2849
|
+
* @return String of rendered function definition
|
|
2850
|
+
*/
|
|
2851
|
+
string t_cpp_generator::function_signature(t_function* tfunction,
|
|
2852
|
+
string prefix,
|
|
2853
|
+
bool name_params) {
|
|
2854
|
+
t_type* ttype = tfunction->get_returntype();
|
|
2855
|
+
t_struct* arglist = tfunction->get_arglist();
|
|
2856
|
+
|
|
2857
|
+
if (is_complex_type(ttype)) {
|
|
2858
|
+
bool empty = arglist->get_members().size() == 0;
|
|
2859
|
+
return
|
|
2860
|
+
"void " + prefix + tfunction->get_name() +
|
|
2861
|
+
"(" + type_name(ttype) + (name_params ? "& _return" : "& /* _return */") +
|
|
2862
|
+
(empty ? "" : (", " + argument_list(arglist, name_params))) + ")";
|
|
2863
|
+
} else {
|
|
2864
|
+
return
|
|
2865
|
+
type_name(ttype) + " " + prefix + tfunction->get_name() +
|
|
2866
|
+
"(" + argument_list(arglist, name_params) + ")";
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
/**
|
|
2871
|
+
* Renders a field list
|
|
2872
|
+
*
|
|
2873
|
+
* @param tstruct The struct definition
|
|
2874
|
+
* @return Comma sepearated list of all field names in that struct
|
|
2875
|
+
*/
|
|
2876
|
+
string t_cpp_generator::argument_list(t_struct* tstruct, bool name_params) {
|
|
2877
|
+
string result = "";
|
|
2878
|
+
|
|
2879
|
+
const vector<t_field*>& fields = tstruct->get_members();
|
|
2880
|
+
vector<t_field*>::const_iterator f_iter;
|
|
2881
|
+
bool first = true;
|
|
2882
|
+
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
|
|
2883
|
+
if (first) {
|
|
2884
|
+
first = false;
|
|
2885
|
+
} else {
|
|
2886
|
+
result += ", ";
|
|
2887
|
+
}
|
|
2888
|
+
result += type_name((*f_iter)->get_type(), false, true) + " " +
|
|
2889
|
+
(name_params ? (*f_iter)->get_name() : "/* " + (*f_iter)->get_name() + " */");
|
|
2890
|
+
}
|
|
2891
|
+
return result;
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
/**
|
|
2895
|
+
* Converts the parse type to a C++ enum string for the given type.
|
|
2896
|
+
*
|
|
2897
|
+
* @param type Thrift Type
|
|
2898
|
+
* @return String of C++ code to definition of that type constant
|
|
2899
|
+
*/
|
|
2900
|
+
string t_cpp_generator::type_to_enum(t_type* type) {
|
|
2901
|
+
type = get_true_type(type);
|
|
2902
|
+
|
|
2903
|
+
if (type->is_base_type()) {
|
|
2904
|
+
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
|
|
2905
|
+
switch (tbase) {
|
|
2906
|
+
case t_base_type::TYPE_VOID:
|
|
2907
|
+
throw "NO T_VOID CONSTRUCT";
|
|
2908
|
+
case t_base_type::TYPE_STRING:
|
|
2909
|
+
return "apache::thrift::protocol::T_STRING";
|
|
2910
|
+
case t_base_type::TYPE_BOOL:
|
|
2911
|
+
return "apache::thrift::protocol::T_BOOL";
|
|
2912
|
+
case t_base_type::TYPE_BYTE:
|
|
2913
|
+
return "apache::thrift::protocol::T_BYTE";
|
|
2914
|
+
case t_base_type::TYPE_I16:
|
|
2915
|
+
return "apache::thrift::protocol::T_I16";
|
|
2916
|
+
case t_base_type::TYPE_I32:
|
|
2917
|
+
return "apache::thrift::protocol::T_I32";
|
|
2918
|
+
case t_base_type::TYPE_I64:
|
|
2919
|
+
return "apache::thrift::protocol::T_I64";
|
|
2920
|
+
case t_base_type::TYPE_DOUBLE:
|
|
2921
|
+
return "apache::thrift::protocol::T_DOUBLE";
|
|
2922
|
+
}
|
|
2923
|
+
} else if (type->is_enum()) {
|
|
2924
|
+
return "apache::thrift::protocol::T_I32";
|
|
2925
|
+
} else if (type->is_struct()) {
|
|
2926
|
+
return "apache::thrift::protocol::T_STRUCT";
|
|
2927
|
+
} else if (type->is_xception()) {
|
|
2928
|
+
return "apache::thrift::protocol::T_STRUCT";
|
|
2929
|
+
} else if (type->is_map()) {
|
|
2930
|
+
return "apache::thrift::protocol::T_MAP";
|
|
2931
|
+
} else if (type->is_set()) {
|
|
2932
|
+
return "apache::thrift::protocol::T_SET";
|
|
2933
|
+
} else if (type->is_list()) {
|
|
2934
|
+
return "apache::thrift::protocol::T_LIST";
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
throw "INVALID TYPE IN type_to_enum: " + type->get_name();
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
/**
|
|
2941
|
+
* Returns the symbol name of the local reflection of a type.
|
|
2942
|
+
*/
|
|
2943
|
+
string t_cpp_generator::local_reflection_name(const char* prefix, t_type* ttype, bool external) {
|
|
2944
|
+
ttype = get_true_type(ttype);
|
|
2945
|
+
|
|
2946
|
+
// We have to use the program name as part of the identifier because
|
|
2947
|
+
// if two thrift "programs" are compiled into one actual program
|
|
2948
|
+
// you would get a symbol collison if they both defined list<i32>.
|
|
2949
|
+
// trlo = Thrift Reflection LOcal.
|
|
2950
|
+
string prog;
|
|
2951
|
+
string name;
|
|
2952
|
+
string nspace;
|
|
2953
|
+
|
|
2954
|
+
// TODO(dreiss): Would it be better to pregenerate the base types
|
|
2955
|
+
// and put them in Thrift.{h,cpp} ?
|
|
2956
|
+
|
|
2957
|
+
if (ttype->is_base_type()) {
|
|
2958
|
+
prog = program_->get_name();
|
|
2959
|
+
name = ttype->get_ascii_fingerprint();
|
|
2960
|
+
} else if (ttype->is_enum()) {
|
|
2961
|
+
assert(ttype->get_program() != NULL);
|
|
2962
|
+
prog = ttype->get_program()->get_name();
|
|
2963
|
+
name = ttype->get_ascii_fingerprint();
|
|
2964
|
+
} else if (ttype->is_container()) {
|
|
2965
|
+
prog = program_->get_name();
|
|
2966
|
+
name = ttype->get_ascii_fingerprint();
|
|
2967
|
+
} else {
|
|
2968
|
+
assert(ttype->is_struct() || ttype->is_xception());
|
|
2969
|
+
assert(ttype->get_program() != NULL);
|
|
2970
|
+
prog = ttype->get_program()->get_name();
|
|
2971
|
+
name = ttype->get_ascii_fingerprint();
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2974
|
+
if (external &&
|
|
2975
|
+
ttype->get_program() != NULL &&
|
|
2976
|
+
ttype->get_program() != program_) {
|
|
2977
|
+
nspace = namespace_prefix(ttype->get_program()->get_namespace("cpp"));
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
return nspace + "trlo_" + prefix + "_" + prog + "_" + name;
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
string t_cpp_generator::get_include_prefix(const t_program& program) const {
|
|
2984
|
+
string include_prefix = program.get_include_prefix();
|
|
2985
|
+
if (!use_include_prefix_ ||
|
|
2986
|
+
(include_prefix.size() > 0 && include_prefix[0] == '/')) {
|
|
2987
|
+
// if flag is turned off or this is absolute path, return empty prefix
|
|
2988
|
+
return "";
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
string::size_type last_slash = string::npos;
|
|
2992
|
+
if ((last_slash = include_prefix.rfind("/")) != string::npos) {
|
|
2993
|
+
return include_prefix.substr(0, last_slash) + "/" + out_dir_base_ + "/";
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
return "";
|
|
2997
|
+
}
|
|
2998
|
+
|
|
2999
|
+
|
|
3000
|
+
THRIFT_REGISTER_GENERATOR(cpp, "C++",
|
|
3001
|
+
" dense: Generate type specifications for the dense protocol.\n"
|
|
3002
|
+
" include_prefix: Use full include paths in generated files.\n"
|
|
3003
|
+
);
|