auser-poolparty 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ );