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.
Files changed (353) hide show
  1. data/VERSION.yml +1 -1
  2. data/examples/monitored_cloud.rb +1 -1
  3. data/examples/thrift/thrift_example.rb +1 -1
  4. data/lib/proto/command_interface_handler.rb +1 -1
  5. data/vendor/gems/thrift/CHANGES +35 -0
  6. data/vendor/gems/thrift/CONTRIBUTORS +77 -0
  7. data/vendor/gems/thrift/DISCLAIMER +6 -0
  8. data/vendor/gems/thrift/LICENSE +202 -0
  9. data/vendor/gems/thrift/Makefile.am +28 -0
  10. data/vendor/gems/thrift/NEWS +79 -0
  11. data/vendor/gems/thrift/NOTICE +26 -0
  12. data/vendor/gems/thrift/README +137 -0
  13. data/vendor/gems/thrift/aclocal/ax_boost_base.m4 +198 -0
  14. data/vendor/gems/thrift/aclocal/ax_javac_and_java.m4 +107 -0
  15. data/vendor/gems/thrift/aclocal/ax_lib_event.m4 +194 -0
  16. data/vendor/gems/thrift/aclocal/ax_lib_zlib.m4 +173 -0
  17. data/vendor/gems/thrift/aclocal/ax_signed_right_shift.m4 +127 -0
  18. data/vendor/gems/thrift/aclocal/ax_thrift_internal.m4 +39 -0
  19. data/vendor/gems/thrift/bootstrap.sh +35 -0
  20. data/vendor/gems/thrift/cleanup.sh +58 -0
  21. data/vendor/gems/thrift/compiler/cpp/Makefile.am +136 -0
  22. data/vendor/gems/thrift/compiler/cpp/README +39 -0
  23. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cocoa_generator.cc +2331 -0
  24. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cpp_generator.cc +3003 -0
  25. data/vendor/gems/thrift/compiler/cpp/src/generate/t_csharp_generator.cc +1700 -0
  26. data/vendor/gems/thrift/compiler/cpp/src/generate/t_erl_generator.cc +932 -0
  27. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.cc +173 -0
  28. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.h +321 -0
  29. data/vendor/gems/thrift/compiler/cpp/src/generate/t_hs_generator.cc +1445 -0
  30. data/vendor/gems/thrift/compiler/cpp/src/generate/t_html_generator.cc +637 -0
  31. data/vendor/gems/thrift/compiler/cpp/src/generate/t_java_generator.cc +3069 -0
  32. data/vendor/gems/thrift/compiler/cpp/src/generate/t_ocaml_generator.cc +1673 -0
  33. data/vendor/gems/thrift/compiler/cpp/src/generate/t_oop_generator.h +77 -0
  34. data/vendor/gems/thrift/compiler/cpp/src/generate/t_perl_generator.cc +1812 -0
  35. data/vendor/gems/thrift/compiler/cpp/src/generate/t_php_generator.cc +2281 -0
  36. data/vendor/gems/thrift/compiler/cpp/src/generate/t_py_generator.cc +2310 -0
  37. data/vendor/gems/thrift/compiler/cpp/src/generate/t_rb_generator.cc +1114 -0
  38. data/vendor/gems/thrift/compiler/cpp/src/generate/t_st_generator.cc +1071 -0
  39. data/vendor/gems/thrift/compiler/cpp/src/generate/t_xsd_generator.cc +354 -0
  40. data/vendor/gems/thrift/compiler/cpp/src/globals.h +117 -0
  41. data/vendor/gems/thrift/compiler/cpp/src/main.cc +1207 -0
  42. data/vendor/gems/thrift/compiler/cpp/src/main.h +103 -0
  43. data/vendor/gems/thrift/compiler/cpp/src/md5.c +381 -0
  44. data/vendor/gems/thrift/compiler/cpp/src/md5.h +91 -0
  45. data/vendor/gems/thrift/compiler/cpp/src/parse/t_base_type.h +137 -0
  46. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const.h +59 -0
  47. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const_value.h +121 -0
  48. data/vendor/gems/thrift/compiler/cpp/src/parse/t_container.h +56 -0
  49. data/vendor/gems/thrift/compiler/cpp/src/parse/t_doc.h +51 -0
  50. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum.h +59 -0
  51. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum_value.h +64 -0
  52. data/vendor/gems/thrift/compiler/cpp/src/parse/t_field.h +150 -0
  53. data/vendor/gems/thrift/compiler/cpp/src/parse/t_function.h +93 -0
  54. data/vendor/gems/thrift/compiler/cpp/src/parse/t_list.h +56 -0
  55. data/vendor/gems/thrift/compiler/cpp/src/parse/t_map.h +64 -0
  56. data/vendor/gems/thrift/compiler/cpp/src/parse/t_program.h +223 -0
  57. data/vendor/gems/thrift/compiler/cpp/src/parse/t_scope.h +86 -0
  58. data/vendor/gems/thrift/compiler/cpp/src/parse/t_service.h +68 -0
  59. data/vendor/gems/thrift/compiler/cpp/src/parse/t_set.h +55 -0
  60. data/vendor/gems/thrift/compiler/cpp/src/parse/t_struct.h +127 -0
  61. data/vendor/gems/thrift/compiler/cpp/src/parse/t_type.h +176 -0
  62. data/vendor/gems/thrift/compiler/cpp/src/parse/t_typedef.h +70 -0
  63. data/vendor/gems/thrift/compiler/cpp/src/platform.h +36 -0
  64. data/vendor/gems/thrift/compiler/cpp/src/thriftl.ll +303 -0
  65. data/vendor/gems/thrift/compiler/cpp/src/thrifty.yy +1140 -0
  66. data/vendor/gems/thrift/configure.ac +255 -0
  67. data/vendor/gems/thrift/contrib/fb303/LICENSE +16 -0
  68. data/vendor/gems/thrift/contrib/fb303/Makefile.am +31 -0
  69. data/vendor/gems/thrift/contrib/fb303/README +37 -0
  70. data/vendor/gems/thrift/contrib/fb303/acinclude.m4 +258 -0
  71. data/vendor/gems/thrift/contrib/fb303/aclocal/ax_boost_base.m4 +198 -0
  72. data/vendor/gems/thrift/contrib/fb303/bootstrap.sh +26 -0
  73. data/vendor/gems/thrift/contrib/fb303/configure.ac +115 -0
  74. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.cpp +124 -0
  75. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.h +103 -0
  76. data/vendor/gems/thrift/contrib/fb303/cpp/Makefile.am +84 -0
  77. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.cpp +481 -0
  78. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.h +215 -0
  79. data/vendor/gems/thrift/contrib/fb303/global_footer.mk +21 -0
  80. data/vendor/gems/thrift/contrib/fb303/global_header.mk +38 -0
  81. data/vendor/gems/thrift/contrib/fb303/if/fb303.thrift +112 -0
  82. data/vendor/gems/thrift/contrib/fb303/java/FacebookBase.java +103 -0
  83. data/vendor/gems/thrift/contrib/fb303/java/build.xml +84 -0
  84. data/vendor/gems/thrift/contrib/fb303/php/FacebookBase.php +89 -0
  85. data/vendor/gems/thrift/contrib/fb303/py/Makefile.am +44 -0
  86. data/vendor/gems/thrift/contrib/fb303/py/fb303/FacebookBase.py +82 -0
  87. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/__init__.py +20 -0
  88. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +195 -0
  89. data/vendor/gems/thrift/contrib/fb303/py/setup.py +27 -0
  90. data/vendor/gems/thrift/contrib/thrift.el +126 -0
  91. data/vendor/gems/thrift/contrib/thrift.spec +206 -0
  92. data/vendor/gems/thrift/contrib/thrift.vim +91 -0
  93. data/vendor/gems/thrift/contrib/thrift_dump.cpp +91 -0
  94. data/vendor/gems/thrift/doc/lgpl-2.1.txt +504 -0
  95. data/vendor/gems/thrift/doc/otp-base-license.txt +20 -0
  96. data/vendor/gems/thrift/doc/thrift.bnf +96 -0
  97. data/vendor/gems/thrift/doc/thrift.tex +1057 -0
  98. data/vendor/gems/thrift/lib/Makefile.am +55 -0
  99. data/vendor/gems/thrift/lib/cocoa/README +21 -0
  100. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.h +44 -0
  101. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.m +130 -0
  102. data/vendor/gems/thrift/lib/cocoa/src/TException.h +34 -0
  103. data/vendor/gems/thrift/lib/cocoa/src/TException.m +64 -0
  104. data/vendor/gems/thrift/lib/cocoa/src/TProcessor.h +29 -0
  105. data/vendor/gems/thrift/lib/cocoa/src/TProcessorFactory.h +27 -0
  106. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.h +27 -0
  107. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.m +51 -0
  108. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.h +51 -0
  109. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.m +477 -0
  110. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocol.h +148 -0
  111. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.h +25 -0
  112. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.m +23 -0
  113. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolFactory.h +29 -0
  114. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.h +29 -0
  115. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.m +104 -0
  116. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.h +50 -0
  117. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.m +153 -0
  118. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.h +42 -0
  119. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.m +159 -0
  120. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.h +35 -0
  121. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.m +91 -0
  122. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.h +38 -0
  123. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.m +89 -0
  124. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.h +32 -0
  125. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.m +58 -0
  126. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransport.h +36 -0
  127. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.h +30 -0
  128. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.m +43 -0
  129. data/vendor/gems/thrift/lib/cpp/Makefile.am +158 -0
  130. data/vendor/gems/thrift/lib/cpp/README +67 -0
  131. data/vendor/gems/thrift/lib/cpp/src/TLogging.h +163 -0
  132. data/vendor/gems/thrift/lib/cpp/src/TProcessor.h +53 -0
  133. data/vendor/gems/thrift/lib/cpp/src/TReflectionLocal.h +96 -0
  134. data/vendor/gems/thrift/lib/cpp/src/Thrift.cpp +148 -0
  135. data/vendor/gems/thrift/lib/cpp/src/Thrift.h +191 -0
  136. data/vendor/gems/thrift/lib/cpp/src/concurrency/Exception.h +60 -0
  137. data/vendor/gems/thrift/lib/cpp/src/concurrency/FunctionRunner.h +77 -0
  138. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.cpp +137 -0
  139. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.h +84 -0
  140. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.cpp +160 -0
  141. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.h +114 -0
  142. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.cpp +314 -0
  143. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.h +130 -0
  144. data/vendor/gems/thrift/lib/cpp/src/concurrency/Thread.h +125 -0
  145. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.cpp +493 -0
  146. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.h +169 -0
  147. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.cpp +284 -0
  148. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.h +122 -0
  149. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.cpp +55 -0
  150. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.h +100 -0
  151. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/Tests.cpp +155 -0
  152. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadFactoryTests.h +354 -0
  153. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadManagerTests.h +379 -0
  154. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/TimerManagerTests.h +155 -0
  155. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.cpp +122 -0
  156. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.h +77 -0
  157. data/vendor/gems/thrift/lib/cpp/src/processor/StatsProcessor.h +264 -0
  158. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.cpp +79 -0
  159. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.h +42 -0
  160. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.cpp +394 -0
  161. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.h +254 -0
  162. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.cpp +736 -0
  163. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.h +279 -0
  164. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.cpp +346 -0
  165. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.h +225 -0
  166. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.cpp +762 -0
  167. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.h +253 -0
  168. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.cpp +998 -0
  169. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.h +340 -0
  170. data/vendor/gems/thrift/lib/cpp/src/protocol/TOneWayProtocol.h +304 -0
  171. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocol.h +438 -0
  172. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolException.h +104 -0
  173. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolTap.h +187 -0
  174. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.cpp +750 -0
  175. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.h +435 -0
  176. data/vendor/gems/thrift/lib/cpp/src/server/TServer.cpp +38 -0
  177. data/vendor/gems/thrift/lib/cpp/src/server/TServer.h +213 -0
  178. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.cpp +118 -0
  179. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.h +70 -0
  180. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.cpp +217 -0
  181. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.h +79 -0
  182. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.cpp +243 -0
  183. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.h +74 -0
  184. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.cpp +370 -0
  185. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.h +667 -0
  186. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.cpp +77 -0
  187. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.h +73 -0
  188. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.cpp +953 -0
  189. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.h +442 -0
  190. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.cpp +348 -0
  191. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.h +111 -0
  192. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.cpp +368 -0
  193. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.h +76 -0
  194. data/vendor/gems/thrift/lib/cpp/src/transport/TServerTransport.h +92 -0
  195. data/vendor/gems/thrift/lib/cpp/src/transport/TShortReadTransport.h +96 -0
  196. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.cpp +54 -0
  197. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.h +41 -0
  198. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.cpp +591 -0
  199. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.h +242 -0
  200. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.cpp +235 -0
  201. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.h +191 -0
  202. data/vendor/gems/thrift/lib/cpp/src/transport/TTransport.h +224 -0
  203. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.cpp +31 -0
  204. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.h +117 -0
  205. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.cpp +178 -0
  206. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.h +287 -0
  207. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.cpp +299 -0
  208. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.h +219 -0
  209. data/vendor/gems/thrift/lib/cpp/thrift-nb.pc.in +30 -0
  210. data/vendor/gems/thrift/lib/cpp/thrift-z.pc.in +30 -0
  211. data/vendor/gems/thrift/lib/cpp/thrift.pc.in +29 -0
  212. data/vendor/gems/thrift/lib/csharp/Makefile.am +70 -0
  213. data/vendor/gems/thrift/lib/csharp/README +26 -0
  214. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs +55 -0
  215. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs +242 -0
  216. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj +62 -0
  217. data/vendor/gems/thrift/lib/csharp/src/Collections/THashSet.cs +142 -0
  218. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBase.cs +34 -0
  219. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs +392 -0
  220. data/vendor/gems/thrift/lib/csharp/src/Protocol/TField.cs +58 -0
  221. data/vendor/gems/thrift/lib/csharp/src/Protocol/TList.cs +50 -0
  222. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMap.cs +58 -0
  223. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessage.cs +58 -0
  224. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessageType.cs +31 -0
  225. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocol.cs +87 -0
  226. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolException.cs +61 -0
  227. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs +29 -0
  228. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs +94 -0
  229. data/vendor/gems/thrift/lib/csharp/src/Protocol/TSet.cs +50 -0
  230. data/vendor/gems/thrift/lib/csharp/src/Protocol/TStruct.cs +42 -0
  231. data/vendor/gems/thrift/lib/csharp/src/Protocol/TType.cs +40 -0
  232. data/vendor/gems/thrift/lib/csharp/src/Server/TServer.cs +135 -0
  233. data/vendor/gems/thrift/lib/csharp/src/Server/TSimpleServer.cs +148 -0
  234. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadPoolServer.cs +186 -0
  235. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadedServer.cs +234 -0
  236. data/vendor/gems/thrift/lib/csharp/src/TApplicationException.cs +131 -0
  237. data/vendor/gems/thrift/lib/csharp/src/TProcessor.cs +29 -0
  238. data/vendor/gems/thrift/lib/csharp/src/Thrift.csproj +73 -0
  239. data/vendor/gems/thrift/lib/csharp/src/Thrift.sln +35 -0
  240. data/vendor/gems/thrift/lib/csharp/src/Transport/TBufferedTransport.cs +100 -0
  241. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerSocket.cs +157 -0
  242. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerTransport.cs +39 -0
  243. data/vendor/gems/thrift/lib/csharp/src/Transport/TSocket.cs +144 -0
  244. data/vendor/gems/thrift/lib/csharp/src/Transport/TStreamTransport.cs +103 -0
  245. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransport.cs +66 -0
  246. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportException.cs +64 -0
  247. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportFactory.cs +38 -0
  248. data/vendor/gems/thrift/lib/erl/Makefile +37 -0
  249. data/vendor/gems/thrift/lib/erl/README +56 -0
  250. data/vendor/gems/thrift/lib/erl/build/beamver +59 -0
  251. data/vendor/gems/thrift/lib/erl/build/buildtargets.mk +15 -0
  252. data/vendor/gems/thrift/lib/erl/build/colors.mk +24 -0
  253. data/vendor/gems/thrift/lib/erl/build/docs.mk +12 -0
  254. data/vendor/gems/thrift/lib/erl/build/mime.types +98 -0
  255. data/vendor/gems/thrift/lib/erl/build/otp.mk +146 -0
  256. data/vendor/gems/thrift/lib/erl/build/otp_subdir.mk +85 -0
  257. data/vendor/gems/thrift/lib/erl/build/raw_test.mk +29 -0
  258. data/vendor/gems/thrift/lib/erl/include/thrift_constants.hrl +54 -0
  259. data/vendor/gems/thrift/lib/erl/include/thrift_protocol.hrl +31 -0
  260. data/vendor/gems/thrift/lib/erl/src/Makefile +116 -0
  261. data/vendor/gems/thrift/lib/erl/src/test_handler.erl +26 -0
  262. data/vendor/gems/thrift/lib/erl/src/test_service.erl +29 -0
  263. data/vendor/gems/thrift/lib/erl/src/thrift.app.src +44 -0
  264. data/vendor/gems/thrift/lib/erl/src/thrift.appup.src +1 -0
  265. data/vendor/gems/thrift/lib/erl/src/thrift_base64_transport.erl +64 -0
  266. data/vendor/gems/thrift/lib/erl/src/thrift_binary_protocol.erl +325 -0
  267. data/vendor/gems/thrift/lib/erl/src/thrift_buffered_transport.erl +180 -0
  268. data/vendor/gems/thrift/lib/erl/src/thrift_client.erl +384 -0
  269. data/vendor/gems/thrift/lib/erl/src/thrift_disk_log_transport.erl +118 -0
  270. data/vendor/gems/thrift/lib/erl/src/thrift_file_transport.erl +87 -0
  271. data/vendor/gems/thrift/lib/erl/src/thrift_framed_transport.erl +208 -0
  272. data/vendor/gems/thrift/lib/erl/src/thrift_http_transport.erl +199 -0
  273. data/vendor/gems/thrift/lib/erl/src/thrift_memory_buffer.erl +164 -0
  274. data/vendor/gems/thrift/lib/erl/src/thrift_processor.erl +188 -0
  275. data/vendor/gems/thrift/lib/erl/src/thrift_protocol.erl +356 -0
  276. data/vendor/gems/thrift/lib/erl/src/thrift_server.erl +183 -0
  277. data/vendor/gems/thrift/lib/erl/src/thrift_service.erl +25 -0
  278. data/vendor/gems/thrift/lib/erl/src/thrift_socket_server.erl +249 -0
  279. data/vendor/gems/thrift/lib/erl/src/thrift_socket_transport.erl +119 -0
  280. data/vendor/gems/thrift/lib/erl/src/thrift_transport.erl +57 -0
  281. data/vendor/gems/thrift/lib/erl/vsn.mk +1 -0
  282. data/vendor/gems/thrift/lib/hs/README +82 -0
  283. data/vendor/gems/thrift/lib/hs/Setup.lhs +23 -0
  284. data/vendor/gems/thrift/lib/hs/TODO +2 -0
  285. data/vendor/gems/thrift/lib/hs/Thrift.cabal +20 -0
  286. data/vendor/gems/thrift/lib/hs/src/Thrift.hs +111 -0
  287. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol.hs +191 -0
  288. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol/Binary.hs +147 -0
  289. data/vendor/gems/thrift/lib/hs/src/Thrift/Server.hs +65 -0
  290. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport.hs +60 -0
  291. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport/Handle.hs +58 -0
  292. data/vendor/gems/thrift/lib/java/Makefile.am +38 -0
  293. data/vendor/gems/thrift/lib/java/README +43 -0
  294. data/vendor/gems/thrift/lib/java/build.xml +195 -0
  295. data/vendor/gems/thrift/lib/java/ivy.xml +8 -0
  296. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/IntRangeSet.java +171 -0
  297. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TApplicationException.java +123 -0
  298. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBase.java +66 -0
  299. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBaseHelper.java +102 -0
  300. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java +46 -0
  301. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TDeserializer.java +94 -0
  302. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TException.java +45 -0
  303. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TFieldRequirementType.java +30 -0
  304. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessor.java +32 -0
  305. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessorFactory.java +39 -0
  306. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TSerializer.java +110 -0
  307. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldMetaData.java +69 -0
  308. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldValueMetaData.java +42 -0
  309. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/ListMetaData.java +29 -0
  310. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/MapMetaData.java +31 -0
  311. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/SetMetaData.java +29 -0
  312. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/StructMetaData.java +31 -0
  313. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBase64Utils.java +128 -0
  314. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java +331 -0
  315. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +741 -0
  316. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TField.java +48 -0
  317. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java +927 -0
  318. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TList.java +38 -0
  319. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMap.java +40 -0
  320. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessage.java +48 -0
  321. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessageType.java +31 -0
  322. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocol.java +146 -0
  323. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolException.java +81 -0
  324. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolFactory.java +30 -0
  325. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolUtil.java +158 -0
  326. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSet.java +42 -0
  327. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java +384 -0
  328. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TStruct.java +36 -0
  329. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TType.java +40 -0
  330. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/THsHaServer.java +304 -0
  331. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TNonblockingServer.java +772 -0
  332. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TServer.java +126 -0
  333. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TSimpleServer.java +145 -0
  334. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java +271 -0
  335. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TFramedTransport.java +126 -0
  336. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/THttpClient.java +157 -0
  337. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java +159 -0
  338. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java +98 -0
  339. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java +160 -0
  340. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerTransport.java +31 -0
  341. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java +213 -0
  342. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java +31 -0
  343. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TServerSocket.java +145 -0
  344. metadata +348 -37
  345. data/vendor/gems/trollop/FAQ.txt +0 -35
  346. data/vendor/gems/trollop/History.txt +0 -84
  347. data/vendor/gems/trollop/Manifest.txt +0 -7
  348. data/vendor/gems/trollop/README.txt +0 -38
  349. data/vendor/gems/trollop/Rakefile +0 -36
  350. data/vendor/gems/trollop/lib/trollop.rb +0 -695
  351. data/vendor/gems/trollop/release-script.txt +0 -13
  352. data/vendor/gems/trollop/test/test_trollop.rb +0 -957
  353. 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
+ );