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,39 @@
1
+ dnl @synopsis AX_THRIFT_GEN(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT)
2
+ dnl @synopsis AX_THRIFT_LIB(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT)
3
+ dnl
4
+ dnl Allow a particular language generator to be disabled.
5
+ dnl Allow a particular language library to be disabled.
6
+ dnl
7
+ dnl These macros have poor error handling and are poorly documented.
8
+ dnl They are intended only for internal use by the Thrift compiler.
9
+ dnl
10
+ dnl @version 2008-02-20
11
+ dnl @license AllPermissive
12
+ dnl
13
+ dnl Copyright (C) 2009 David Reiss
14
+ dnl Copying and distribution of this file, with or without modification,
15
+ dnl are permitted in any medium without royalty provided the copyright
16
+ dnl notice and this notice are preserved.
17
+
18
+ AC_DEFUN([AX_THRIFT_GEN],
19
+ [
20
+ AC_ARG_ENABLE([gen-$1],
21
+ AC_HELP_STRING([--enable-gen-$1], [enable the $2 compiler @<:@default=$3@:>@]),
22
+ [ax_thrift_gen_$1="$enableval"],
23
+ [ax_thrift_gen_$1=$3]
24
+ )
25
+ dnl I'd like to run the AM_CONDITIONAL here, but automake likes
26
+ dnl all AM_CONDITIONALs to be nice and explicit in configure.ac.
27
+ dnl AM_CONDITIONAL([THRIFT_GEN_$1], [test "$ax_thrift_gen_$1" = "yes"])
28
+ ])
29
+
30
+ AC_DEFUN([AX_THRIFT_LIB],
31
+ [
32
+ AC_ARG_WITH($1,
33
+ AC_HELP_STRING([--with-$1], [build the $2 library @<:@default=$3@:>@]),
34
+ [with_$1="$withval"],
35
+ [with_$1=$3]
36
+ )
37
+ dnl What we do here is going to vary from library to library,
38
+ dnl so we can't really generalize (yet!).
39
+ ])
@@ -0,0 +1,35 @@
1
+ #!/bin/sh
2
+
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+ #
21
+
22
+ ./cleanup.sh
23
+
24
+ autoscan || exit 1
25
+ aclocal -I ./aclocal || exit 1
26
+ autoheader || exit 1
27
+
28
+ if libtoolize --version 1 >/dev/null 2>/dev/null; then
29
+ libtoolize --copy --automake || exit 1
30
+ elif glibtoolize --version 1 >/dev/null 2>/dev/null; then
31
+ glibtoolize --copy --automake || exit 1
32
+ fi
33
+
34
+ autoconf
35
+ automake -ac --add-missing --foreign || exit 1
@@ -0,0 +1,58 @@
1
+ #!/bin/sh
2
+
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+ #
21
+
22
+ topsrcdir="`dirname $0`"
23
+ cd "$topsrcdir"
24
+
25
+ make -k clean >/dev/null 2>&1
26
+ make -k distclean >/dev/null 2>&1
27
+ find . -name Makefile.in -exec rm -f {} \;
28
+ rm -rf \
29
+ AUTHORS \
30
+ ChangeLog \
31
+ INSTALL \
32
+ Makefile \
33
+ Makefile.in \
34
+ Makefile.orig \
35
+ aclocal.m4 \
36
+ autom4te.cache \
37
+ autoscan.log \
38
+ config.guess \
39
+ config.h \
40
+ config.hin \
41
+ config.hin~ \
42
+ config.log \
43
+ config.status \
44
+ config.status.lineno \
45
+ config.sub \
46
+ configure \
47
+ configure.lineno \
48
+ configure.scan \
49
+ depcomp \
50
+ .deps \
51
+ install-sh \
52
+ .libs \
53
+ libtool \
54
+ ltmain.sh \
55
+ missing \
56
+ ylwrap \
57
+ if/gen-* \
58
+ test/gen-*
@@ -0,0 +1,136 @@
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
+ AM_YFLAGS = -d
21
+ BUILT_SOURCES =
22
+
23
+ bin_PROGRAMS = thrift
24
+
25
+ thrift_OBJDIR = obj
26
+
27
+ thrift_SOURCES = src/thrifty.yy \
28
+ src/thriftl.ll \
29
+ src/main.cc \
30
+ src/md5.c \
31
+ src/generate/t_generator.cc \
32
+ src/globals.h \
33
+ src/main.h \
34
+ src/platform.h \
35
+ src/md5.h \
36
+ src/parse/t_doc.h \
37
+ src/parse/t_type.h \
38
+ src/parse/t_base_type.h \
39
+ src/parse/t_enum.h \
40
+ src/parse/t_enum_value.h \
41
+ src/parse/t_typedef.h \
42
+ src/parse/t_container.h \
43
+ src/parse/t_list.h \
44
+ src/parse/t_set.h \
45
+ src/parse/t_map.h \
46
+ src/parse/t_struct.h \
47
+ src/parse/t_field.h \
48
+ src/parse/t_service.h \
49
+ src/parse/t_function.h \
50
+ src/parse/t_program.h \
51
+ src/parse/t_scope.h \
52
+ src/parse/t_const.h \
53
+ src/parse/t_const_value.h \
54
+ src/generate/t_generator.h \
55
+ src/generate/t_oop_generator.h
56
+
57
+ if THRIFT_GEN_cpp
58
+ thrift_SOURCES += src/generate/t_cpp_generator.cc
59
+ endif
60
+ if THRIFT_GEN_java
61
+ thrift_SOURCES += src/generate/t_java_generator.cc
62
+ endif
63
+ if THRIFT_GEN_csharp
64
+ thrift_SOURCES += src/generate/t_csharp_generator.cc
65
+ endif
66
+ if THRIFT_GEN_py
67
+ thrift_SOURCES += src/generate/t_py_generator.cc
68
+ endif
69
+ if THRIFT_GEN_rb
70
+ thrift_SOURCES += src/generate/t_rb_generator.cc
71
+ endif
72
+ if THRIFT_GEN_perl
73
+ thrift_SOURCES += src/generate/t_perl_generator.cc
74
+ endif
75
+ if THRIFT_GEN_php
76
+ thrift_SOURCES += src/generate/t_php_generator.cc
77
+ endif
78
+ if THRIFT_GEN_erl
79
+ thrift_SOURCES += src/generate/t_erl_generator.cc
80
+ endif
81
+ if THRIFT_GEN_cocoa
82
+ thrift_SOURCES += src/generate/t_cocoa_generator.cc
83
+ endif
84
+ if THRIFT_GEN_st
85
+ thrift_SOURCES += src/generate/t_st_generator.cc
86
+ endif
87
+ if THRIFT_GEN_ocaml
88
+ thrift_SOURCES += src/generate/t_ocaml_generator.cc
89
+ endif
90
+ if THRIFT_GEN_hs
91
+ thrift_SOURCES += src/generate/t_hs_generator.cc
92
+ endif
93
+ if THRIFT_GEN_xsd
94
+ thrift_SOURCES += src/generate/t_xsd_generator.cc
95
+ endif
96
+ if THRIFT_GEN_html
97
+ thrift_SOURCES += src/generate/t_html_generator.cc
98
+ endif
99
+
100
+ thrift_CXXFLAGS = -Wall -I$(srcdir)/src $(BOOST_CPPFLAGS)
101
+ thrift_LDFLAGS = -Wall $(BOOST_LDFLAGS)
102
+
103
+ thrift_LDADD = @LEXLIB@
104
+
105
+ EXTRA_DIST = README
106
+
107
+ clean-local:
108
+ $(RM) thriftl.cc thrifty.cc thrifty.h version.h
109
+
110
+ src/main.cc: version.h
111
+
112
+ # Adding this to BUILT_SOURCES will cause version.h to be
113
+ # regenerated on every "make all" or "make check", which is
114
+ # necessary because it changes whenever we "svn up" or similar.
115
+ # Ideally, we would like this to be regenerated whenever the
116
+ # compiler is rebuilt, but every way we could think of to do
117
+ # that caused unnecessary rebuilds of the compiler.
118
+ BUILT_SOURCES += regen_version_h
119
+
120
+ THRIFT_VERSION=$(shell /bin/sh $(top_srcdir)/print_version.sh -v)
121
+ THRIFT_REVISION=$(shell /bin/sh $(top_srcdir)/print_version.sh -r)
122
+
123
+ regen_version_h:
124
+ @printf "Regenerating version.h... "
125
+ @TMPFILE=`mktemp ./version_h.tmp_XXXXXX` ; \
126
+ echo "// AUTOGENERATED, DO NOT EDIT" > $$TMPFILE ; \
127
+ echo '#define THRIFT_VERSION "$(THRIFT_VERSION)"' >> $$TMPFILE ; \
128
+ echo '#define THRIFT_REVISION "$(THRIFT_REVISION)"' >> $$TMPFILE ; \
129
+ if cmp $$TMPFILE version.h >/dev/null ; \
130
+ then \
131
+ rm -f $$TMPFILE ; \
132
+ echo "No changes." ; \
133
+ else \
134
+ mv $$TMPFILE version.h ; \
135
+ echo "Updated." ; \
136
+ fi
@@ -0,0 +1,39 @@
1
+ Thrift Code Compiler
2
+
3
+ License
4
+ =======
5
+
6
+ Licensed to the Apache Software Foundation (ASF) under one
7
+ or more contributor license agreements. See the NOTICE file
8
+ distributed with this work for additional information
9
+ regarding copyright ownership. The ASF licenses this file
10
+ to you under the Apache License, Version 2.0 (the
11
+ "License"); you may not use this file except in compliance
12
+ with the License. You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing,
17
+ software distributed under the License is distributed on an
18
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
+ KIND, either express or implied. See the License for the
20
+ specific language governing permissions and limitations
21
+ under the License.
22
+
23
+ Thrift Code Compiler
24
+ ====================
25
+
26
+ This compiler takes thrift files as input and generates output code across
27
+ various programming languages. To build and install it, do this:
28
+
29
+ ./bootstrap.sh
30
+ ./configure
31
+ make
32
+ sudo make install
33
+
34
+ It requires some form of LEX and YACC to be installed, which should be
35
+ picked up by autoconf.
36
+
37
+ Not much else to report here. You'll have to look at the code to get your
38
+ questions answered. Or just run the executable after you build and take
39
+ a look at the usage message.
@@ -0,0 +1,2331 @@
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 <string>
21
+ #include <fstream>
22
+ #include <iostream>
23
+ #include <vector>
24
+
25
+ #include <stdlib.h>
26
+ #include <sys/stat.h>
27
+ #include <sstream>
28
+ #include "t_oop_generator.h"
29
+ #include "platform.h"
30
+ using namespace std;
31
+
32
+
33
+ /**
34
+ * Objective-C code generator.
35
+ *
36
+ * mostly copy/pasting/tweaking from mcslee's work.
37
+ */
38
+ class t_cocoa_generator : public t_oop_generator {
39
+ public:
40
+ t_cocoa_generator(
41
+ t_program* program,
42
+ const std::map<std::string, std::string>& parsed_options,
43
+ const std::string& option_string)
44
+ : t_oop_generator(program)
45
+ {
46
+ std::map<std::string, std::string>::const_iterator iter;
47
+
48
+ iter = parsed_options.find("log_unexpected");
49
+ log_unexpected_ = (iter != parsed_options.end());
50
+
51
+ out_dir_base_ = "gen-cocoa";
52
+ }
53
+
54
+ /**
55
+ * Init and close methods
56
+ */
57
+
58
+ void init_generator();
59
+ void close_generator();
60
+
61
+ void generate_consts(std::vector<t_const*> consts);
62
+
63
+ /**
64
+ * Program-level generation functions
65
+ */
66
+
67
+ void generate_typedef (t_typedef* ttypedef);
68
+ void generate_enum (t_enum* tenum);
69
+ void generate_struct (t_struct* tstruct);
70
+ void generate_xception(t_struct* txception);
71
+ void generate_service (t_service* tservice);
72
+
73
+ void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
74
+ std::string render_const_value(std::string name, t_type* type, t_const_value* value,
75
+ bool containerize_it=false);
76
+
77
+ void generate_cocoa_struct(t_struct* tstruct, bool is_exception);
78
+ void generate_cocoa_struct_interface(std::ofstream& out, t_struct* tstruct, bool is_xception=false);
79
+ void generate_cocoa_struct_implementation(std::ofstream& out, t_struct* tstruct, bool is_xception=false, bool is_result=false);
80
+ void generate_cocoa_struct_initializer_signature(std::ofstream& out,
81
+ t_struct* tstruct);
82
+ void generate_cocoa_struct_field_accessor_declarations(std::ofstream& out,
83
+ t_struct* tstruct,
84
+ bool is_exception);
85
+ void generate_cocoa_struct_field_accessor_implementations(std::ofstream& out,
86
+ t_struct* tstruct,
87
+ bool is_exception);
88
+ void generate_cocoa_struct_reader(std::ofstream& out, t_struct* tstruct);
89
+ void generate_cocoa_struct_result_writer(std::ofstream& out, t_struct* tstruct);
90
+ void generate_cocoa_struct_writer(std::ofstream& out, t_struct* tstruct);
91
+ void generate_cocoa_struct_description(std::ofstream& out, t_struct* tstruct);
92
+
93
+ std::string function_result_helper_struct_type(t_function* tfunction);
94
+ std::string function_args_helper_struct_type(t_function* tfunction);
95
+ void generate_function_helpers(t_function* tfunction);
96
+
97
+ /**
98
+ * Service-level generation functions
99
+ */
100
+
101
+ void generate_cocoa_service_protocol (std::ofstream& out, t_service* tservice);
102
+ void generate_cocoa_service_client_interface (std::ofstream& out, t_service* tservice);
103
+ void generate_cocoa_service_client_implementation (std::ofstream& out, t_service* tservice);
104
+ void generate_cocoa_service_server_interface (std::ofstream& out, t_service* tservice);
105
+ void generate_cocoa_service_server_implementation (std::ofstream& out, t_service* tservice);
106
+ void generate_cocoa_service_helpers (t_service* tservice);
107
+ void generate_service_client (t_service* tservice);
108
+ void generate_service_server (t_service* tservice);
109
+ void generate_process_function (t_service* tservice, t_function* tfunction);
110
+
111
+ /**
112
+ * Serialization constructs
113
+ */
114
+
115
+ void generate_deserialize_field (std::ofstream& out,
116
+ t_field* tfield,
117
+ std::string fieldName);
118
+
119
+ void generate_deserialize_struct (std::ofstream& out,
120
+ t_struct* tstruct,
121
+ std::string prefix="");
122
+
123
+ void generate_deserialize_container (std::ofstream& out,
124
+ t_type* ttype,
125
+ std::string prefix="");
126
+
127
+ void generate_deserialize_set_element (std::ofstream& out,
128
+ t_set* tset,
129
+ std::string prefix="");
130
+
131
+ void generate_deserialize_map_element (std::ofstream& out,
132
+ t_map* tmap,
133
+ std::string prefix="");
134
+
135
+ void generate_deserialize_list_element (std::ofstream& out,
136
+ t_list* tlist,
137
+ std::string prefix="");
138
+
139
+ void generate_serialize_field (std::ofstream& out,
140
+ t_field* tfield,
141
+ std::string prefix="");
142
+
143
+ void generate_serialize_struct (std::ofstream& out,
144
+ t_struct* tstruct,
145
+ std::string fieldName="");
146
+
147
+ void generate_serialize_container (std::ofstream& out,
148
+ t_type* ttype,
149
+ std::string prefix="");
150
+
151
+ void generate_serialize_map_element (std::ofstream& out,
152
+ t_map* tmap,
153
+ std::string iter,
154
+ std::string map);
155
+
156
+ void generate_serialize_set_element (std::ofstream& out,
157
+ t_set* tmap,
158
+ std::string iter);
159
+
160
+ void generate_serialize_list_element (std::ofstream& out,
161
+ t_list* tlist,
162
+ std::string index,
163
+ std::string listName);
164
+
165
+ /**
166
+ * Helper rendering functions
167
+ */
168
+
169
+ std::string cocoa_prefix();
170
+ std::string cocoa_imports();
171
+ std::string cocoa_thrift_imports();
172
+ std::string type_name(t_type* ttype, bool class_ref=false);
173
+ std::string base_type_name(t_base_type* tbase);
174
+ std::string declare_field(t_field* tfield);
175
+ std::string declare_property(t_field* tfield);
176
+ std::string synthesize_property(t_field* tfield);
177
+ std::string function_signature(t_function* tfunction);
178
+ std::string argument_list(t_struct* tstruct);
179
+ std::string type_to_enum(t_type* ttype);
180
+ std::string format_string_for_type(t_type* type);
181
+ std::string call_field_setter(t_field* tfield, std::string fieldName);
182
+ std::string containerize(t_type * ttype, std::string fieldName);
183
+ std::string decontainerize(t_field * tfield, std::string fieldName);
184
+
185
+ bool type_can_be_null(t_type* ttype) {
186
+ ttype = get_true_type(ttype);
187
+
188
+ return
189
+ ttype->is_container() ||
190
+ ttype->is_struct() ||
191
+ ttype->is_xception() ||
192
+ ttype->is_string();
193
+ }
194
+
195
+ private:
196
+
197
+ std::string cocoa_prefix_;
198
+ std::string constants_declarations_;
199
+
200
+ /**
201
+ * File streams
202
+ */
203
+
204
+ std::ofstream f_header_;
205
+ std::ofstream f_impl_;
206
+
207
+ bool log_unexpected_;
208
+ };
209
+
210
+
211
+ /**
212
+ * Prepares for file generation by opening up the necessary file output
213
+ * streams.
214
+ */
215
+ void t_cocoa_generator::init_generator() {
216
+ // Make output directory
217
+ MKDIR(get_out_dir().c_str());
218
+ cocoa_prefix_ = program_->get_namespace("cocoa");
219
+
220
+ // we have a .h header file...
221
+ string f_header_name = program_name_+".h";
222
+ string f_header_fullname = get_out_dir()+f_header_name;
223
+ f_header_.open(f_header_fullname.c_str());
224
+
225
+ f_header_ <<
226
+ autogen_comment() <<
227
+ endl;
228
+
229
+ f_header_ <<
230
+ cocoa_imports() <<
231
+ cocoa_thrift_imports();
232
+
233
+ // ...and a .m implementation file
234
+ string f_impl_name = get_out_dir()+program_name_+".m";
235
+ f_impl_.open(f_impl_name.c_str());
236
+
237
+ f_impl_ <<
238
+ autogen_comment() <<
239
+ endl;
240
+
241
+ f_impl_ <<
242
+ cocoa_imports() <<
243
+ cocoa_thrift_imports() <<
244
+ "#import \"" << f_header_name << "\"" << endl <<
245
+ endl;
246
+
247
+ }
248
+
249
+ /**
250
+ * Prints standard Cocoa imports
251
+ *
252
+ * @return List of imports for Cocoa libraries
253
+ */
254
+ string t_cocoa_generator::cocoa_imports() {
255
+ return
256
+ string() +
257
+ "#import <Foundation/Foundation.h>\n" +
258
+ "\n";
259
+ }
260
+
261
+ /**
262
+ * Prints thrift runtime imports
263
+ *
264
+ * @return List of imports necessary for thrift runtime
265
+ */
266
+ string t_cocoa_generator::cocoa_thrift_imports() {
267
+ string result = string() +
268
+ "#import <TProtocol.h>\n" +
269
+ "#import <TApplicationException.h>\n" +
270
+ "#import <TProtocolUtil.h>\n" +
271
+ "#import <TProcessor.h>\n" +
272
+ "\n";
273
+
274
+ // Include other Thrift includes
275
+ const vector<t_program*>& includes = program_->get_includes();
276
+ for (size_t i = 0; i < includes.size(); ++i) {
277
+ result += "#import \"" + includes[i]->get_name() + ".h\"" + "\n";
278
+ }
279
+ result += "\n";
280
+
281
+ return result;
282
+ }
283
+
284
+
285
+ /**
286
+ * Finish up generation.
287
+ */
288
+ void t_cocoa_generator::close_generator()
289
+ {
290
+ // stick our constants declarations at the end of the header file
291
+ // since they refer to things we are defining.
292
+ f_header_ << constants_declarations_ << endl;
293
+ }
294
+
295
+ /**
296
+ * Generates a typedef. This is just a simple 1-liner in objective-c
297
+ *
298
+ * @param ttypedef The type definition
299
+ */
300
+ void t_cocoa_generator::generate_typedef(t_typedef* ttypedef) {
301
+ f_header_ <<
302
+ indent() << "typedef " << type_name(ttypedef->get_type()) << " " << cocoa_prefix_ << ttypedef->get_symbolic() << ";" << endl <<
303
+ endl;
304
+ }
305
+
306
+ /**
307
+ * Generates code for an enumerated type. In Objective-C, this is
308
+ * essentially the same as the thrift definition itself, using the
309
+ * enum keyword in Objective-C. For namespace purposes, the name of
310
+ * the enum plus an underscore is prefixed onto each element.
311
+ *
312
+ * @param tenum The enumeration
313
+ */
314
+ void t_cocoa_generator::generate_enum(t_enum* tenum) {
315
+ f_header_ <<
316
+ indent() << "enum " << cocoa_prefix_ << tenum->get_name() << " {" << endl;
317
+ indent_up();
318
+
319
+ vector<t_enum_value*> constants = tenum->get_constants();
320
+ vector<t_enum_value*>::iterator c_iter;
321
+ bool first = true;
322
+ for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
323
+ if (first) {
324
+ first = false;
325
+ } else {
326
+ f_header_ <<
327
+ "," << endl;
328
+ }
329
+ f_header_ <<
330
+ indent() << tenum->get_name() << "_" << (*c_iter)->get_name();
331
+ if ((*c_iter)->has_value()) {
332
+ f_header_ <<
333
+ " = " << (*c_iter)->get_value();
334
+ }
335
+ }
336
+
337
+ indent_down();
338
+ f_header_ <<
339
+ endl <<
340
+ "};" << endl <<
341
+ endl;
342
+ }
343
+
344
+ /**
345
+ * Generates a class that holds all the constants. Primitive values
346
+ * could have been placed outside this class, but I just put
347
+ * everything in for consistency.
348
+ */
349
+ void t_cocoa_generator::generate_consts(std::vector<t_const*> consts) {
350
+ std::ostringstream const_interface;
351
+ string constants_class_name = cocoa_prefix_ + program_name_ + "Constants";
352
+
353
+ const_interface << "@interface " << constants_class_name << " : NSObject ";
354
+ scope_up(const_interface);
355
+ scope_down(const_interface);
356
+
357
+ // getter method for each constant defined.
358
+ vector<t_const*>::iterator c_iter;
359
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
360
+ string name = (*c_iter)->get_name();
361
+ t_type* type = (*c_iter)->get_type();
362
+ const_interface <<
363
+ "+ (" << type_name(type) << ") " << name << ";" << endl;
364
+ }
365
+
366
+ const_interface << "@end";
367
+
368
+ // this gets spit into the header file in ::close_generator
369
+ constants_declarations_ = const_interface.str();
370
+
371
+ // static variables in the .m hold all constant values
372
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
373
+ string name = (*c_iter)->get_name();
374
+ t_type* type = (*c_iter)->get_type();
375
+ f_impl_ <<
376
+ "static " << type_name(type) << " " << cocoa_prefix_ << name;
377
+ if (!type->is_container() && !type->is_struct()) {
378
+ f_impl_ << " = " << render_const_value(name, type, (*c_iter)->get_value());
379
+ }
380
+ f_impl_ << ";" << endl;
381
+ }
382
+ f_impl_ << endl;
383
+
384
+ f_impl_ << "@implementation " << constants_class_name << endl;
385
+
386
+ // initialize complex constants when the class is loaded
387
+ f_impl_ << "+ (void) initialize ";
388
+ scope_up(f_impl_);
389
+
390
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
391
+ if ((*c_iter)->get_type()->is_container() ||
392
+ (*c_iter)->get_type()->is_struct()) {
393
+ string name = (*c_iter)->get_name();
394
+ f_impl_ << indent() << cocoa_prefix_ << name << " = " << render_const_value(name,
395
+ (*c_iter)->get_type(),
396
+ (*c_iter)->get_value());
397
+ f_impl_ << ";" << endl;
398
+ }
399
+ }
400
+ scope_down(f_impl_);
401
+
402
+ // getter method for each constant
403
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
404
+ string name = (*c_iter)->get_name();
405
+ t_type* type = (*c_iter)->get_type();
406
+ f_impl_ <<
407
+ "+ (" << type_name(type) << ") " << name;
408
+ scope_up(f_impl_);
409
+ indent(f_impl_) << "return " << cocoa_prefix_ << name << ";" << endl;
410
+ scope_down(f_impl_);
411
+ }
412
+
413
+ f_impl_ << "@end" << endl << endl;
414
+ }
415
+
416
+
417
+ /**
418
+ * Generates a struct definition for a thrift data type. This is a class
419
+ * with protected data members, read(), write(), and getters and setters.
420
+ *
421
+ * @param tstruct The struct definition
422
+ */
423
+ void t_cocoa_generator::generate_struct(t_struct* tstruct) {
424
+ generate_cocoa_struct_interface(f_header_, tstruct, false);
425
+ generate_cocoa_struct_implementation(f_impl_, tstruct, false);
426
+ }
427
+
428
+ /**
429
+ * Exceptions are structs, but they inherit from NSException
430
+ *
431
+ * @param tstruct The struct definition
432
+ */
433
+ void t_cocoa_generator::generate_xception(t_struct* txception) {
434
+ generate_cocoa_struct_interface(f_header_, txception, true);
435
+ generate_cocoa_struct_implementation(f_impl_, txception, true);
436
+ }
437
+
438
+
439
+ /**
440
+ * Generate the interface for a struct
441
+ *
442
+ * @param tstruct The struct definition
443
+ */
444
+ void t_cocoa_generator::generate_cocoa_struct_interface(ofstream &out,
445
+ t_struct* tstruct,
446
+ bool is_exception) {
447
+ out << "@interface " << cocoa_prefix_ << tstruct->get_name() << " : ";
448
+
449
+ if (is_exception) {
450
+ out << "NSException ";
451
+ } else {
452
+ out << "NSObject ";
453
+ }
454
+
455
+ scope_up(out);
456
+
457
+ // members are protected. this is redundant, but explicit.
458
+ // f_header_ << endl << "@protected:" << endl;
459
+
460
+ const vector<t_field*>& members = tstruct->get_members();
461
+
462
+ // member varialbes
463
+ vector<t_field*>::const_iterator m_iter;
464
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
465
+ out << indent() << declare_field(*m_iter) << endl;
466
+ }
467
+
468
+ if (members.size() > 0) {
469
+ out << endl;
470
+ // isset fields
471
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
472
+ indent(out) <<
473
+ "BOOL __" << (*m_iter)->get_name() << "_isset;" << endl;
474
+ }
475
+ }
476
+
477
+ scope_down(out);
478
+ out << endl;
479
+
480
+ // properties
481
+ if (members.size() > 0) {
482
+ out << "#if TARGET_OS_IPHONE || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)" << endl;
483
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
484
+ out << indent() << declare_property(*m_iter) << endl;
485
+ }
486
+ out << "#endif" << endl << endl;
487
+ }
488
+
489
+ // initializer for all fields
490
+ if (!members.empty()) {
491
+ generate_cocoa_struct_initializer_signature(out, tstruct);
492
+ out << ";" << endl;
493
+ }
494
+ out << endl;
495
+
496
+ // read and write
497
+ out << "- (void) read: (id <TProtocol>) inProtocol;" << endl;
498
+ out << "- (void) write: (id <TProtocol>) outProtocol;" << endl;
499
+ out << endl;
500
+
501
+ // getters and setters
502
+ generate_cocoa_struct_field_accessor_declarations(out, tstruct, is_exception);
503
+
504
+ out << "@end" << endl << endl;
505
+ }
506
+
507
+
508
+ /**
509
+ * Generate signature for initializer of struct with a parameter for
510
+ * each field.
511
+ */
512
+ void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream &out,
513
+ t_struct* tstruct) {
514
+ const vector<t_field*>& members = tstruct->get_members();
515
+ vector<t_field*>::const_iterator m_iter;
516
+ indent(out) << "- (id) initWith";
517
+ for (m_iter = members.begin(); m_iter != members.end(); ) {
518
+ if (m_iter == members.begin()) {
519
+ out << capitalize((*m_iter)->get_name());
520
+ } else {
521
+ out << (*m_iter)->get_name();
522
+ }
523
+ out << ": (" << type_name((*m_iter)->get_type()) << ") " <<
524
+ (*m_iter)->get_name();
525
+ ++m_iter;
526
+ if (m_iter != members.end()) {
527
+ out << " ";
528
+ }
529
+ }
530
+ }
531
+
532
+
533
+ /**
534
+ * Generate getter and setter declarations for all fields, plus an
535
+ * IsSet getter.
536
+ */
537
+ void t_cocoa_generator::generate_cocoa_struct_field_accessor_declarations(ofstream &out,
538
+ t_struct* tstruct,
539
+ bool is_exception) {
540
+ const vector<t_field*>& members = tstruct->get_members();
541
+ vector<t_field*>::const_iterator m_iter;
542
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
543
+ out << indent() << "- (" << type_name((*m_iter)->get_type()) << ") " << decapitalize((*m_iter)->get_name()) << ";" << endl;
544
+ out << indent() << "- (void) set" << capitalize((*m_iter)->get_name()) <<
545
+ ": (" << type_name((*m_iter)->get_type()) << ") " << (*m_iter)->get_name() << ";" << endl;
546
+ out << indent() << "- (BOOL) " << (*m_iter)->get_name() << "IsSet;" << endl << endl;
547
+ }
548
+ }
549
+
550
+
551
+ /**
552
+ * Generate struct implementation.
553
+ *
554
+ * @param tstruct The struct definition
555
+ * @param is_exception Is this an exception?
556
+ * @param is_result If this is a result it needs a different writer
557
+ */
558
+ void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream &out,
559
+ t_struct* tstruct,
560
+ bool is_exception,
561
+ bool is_result) {
562
+ indent(out) <<
563
+ "@implementation " << cocoa_prefix_ << tstruct->get_name() << endl << endl;
564
+
565
+ // exceptions need to call the designated initializer on NSException
566
+ if (is_exception) {
567
+ out << indent() << "- (id) init" << endl;
568
+ scope_up(out);
569
+ out << indent() << "return [super initWithName: @\"" << tstruct->get_name() <<
570
+ "\" reason: @\"unknown\" userInfo: nil];" << endl;
571
+ scope_down(out);
572
+ }
573
+
574
+ const vector<t_field*>& members = tstruct->get_members();
575
+ vector<t_field*>::const_iterator m_iter;
576
+
577
+ // synthesize properties
578
+ if (!members.empty()) {
579
+ out << "#if TARGET_OS_IPHONE || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)" << endl;
580
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
581
+ out << indent() << synthesize_property(*m_iter) << endl;
582
+ }
583
+ out << "#endif" << endl << endl;
584
+ }
585
+
586
+ // initializer with all fields as params
587
+ if (!members.empty()) {
588
+ generate_cocoa_struct_initializer_signature(out, tstruct);
589
+ out << endl;
590
+ scope_up(out);
591
+ if (is_exception) {
592
+ out << indent() << "self = [self init];" << endl;
593
+ } else {
594
+ out << indent() << "self = [super init];" << endl;
595
+ }
596
+
597
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
598
+ t_type* t = get_true_type((*m_iter)->get_type());
599
+ out << indent() << "__" << (*m_iter)->get_name() << " = ";
600
+ if (type_can_be_null(t)) {
601
+ out << "[" << (*m_iter)->get_name() << " retain];" << endl;
602
+ } else {
603
+ out << (*m_iter)->get_name() << ";" << endl;
604
+ }
605
+ out << indent() << "__" << (*m_iter)->get_name() << "_isset = YES;" << endl;
606
+ }
607
+
608
+ out << indent() << "return self;" << endl;
609
+ scope_down(out);
610
+ out << endl;
611
+ }
612
+
613
+ // dealloc
614
+ if (!members.empty()) {
615
+ out << "- (void) dealloc" << endl;
616
+ scope_up(out);
617
+
618
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
619
+ t_type* t = get_true_type((*m_iter)->get_type());
620
+ if (type_can_be_null(t)) {
621
+ indent(out) << "[__" << (*m_iter)->get_name() << " release];" << endl;
622
+ }
623
+ }
624
+
625
+ out << indent() << "[super dealloc];" << endl;
626
+ scope_down(out);
627
+ out << endl;
628
+ }
629
+
630
+ // the rest of the methods
631
+ generate_cocoa_struct_field_accessor_implementations(out, tstruct, is_exception);
632
+ generate_cocoa_struct_reader(out, tstruct);
633
+ if (is_result) {
634
+ generate_cocoa_struct_result_writer(out, tstruct);
635
+ } else {
636
+ generate_cocoa_struct_writer(out, tstruct);
637
+ }
638
+ generate_cocoa_struct_description(out, tstruct);
639
+
640
+ out << "@end" << endl << endl;
641
+ }
642
+
643
+
644
+ /**
645
+ * Generates a function to read all the fields of the struct.
646
+ *
647
+ * @param tstruct The struct definition
648
+ */
649
+ void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out,
650
+ t_struct* tstruct) {
651
+ out <<
652
+ "- (void) read: (id <TProtocol>) inProtocol" << endl;
653
+ scope_up(out);
654
+
655
+ const vector<t_field*>& fields = tstruct->get_members();
656
+ vector<t_field*>::const_iterator f_iter;
657
+
658
+ // Declare stack tmp variables
659
+ indent(out) << "NSString * fieldName;" << endl;
660
+ indent(out) << "int fieldType;" << endl;
661
+ indent(out) << "int fieldID;" << endl;
662
+ out << endl;
663
+
664
+ indent(out) << "[inProtocol readStructBeginReturningName: NULL];" << endl;
665
+
666
+ // Loop over reading in fields
667
+ indent(out) <<
668
+ "while (true)" << endl;
669
+ scope_up(out);
670
+
671
+ // Read beginning field marker
672
+ indent(out) <<
673
+ "[inProtocol readFieldBeginReturningName: &fieldName type: &fieldType fieldID: &fieldID];" << endl;
674
+
675
+ // Check for field STOP marker and break
676
+ indent(out) <<
677
+ "if (fieldType == TType_STOP) { " << endl;
678
+ indent_up();
679
+ indent(out) <<
680
+ "break;" << endl;
681
+ indent_down();
682
+ indent(out) <<
683
+ "}" << endl;
684
+
685
+ // Switch statement on the field we are reading
686
+ indent(out) <<
687
+ "switch (fieldID)" << endl;
688
+
689
+ scope_up(out);
690
+
691
+ // Generate deserialization code for known cases
692
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
693
+ indent(out) <<
694
+ "case " << (*f_iter)->get_key() << ":" << endl;
695
+ indent_up();
696
+ indent(out) <<
697
+ "if (fieldType == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
698
+ indent_up();
699
+
700
+ generate_deserialize_field(out, *f_iter, "fieldValue");
701
+ indent(out) << call_field_setter(*f_iter, "fieldValue") << endl;
702
+ // if this is an allocated field, release it since the struct
703
+ // is now retaining it
704
+ if (type_can_be_null((*f_iter)->get_type())) {
705
+ // deserialized strings are autorelease, so don't release them
706
+ if (!(get_true_type((*f_iter)->get_type())->is_string())) {
707
+ indent(out) << "[fieldValue release];" << endl;
708
+ }
709
+ }
710
+
711
+ indent_down();
712
+ out << indent() << "} else { " << endl;
713
+ if (log_unexpected_) {
714
+ out << indent() << " NSLog(@\"%s: field ID %i has unexpected type %i. Skipping.\", __PRETTY_FUNCTION__, fieldID, fieldType);" << endl;
715
+ }
716
+ out << indent() << " [TProtocolUtil skipType: fieldType onProtocol: inProtocol];" << endl <<
717
+ indent() << "}" << endl <<
718
+ indent() << "break;" << endl;
719
+ indent_down();
720
+ }
721
+
722
+ // In the default case we skip the field
723
+ out << indent() << "default:" << endl;
724
+ if (log_unexpected_) {
725
+ out << indent() << " NSLog(@\"%s: unexpected field ID %i with type %i. Skipping.\", __PRETTY_FUNCTION__, fieldID, fieldType);" << endl;
726
+ }
727
+ out << indent() << " [TProtocolUtil skipType: fieldType onProtocol: inProtocol];" << endl <<
728
+ indent() << " break;" << endl;
729
+
730
+ scope_down(out);
731
+
732
+ // Read field end marker
733
+ indent(out) <<
734
+ "[inProtocol readFieldEnd];" << endl;
735
+
736
+ scope_down(out);
737
+
738
+ out <<
739
+ indent() << "[inProtocol readStructEnd];" << endl;
740
+
741
+ indent_down();
742
+ out <<
743
+ indent() << "}" << endl <<
744
+ endl;
745
+ }
746
+
747
+ /**
748
+ * Generates a function to write all the fields of the struct
749
+ *
750
+ * @param tstruct The struct definition
751
+ */
752
+ void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out,
753
+ t_struct* tstruct) {
754
+ out <<
755
+ indent() << "- (void) write: (id <TProtocol>) outProtocol {" << endl;
756
+ indent_up();
757
+
758
+ string name = tstruct->get_name();
759
+ const vector<t_field*>& fields = tstruct->get_members();
760
+ vector<t_field*>::const_iterator f_iter;
761
+
762
+ out <<
763
+ indent() << "[outProtocol writeStructBeginWithName: @\"" << name << "\"];" << endl;
764
+
765
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
766
+ out <<
767
+ indent() << "if (__" << (*f_iter)->get_name() << "_isset) {" << endl;
768
+ indent_up();
769
+ bool null_allowed = type_can_be_null((*f_iter)->get_type());
770
+ if (null_allowed) {
771
+ out <<
772
+ indent() << "if (__" << (*f_iter)->get_name() << " != nil) {" << endl;
773
+ indent_up();
774
+ }
775
+
776
+ indent(out) << "[outProtocol writeFieldBeginWithName: @\"" <<
777
+ (*f_iter)->get_name() << "\" type: " << type_to_enum((*f_iter)->get_type()) <<
778
+ " fieldID: " << (*f_iter)->get_key() << "];" << endl;
779
+
780
+ // Write field contents
781
+ generate_serialize_field(out, *f_iter, "__"+(*f_iter)->get_name());
782
+
783
+ // Write field closer
784
+ indent(out) <<
785
+ "[outProtocol writeFieldEnd];" << endl;
786
+
787
+ if (null_allowed) {
788
+ scope_down(out);
789
+ }
790
+ scope_down(out);
791
+ }
792
+ // Write the struct map
793
+ out <<
794
+ indent() << "[outProtocol writeFieldStop];" << endl <<
795
+ indent() << "[outProtocol writeStructEnd];" << endl;
796
+
797
+ indent_down();
798
+ out <<
799
+ indent() << "}" << endl <<
800
+ endl;
801
+ }
802
+
803
+ /**
804
+ * Generates a function to write all the fields of the struct, which
805
+ * is a function result. These fields are only written if they are
806
+ * set, and only one of them can be set at a time.
807
+ *
808
+ * @param tstruct The struct definition
809
+ */
810
+ void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out,
811
+ t_struct* tstruct) {
812
+ out <<
813
+ indent() << "- (void) write: (id <TProtocol>) outProtocol {" << endl;
814
+ indent_up();
815
+
816
+ string name = tstruct->get_name();
817
+ const vector<t_field*>& fields = tstruct->get_members();
818
+ vector<t_field*>::const_iterator f_iter;
819
+
820
+ out <<
821
+ indent() << "[outProtocol writeStructBeginWithName: @\"" << name << "\"];" << endl;
822
+
823
+ bool first = true;
824
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
825
+ if (first) {
826
+ first = false;
827
+ out <<
828
+ endl <<
829
+ indent() << "if ";
830
+ } else {
831
+ out <<
832
+ " else if ";
833
+ }
834
+
835
+ out <<
836
+ "(__" << (*f_iter)->get_name() << "_isset) {" << endl;
837
+ indent_up();
838
+
839
+ bool null_allowed = type_can_be_null((*f_iter)->get_type());
840
+ if (null_allowed) {
841
+ out <<
842
+ indent() << "if (__" << (*f_iter)->get_name() << " != nil) {" << endl;
843
+ indent_up();
844
+ }
845
+
846
+ indent(out) << "[outProtocol writeFieldBeginWithName: @\"" <<
847
+ (*f_iter)->get_name() << "\" type: " << type_to_enum((*f_iter)->get_type()) <<
848
+ " fieldID: " << (*f_iter)->get_key() << "];" << endl;
849
+
850
+ // Write field contents
851
+ generate_serialize_field(out, *f_iter, "__"+(*f_iter)->get_name());
852
+
853
+ // Write field closer
854
+ indent(out) <<
855
+ "[outProtocol writeFieldEnd];" << endl;
856
+
857
+ if (null_allowed) {
858
+ indent_down();
859
+ indent(out) << "}" << endl;
860
+ }
861
+
862
+ indent_down();
863
+ indent(out) << "}";
864
+ }
865
+ // Write the struct map
866
+ out <<
867
+ endl <<
868
+ indent() << "[outProtocol writeFieldStop];" << endl <<
869
+ indent() << "[outProtocol writeStructEnd];" << endl;
870
+
871
+ indent_down();
872
+ out <<
873
+ indent() << "}" << endl <<
874
+ endl;
875
+ }
876
+
877
+ /**
878
+ * Generate property accessor methods for all fields in the struct.
879
+ * getter, setter, isset getter.
880
+ *
881
+ * @param tstruct The struct definition
882
+ */
883
+ void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofstream& out,
884
+ t_struct* tstruct,
885
+ bool is_exception) {
886
+ const vector<t_field*>& fields = tstruct->get_members();
887
+ vector<t_field*>::const_iterator f_iter;
888
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
889
+ t_field* field = *f_iter;
890
+ t_type* type = get_true_type(field->get_type());
891
+ std::string field_name = field->get_name();
892
+ std::string cap_name = field_name;
893
+ cap_name[0] = toupper(cap_name[0]);
894
+
895
+ // Simple getter
896
+ indent(out) << "- (" << type_name(type) << ") ";
897
+ out << field_name << " {" << endl;
898
+ indent_up();
899
+ if (!type_can_be_null(type)) {
900
+ indent(out) << "return __" << field_name << ";" << endl;
901
+ } else {
902
+ indent(out) << "return [[__" << field_name << " retain] autorelease];" << endl;
903
+ }
904
+ indent_down();
905
+ indent(out) << "}" << endl << endl;
906
+
907
+ // Simple setter
908
+ indent(out) << "- (void) set" << cap_name << ": (" << type_name(type) <<
909
+ ") " << field_name << " {" << endl;
910
+ indent_up();
911
+ if (!type_can_be_null(type)) {
912
+ indent(out) << "__" << field_name << " = " << field_name << ";" << endl;
913
+ } else {
914
+ indent(out) << "[" << field_name << " retain];" << endl;
915
+ indent(out) << "[__" << field_name << " release];" << endl;
916
+ indent(out) << "__" << field_name << " = " << field_name << ";" << endl;
917
+ }
918
+ indent(out) << "__" << field_name << "_isset = YES;" << endl;
919
+ indent_down();
920
+ indent(out) << "}" << endl << endl;
921
+
922
+ // IsSet
923
+ indent(out) << "- (BOOL) " << field_name << "IsSet {" << endl;
924
+ indent_up();
925
+ indent(out) << "return __" << field_name << "_isset;" << endl;
926
+ indent_down();
927
+ indent(out) << "}" << endl << endl;
928
+
929
+ // Unsetter - do we need this?
930
+ indent(out) << "- (void) unset" << cap_name << " {" << endl;
931
+ indent_up();
932
+ if (type_can_be_null(type)) {
933
+ indent(out) << "[__" << field_name << " release];" << endl;
934
+ indent(out) << "__" << field_name << " = nil;" << endl;
935
+ }
936
+ indent(out) << "__" << field_name << "_isset = NO;" << endl;
937
+ indent_down();
938
+ indent(out) << "}" << endl << endl;
939
+ }
940
+ }
941
+
942
+ /**
943
+ * Generates a description method for the given struct
944
+ *
945
+ * @param tstruct The struct definition
946
+ */
947
+ void t_cocoa_generator::generate_cocoa_struct_description(ofstream& out,
948
+ t_struct* tstruct) {
949
+ out <<
950
+ indent() << "- (NSString *) description {" << endl;
951
+ indent_up();
952
+
953
+ out <<
954
+ indent() << "NSMutableString * ms = [NSMutableString stringWithString: @\"" <<
955
+ tstruct->get_name() << "(\"];" << endl;
956
+
957
+ const vector<t_field*>& fields = tstruct->get_members();
958
+ vector<t_field*>::const_iterator f_iter;
959
+ bool first = true;
960
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
961
+ if (first) {
962
+ first = false;
963
+ indent(out) << "[ms appendString: @\"" << (*f_iter)->get_name() << ":\"];" << endl;
964
+ } else {
965
+ indent(out) << "[ms appendString: @\"," << (*f_iter)->get_name() << ":\"];" << endl;
966
+ }
967
+ t_type* ttype = (*f_iter)->get_type();
968
+ indent(out) << "[ms appendFormat: @\"" << format_string_for_type(ttype) << "\", __" <<
969
+ (*f_iter)->get_name() << "];" << endl;
970
+ }
971
+ out <<
972
+ indent() << "[ms appendString: @\")\"];" << endl <<
973
+ indent() << "return [NSString stringWithString: ms];" << endl;
974
+
975
+ indent_down();
976
+ indent(out) << "}" << endl <<
977
+ endl;
978
+ }
979
+
980
+
981
+ /**
982
+ * Generates a thrift service. In Objective-C this consists of a
983
+ * protocol definition, a client interface and a client implementation.
984
+ *
985
+ * @param tservice The service definition
986
+ */
987
+ void t_cocoa_generator::generate_service(t_service* tservice) {
988
+ generate_cocoa_service_protocol(f_header_, tservice);
989
+ generate_cocoa_service_client_interface(f_header_, tservice);
990
+ generate_cocoa_service_server_interface(f_header_, tservice);
991
+ generate_cocoa_service_helpers(tservice);
992
+ generate_cocoa_service_client_implementation(f_impl_, tservice);
993
+ generate_cocoa_service_server_implementation(f_impl_, tservice);
994
+ }
995
+
996
+
997
+ /**
998
+ * Generates structs for all the service return types
999
+ *
1000
+ * @param tservice The service
1001
+ */
1002
+ void t_cocoa_generator::generate_cocoa_service_helpers(t_service* tservice) {
1003
+ vector<t_function*> functions = tservice->get_functions();
1004
+ vector<t_function*>::iterator f_iter;
1005
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1006
+ t_struct* ts = (*f_iter)->get_arglist();
1007
+ generate_cocoa_struct_interface(f_impl_, ts, false);
1008
+ generate_cocoa_struct_implementation(f_impl_, ts, false, false);
1009
+ generate_function_helpers(*f_iter);
1010
+ }
1011
+ }
1012
+
1013
+ string t_cocoa_generator::function_result_helper_struct_type(t_function* tfunction) {
1014
+ return capitalize(tfunction->get_name()) + "_result";
1015
+ }
1016
+
1017
+
1018
+ string t_cocoa_generator::function_args_helper_struct_type(t_function* tfunction) {
1019
+ return tfunction->get_name() + "_args";
1020
+ }
1021
+
1022
+
1023
+ /**
1024
+ * Generates a struct and helpers for a function.
1025
+ *
1026
+ * @param tfunction The function
1027
+ */
1028
+ void t_cocoa_generator::generate_function_helpers(t_function* tfunction) {
1029
+ if (tfunction->is_oneway()) {
1030
+ return;
1031
+ }
1032
+
1033
+ // create a result struct with a success field of the return type,
1034
+ // and a field for each type of exception thrown
1035
+ t_struct result(program_, function_result_helper_struct_type(tfunction));
1036
+ t_field success(tfunction->get_returntype(), "success", 0);
1037
+ if (!tfunction->get_returntype()->is_void()) {
1038
+ result.append(&success);
1039
+ }
1040
+
1041
+ t_struct* xs = tfunction->get_xceptions();
1042
+ const vector<t_field*>& fields = xs->get_members();
1043
+ vector<t_field*>::const_iterator f_iter;
1044
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1045
+ result.append(*f_iter);
1046
+ }
1047
+
1048
+ // generate the result struct
1049
+ generate_cocoa_struct_interface(f_impl_, &result, false);
1050
+ generate_cocoa_struct_implementation(f_impl_, &result, false, true);
1051
+ }
1052
+
1053
+
1054
+ /**
1055
+ * Generates a service protocol definition.
1056
+ *
1057
+ * @param tservice The service to generate a protocol definition for
1058
+ */
1059
+ void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out,
1060
+ t_service* tservice) {
1061
+ out << "@protocol " << cocoa_prefix_ << tservice->get_name() << " <NSObject>" << endl;
1062
+
1063
+ vector<t_function*> functions = tservice->get_functions();
1064
+ vector<t_function*>::iterator f_iter;
1065
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1066
+ out << "- " << function_signature(*f_iter) << ";" <<
1067
+ " // throws ";
1068
+ t_struct* xs = (*f_iter)->get_xceptions();
1069
+ const std::vector<t_field*>& xceptions = xs->get_members();
1070
+ vector<t_field*>::const_iterator x_iter;
1071
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
1072
+ out << type_name((*x_iter)->get_type()) + ", ";
1073
+ }
1074
+ out << "TException" << endl;
1075
+ }
1076
+ out << "@end" << endl << endl;
1077
+ }
1078
+
1079
+
1080
+ /**
1081
+ * Generates a service client interface definition.
1082
+ *
1083
+ * @param tservice The service to generate a client interface definition for
1084
+ */
1085
+ void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
1086
+ t_service* tservice) {
1087
+ out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : NSObject <" <<
1088
+ cocoa_prefix_ << tservice->get_name() << "> ";
1089
+
1090
+ scope_up(out);
1091
+ out << indent() << "id <TProtocol> inProtocol;" << endl;
1092
+ out << indent() << "id <TProtocol> outProtocol;" << endl;
1093
+ scope_down(out);
1094
+
1095
+ out << "- (id) initWithProtocol: (id <TProtocol>) protocol;" << endl;
1096
+ out << "- (id) initWithInProtocol: (id <TProtocol>) inProtocol outProtocol: (id <TProtocol>) outProtocol;" << endl;
1097
+ out << "@end" << endl << endl;
1098
+ }
1099
+
1100
+
1101
+ /**
1102
+ * Generates a service server interface definition. In other words, the TProcess implementation for the
1103
+ * service definition.
1104
+ *
1105
+ * @param tservice The service to generate a client interface definition for
1106
+ */
1107
+ void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
1108
+ t_service* tservice) {
1109
+ out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Processor : NSObject <TProcessor> ";
1110
+
1111
+ scope_up(out);
1112
+ out << indent() << "id <" << cocoa_prefix_ << tservice->get_name() <<"> mService;" << endl;
1113
+ out << indent() << "NSDictionary * mMethodMap;" << endl;
1114
+ scope_down(out);
1115
+
1116
+ out << "- (id) initWith" << tservice->get_name() << ": (id <" << cocoa_prefix_ << tservice->get_name() << ">) service;" << endl;
1117
+ out << "- (id<"<<cocoa_prefix_ << tservice->get_name() << ">) service;" << endl;
1118
+
1119
+ out << "@end" << endl << endl;
1120
+ }
1121
+
1122
+
1123
+ /**
1124
+ * Generates a service client implementation.
1125
+ *
1126
+ * @param tservice The service to generate an implementation for
1127
+ */
1128
+ void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& out,
1129
+ t_service* tservice) {
1130
+ out << "@implementation " << cocoa_prefix_ << tservice->get_name() << "Client" << endl;
1131
+
1132
+ // initializers
1133
+ out << "- (id) initWithProtocol: (id <TProtocol>) protocol" << endl;
1134
+ scope_up(out);
1135
+ out << indent() << "return [self initWithInProtocol: protocol outProtocol: protocol];" << endl;
1136
+ scope_down(out);
1137
+ out << endl;
1138
+
1139
+ out << "- (id) initWithInProtocol: (id <TProtocol>) anInProtocol outProtocol: (id <TProtocol>) anOutProtocol" << endl;
1140
+ scope_up(out);
1141
+ out << indent() << "[super init];" << endl;
1142
+ out << indent() << "inProtocol = [anInProtocol retain];" << endl;
1143
+ out << indent() << "outProtocol = [anOutProtocol retain];" << endl;
1144
+ out << indent() << "return self;" << endl;
1145
+ scope_down(out);
1146
+ out << endl;
1147
+
1148
+ // dealloc
1149
+ out << "- (void) dealloc" << endl;
1150
+ scope_up(out);
1151
+ out << indent() << "[inProtocol release];" << endl;
1152
+ out << indent() << "[outProtocol release];" << endl;
1153
+ out << indent() << "[super dealloc];" << endl;
1154
+ scope_down(out);
1155
+ out << endl;
1156
+
1157
+ // generate client method implementations
1158
+ vector<t_function*> functions = tservice->get_functions();
1159
+ vector<t_function*>::const_iterator f_iter;
1160
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1161
+ string funname = (*f_iter)->get_name();
1162
+
1163
+ t_function send_function(g_type_void,
1164
+ string("send_") + (*f_iter)->get_name(),
1165
+ (*f_iter)->get_arglist());
1166
+
1167
+ string argsname = (*f_iter)->get_name() + "_args";
1168
+
1169
+ // Open function
1170
+ indent(out) <<
1171
+ "- " << function_signature(&send_function) << endl;
1172
+ scope_up(out);
1173
+
1174
+ // Serialize the request
1175
+ out <<
1176
+ indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" <<
1177
+ " type: TMessageType_CALL" <<
1178
+ " sequenceID: 0];" << endl;
1179
+
1180
+ out <<
1181
+ indent() << "[outProtocol writeStructBeginWithName: @\"" << argsname << "\"];" << endl;
1182
+
1183
+ // write out function parameters
1184
+ t_struct* arg_struct = (*f_iter)->get_arglist();
1185
+ const vector<t_field*>& fields = arg_struct->get_members();
1186
+ vector<t_field*>::const_iterator fld_iter;
1187
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
1188
+ string fieldName = (*fld_iter)->get_name();
1189
+ if (type_can_be_null((*fld_iter)->get_type())) {
1190
+ out << indent() << "if (" << fieldName << " != nil)";
1191
+ scope_up(out);
1192
+ }
1193
+ out <<
1194
+ indent() << "[outProtocol writeFieldBeginWithName: @\"" << fieldName << "\""
1195
+ " type: " << type_to_enum((*fld_iter)->get_type()) <<
1196
+ " fieldID: " << (*fld_iter)->get_key() << "];" << endl;
1197
+
1198
+ generate_serialize_field(out, *fld_iter, fieldName);
1199
+
1200
+ out <<
1201
+ indent() << "[outProtocol writeFieldEnd];" << endl;
1202
+
1203
+ if (type_can_be_null((*fld_iter)->get_type())) {
1204
+ scope_down(out);
1205
+ }
1206
+ }
1207
+
1208
+ out <<
1209
+ indent() << "[outProtocol writeFieldStop];" << endl;
1210
+ out <<
1211
+ indent() << "[outProtocol writeStructEnd];" << endl;
1212
+
1213
+ out <<
1214
+ indent() << "[outProtocol writeMessageEnd];" << endl <<
1215
+ indent() << "[[outProtocol transport] flush];" << endl;
1216
+
1217
+ scope_down(out);
1218
+ out << endl;
1219
+
1220
+ if (!(*f_iter)->is_oneway()) {
1221
+ t_struct noargs(program_);
1222
+ t_function recv_function((*f_iter)->get_returntype(),
1223
+ string("recv_") + (*f_iter)->get_name(),
1224
+ &noargs,
1225
+ (*f_iter)->get_xceptions());
1226
+ // Open function
1227
+ indent(out) <<
1228
+ "- " << function_signature(&recv_function) << endl;
1229
+ scope_up(out);
1230
+
1231
+ // TODO(mcslee): Message validation here, was the seqid etc ok?
1232
+
1233
+ // check for an exception
1234
+ out <<
1235
+ indent() << "int msgType = 0;" << endl <<
1236
+ indent() << "[inProtocol readMessageBeginReturningName: nil type: &msgType sequenceID: NULL];" << endl <<
1237
+ indent() << "if (msgType == TMessageType_EXCEPTION) {" << endl <<
1238
+ indent() << " TApplicationException * x = [TApplicationException read: inProtocol];" << endl <<
1239
+ indent() << " [inProtocol readMessageEnd];" << endl <<
1240
+ indent() << " @throw x;" << endl <<
1241
+ indent() << "}" << endl;
1242
+
1243
+ // FIXME - could optimize here to reduce creation of temporary objects.
1244
+ string resultname = function_result_helper_struct_type(*f_iter);
1245
+ out <<
1246
+ indent() << cocoa_prefix_ << resultname << " * result = [[[" << cocoa_prefix_ <<
1247
+ resultname << " alloc] init] autorelease];" << endl;
1248
+ indent(out) << "[result read: inProtocol];" << endl;
1249
+ indent(out) << "[inProtocol readMessageEnd];" << endl;
1250
+
1251
+ // Careful, only return _result if not a void function
1252
+ if (!(*f_iter)->get_returntype()->is_void()) {
1253
+ out <<
1254
+ indent() << "if ([result successIsSet]) {" << endl <<
1255
+ indent() << " return [result success];" << endl <<
1256
+ indent() << "}" << endl;
1257
+ }
1258
+
1259
+ t_struct* xs = (*f_iter)->get_xceptions();
1260
+ const std::vector<t_field*>& xceptions = xs->get_members();
1261
+ vector<t_field*>::const_iterator x_iter;
1262
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
1263
+ out <<
1264
+ indent() << "if ([result " << (*x_iter)->get_name() << "IsSet]) {" << endl <<
1265
+ indent() << " @throw [result " << (*x_iter)->get_name() << "];" << endl <<
1266
+ indent() << "}" << endl;
1267
+ }
1268
+
1269
+ // If you get here it's an exception, unless a void function
1270
+ if ((*f_iter)->get_returntype()->is_void()) {
1271
+ indent(out) <<
1272
+ "return;" << endl;
1273
+ } else {
1274
+ out <<
1275
+ indent() << "@throw [TApplicationException exceptionWithType: TApplicationException_MISSING_RESULT" << endl <<
1276
+ indent() << " reason: @\"" << (*f_iter)->get_name() << " failed: unknown result\"];" << endl;
1277
+ }
1278
+
1279
+ // Close function
1280
+ scope_down(out);
1281
+ out << endl;
1282
+ }
1283
+
1284
+ // Open function
1285
+ indent(out) <<
1286
+ "- " << function_signature(*f_iter) << endl;
1287
+ scope_up(out);
1288
+ indent(out) <<
1289
+ "[self send_" << funname;
1290
+
1291
+ // Declare the function arguments
1292
+ bool first = true;
1293
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
1294
+ if (first) {
1295
+ first = false;
1296
+ } else {
1297
+ out << " ";
1298
+ }
1299
+ out << ": " << (*fld_iter)->get_name();
1300
+ }
1301
+ out << "];" << endl;
1302
+
1303
+ if (!(*f_iter)->is_oneway()) {
1304
+ out << indent();
1305
+ if (!(*f_iter)->get_returntype()->is_void()) {
1306
+ out << "return ";
1307
+ }
1308
+ out <<
1309
+ "[self recv_" << funname << "];" << endl;
1310
+ }
1311
+ scope_down(out);
1312
+ out << endl;
1313
+ }
1314
+
1315
+ indent_down();
1316
+
1317
+ out << "@end" << endl << endl;
1318
+ }
1319
+
1320
+
1321
+ /**
1322
+ * Generates a service server implementation. In other words the actual TProcessor implementation
1323
+ * for the service.
1324
+ *
1325
+ * @param tservice The service to generate an implementation for
1326
+ */
1327
+ void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& out,
1328
+ t_service* tservice) {
1329
+ out << "@implementation " << cocoa_prefix_ << tservice->get_name() << "Processor" << endl;
1330
+ indent_up();
1331
+
1332
+ // initializer
1333
+ out << endl;
1334
+ out << "- (id) initWith" << tservice->get_name() << ": (id <" << cocoa_prefix_ << tservice->get_name() << ">) service" << endl;
1335
+ scope_up(out);
1336
+ out << indent() << "self = [super init];" << endl;
1337
+ out << indent() << "if (!self) {" << endl;
1338
+ out << indent() << " return nil;" << endl;
1339
+ out << indent() << "}" << endl;
1340
+ out << indent() << "mService = [service retain];" << endl;
1341
+ out << indent() << "mMethodMap = [[NSMutableDictionary dictionary] retain];" << endl;
1342
+
1343
+ // generate method map for routing incoming calls
1344
+ vector<t_function*> functions = tservice->get_functions();
1345
+ vector<t_function*>::const_iterator f_iter;
1346
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1347
+ string funname = (*f_iter)->get_name();
1348
+ scope_up(out);
1349
+ out << indent() << "SEL s = @selector(process_" << funname << "_withSequenceID:inProtocol:outProtocol:);" << endl;
1350
+ out << indent() << "NSMethodSignature * sig = [self methodSignatureForSelector: s];" << endl;
1351
+ out << indent() << "NSInvocation * invocation = [NSInvocation invocationWithMethodSignature: sig];" << endl;
1352
+ out << indent() << "[invocation setSelector: s];" << endl;
1353
+ out << indent() << "[invocation retainArguments];" << endl;
1354
+ out << indent() << "[mMethodMap setValue: invocation forKey: @\"" << funname << "\"];" << endl;
1355
+ scope_down(out);
1356
+ }
1357
+ out << indent() << "return self;" << endl;
1358
+ scope_down(out);
1359
+
1360
+ // implementation of the 'service' method which returns the service associated with this
1361
+ // processor
1362
+ out << endl;
1363
+ out << indent() << "- (id<"<<cocoa_prefix_ << tservice->get_name() << ">) service" << endl;
1364
+ out << indent() << "{" << endl;
1365
+ out << indent() << " return [[mService retain] autorelease];" << endl;
1366
+ out << indent() << "}" << endl;
1367
+
1368
+ // implementation of the TProcess method, which dispatches the incoming call using the method map
1369
+ out << endl;
1370
+ out << indent() << "- (BOOL) processOnInputProtocol: (id <TProtocol>) inProtocol" << endl;
1371
+ out << indent() << " outputProtocol: (id <TProtocol>) outProtocol" <<endl;
1372
+ out << indent() << "{" << endl;
1373
+ out << indent() << " NSString * messageName;" << endl;
1374
+ out << indent() << " int messageType;" << endl;
1375
+ out << indent() << " int seqID;" << endl;
1376
+ out << indent() << " [inProtocol readMessageBeginReturningName: &messageName" << endl;
1377
+ out << indent() << " type: &messageType" << endl;
1378
+ out << indent() << " sequenceID: &seqID];" << endl;
1379
+ out << indent() << " NSInvocation * invocation = [mMethodMap valueForKey: messageName];" << endl;
1380
+ out << indent() << " if (invocation == nil) {" << endl;
1381
+ out << indent() << " [TProtocolUtil skipType: TType_STRUCT onProtocol: inProtocol];" << endl;
1382
+ out << indent() << " [inProtocol readMessageEnd];" << endl;
1383
+ out << indent() << " TApplicationException * x = [TApplicationException exceptionWithType: TApplicationException_UNKNOWN_METHOD reason: [NSString stringWithFormat: @\"Invalid method name: '%@'\", messageName]];" << endl;
1384
+ out << indent() << " [outProtocol writeMessageBeginWithName: messageName" << endl;
1385
+ out << indent() << " type: TMessageType_EXCEPTION" << endl;
1386
+ out << indent() << " sequenceID: seqID];" << endl;
1387
+ out << indent() << " [x write: outProtocol];" << endl;
1388
+ out << indent() << " [outProtocol writeMessageEnd];" << endl;
1389
+ out << indent() << " [[outProtocol transport] flush];" << endl;
1390
+ out << indent() << " return YES;" << endl;
1391
+ out << indent() << " }" << endl;
1392
+ out << indent() << " // NSInvocation does not conform to NSCopying protocol" << endl;
1393
+ out << indent() << " NSInvocation * i = [NSInvocation invocationWithMethodSignature: [invocation methodSignature]];" << endl;
1394
+ out << indent() << " [i setSelector: [invocation selector]];" << endl;
1395
+ out << indent() << " [i setArgument: &seqID atIndex: 2];" << endl;
1396
+ out << indent() << " [i setArgument: &inProtocol atIndex: 3];" << endl;
1397
+ out << indent() << " [i setArgument: &outProtocol atIndex: 4];" << endl;
1398
+ out << indent() << " [i setTarget: self];" << endl;
1399
+ out << indent() << " [i invoke];" << endl;
1400
+ out << indent() << " return YES;" << endl;
1401
+ out << indent() << "}" << endl;
1402
+
1403
+ // generate a process_XXXX method for each service function, which reads args, calls the service, and writes results
1404
+ functions = tservice->get_functions();
1405
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1406
+ out << endl;
1407
+ string funname = (*f_iter)->get_name();
1408
+ out << indent() << "- (void) process_" << funname << "_withSequenceID: (int32_t) seqID inProtocol: (id<TProtocol>) inProtocol outProtocol: (id<TProtocol>) outProtocol" << endl;
1409
+ scope_up(out);
1410
+ string argstype = cocoa_prefix_ + function_args_helper_struct_type(*f_iter);
1411
+ out << indent() << argstype << " * args = [[" << argstype << " alloc] init];" << endl;
1412
+ out << indent() << "[args read: inProtocol];" << endl;
1413
+ out << indent() << "[inProtocol readMessageEnd];" << endl;
1414
+
1415
+ string resulttype = cocoa_prefix_ + function_result_helper_struct_type(*f_iter);
1416
+ out << indent() << resulttype << " * result = [[" << resulttype << " alloc] init];" << endl;
1417
+
1418
+ // make the call to the actual service object
1419
+ out << indent();
1420
+ if (!(*f_iter)->get_returntype()->is_void()) {
1421
+ out << "[result setSuccess: ";
1422
+ }
1423
+ out << "[mService " << funname;
1424
+ // supplying arguments
1425
+ t_struct* arg_struct = (*f_iter)->get_arglist();
1426
+ const vector<t_field*>& fields = arg_struct->get_members();
1427
+ vector<t_field*>::const_iterator fld_iter;
1428
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
1429
+ string fieldName = (*fld_iter)->get_name();
1430
+ out << ": [args " << fieldName << "]";
1431
+ }
1432
+ out << "]";
1433
+ if (!(*f_iter)->get_returntype()->is_void()) {
1434
+ out << "]";
1435
+ }
1436
+ out << ";" << endl;
1437
+
1438
+ // write out the result
1439
+ out << indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" << endl;
1440
+ out << indent() << " type: TMessageType_REPLY" << endl;
1441
+ out << indent() << " sequenceID: seqID];" << endl;
1442
+ out << indent() << "[result write: outProtocol];" << endl;
1443
+ out << indent() << "[outProtocol writeMessageEnd];" << endl;
1444
+ out << indent() << "[[outProtocol transport] flush];" << endl;
1445
+ out << indent() << "[result release];" << endl;
1446
+ out << indent() << "[args release];" << endl;
1447
+
1448
+ scope_down(out);
1449
+ }
1450
+
1451
+ // dealloc
1452
+ out << endl;
1453
+ out << "- (void) dealloc" << endl;
1454
+ scope_up(out);
1455
+ out << indent() << "[mService release];" << endl;
1456
+ out << indent() << "[mMethodMap release];" << endl;
1457
+ out << indent() << "[super dealloc];" << endl;
1458
+ scope_down(out);
1459
+ out << endl;
1460
+
1461
+ indent_down();
1462
+
1463
+ out << "@end" << endl << endl;
1464
+ }
1465
+
1466
+
1467
+ /**
1468
+ * Deserializes a field of any type.
1469
+ *
1470
+ * @param tfield The field
1471
+ * @param fieldName The variable name for this field
1472
+ */
1473
+ void t_cocoa_generator::generate_deserialize_field(ofstream& out,
1474
+ t_field* tfield,
1475
+ string fieldName) {
1476
+ t_type* type = get_true_type(tfield->get_type());
1477
+
1478
+ if (type->is_void()) {
1479
+ throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
1480
+ tfield->get_name();
1481
+ }
1482
+
1483
+ if (type->is_struct() || type->is_xception()) {
1484
+ generate_deserialize_struct(out,
1485
+ (t_struct*)type,
1486
+ fieldName);
1487
+ } else if (type->is_container()) {
1488
+ generate_deserialize_container(out, type, fieldName);
1489
+ } else if (type->is_base_type() || type->is_enum()) {
1490
+ indent(out) <<
1491
+ type_name(type) << " " << fieldName << " = [inProtocol ";
1492
+
1493
+ if (type->is_base_type()) {
1494
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
1495
+ switch (tbase) {
1496
+ case t_base_type::TYPE_VOID:
1497
+ throw "compiler error: cannot serialize void field in a struct: " +
1498
+ tfield->get_name();
1499
+ break;
1500
+ case t_base_type::TYPE_STRING:
1501
+ if (((t_base_type*)type)->is_binary()) {
1502
+ out << "readBinary];";
1503
+ } else {
1504
+ out << "readString];";
1505
+ }
1506
+ break;
1507
+ case t_base_type::TYPE_BOOL:
1508
+ out << "readBool];";
1509
+ break;
1510
+ case t_base_type::TYPE_BYTE:
1511
+ out << "readByte];";
1512
+ break;
1513
+ case t_base_type::TYPE_I16:
1514
+ out << "readI16];";
1515
+ break;
1516
+ case t_base_type::TYPE_I32:
1517
+ out << "readI32];";
1518
+ break;
1519
+ case t_base_type::TYPE_I64:
1520
+ out << "readI64];";
1521
+ break;
1522
+ case t_base_type::TYPE_DOUBLE:
1523
+ out << "readDouble];";
1524
+ break;
1525
+ default:
1526
+ throw "compiler error: no Objective-C name for base type " + t_base_type::t_base_name(tbase);
1527
+ }
1528
+ } else if (type->is_enum()) {
1529
+ out << "readI32];";
1530
+ }
1531
+ out <<
1532
+ endl;
1533
+ } else {
1534
+ printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
1535
+ tfield->get_name().c_str(), type_name(type).c_str());
1536
+ }
1537
+ }
1538
+
1539
+ /**
1540
+ * Generates an unserializer for a struct, allocates the struct and invokes read:
1541
+ */
1542
+ void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
1543
+ t_struct* tstruct,
1544
+ string fieldName) {
1545
+ indent(out) << type_name(tstruct) << fieldName << " = [[" <<
1546
+ type_name(tstruct, true) << " alloc] init];" << endl;
1547
+ indent(out) << "[" << fieldName << " read: inProtocol];" << endl;
1548
+ }
1549
+
1550
+ /**
1551
+ * Deserializes a container by reading its size and then iterating
1552
+ */
1553
+ void t_cocoa_generator::generate_deserialize_container(ofstream& out,
1554
+ t_type* ttype,
1555
+ string fieldName) {
1556
+ string size = tmp("_size");
1557
+ indent(out) << "int " << size << ";" << endl;
1558
+
1559
+ // Declare variables, read header
1560
+ if (ttype->is_map()) {
1561
+ indent(out)
1562
+ << "[inProtocol readMapBeginReturningKeyType: NULL valueType: NULL size: &" <<
1563
+ size << "];" << endl;
1564
+ indent(out) << "NSMutableDictionary * " << fieldName <<
1565
+ " = [[NSMutableDictionary alloc] initWithCapacity: " << size << "];" << endl;
1566
+ } else if (ttype->is_set()) {
1567
+ indent(out)
1568
+ << "[inProtocol readSetBeginReturningElementType: NULL size: &" << size << "];" << endl;
1569
+ indent(out) << "NSMutableSet * " << fieldName <<
1570
+ " = [[NSMutableSet alloc] initWithCapacity: " << size << "];" << endl;
1571
+ } else if (ttype->is_list()) {
1572
+ indent(out)
1573
+ << "[inProtocol readListBeginReturningElementType: NULL size: &" << size << "];" << endl;
1574
+ indent(out) << "NSMutableArray * " << fieldName <<
1575
+ " = [[NSMutableArray alloc] initWithCapacity: " << size << "];" << endl;
1576
+ }
1577
+ // FIXME - the code above does not verify that the element types of
1578
+ // the containers being read match the element types of the
1579
+ // containers we are reading into. Does that matter?
1580
+
1581
+ // For loop iterates over elements
1582
+ string i = tmp("_i");
1583
+ indent(out) << "int " << i << ";" << endl <<
1584
+ indent() << "for (" << i << " = 0; " <<
1585
+ i << " < " << size << "; " <<
1586
+ "++" << i << ")" << endl;
1587
+
1588
+ scope_up(out);
1589
+
1590
+ if (ttype->is_map()) {
1591
+ generate_deserialize_map_element(out, (t_map*)ttype, fieldName);
1592
+ } else if (ttype->is_set()) {
1593
+ generate_deserialize_set_element(out, (t_set*)ttype, fieldName);
1594
+ } else if (ttype->is_list()) {
1595
+ generate_deserialize_list_element(out, (t_list*)ttype, fieldName);
1596
+ }
1597
+
1598
+ scope_down(out);
1599
+
1600
+ // Read container end
1601
+ if (ttype->is_map()) {
1602
+ indent(out) << "[inProtocol readMapEnd];" << endl;
1603
+ } else if (ttype->is_set()) {
1604
+ indent(out) << "[inProtocol readSetEnd];" << endl;
1605
+ } else if (ttype->is_list()) {
1606
+ indent(out) << "[inProtocol readListEnd];" << endl;
1607
+ }
1608
+
1609
+ }
1610
+
1611
+
1612
+ /**
1613
+ * Take a variable of a given type and wrap it in code to make it
1614
+ * suitable for putting into a container, if necessary. Basically,
1615
+ * wrap scaler primitives in NSNumber objects.
1616
+ */
1617
+ string t_cocoa_generator::containerize(t_type * ttype,
1618
+ string fieldName)
1619
+ {
1620
+ // FIXME - optimize here to avoid autorelease pool?
1621
+ ttype = get_true_type(ttype);
1622
+ if (ttype->is_enum()) {
1623
+ return "[NSNumber numberWithInt: " + fieldName + "]";
1624
+ } else if (ttype->is_base_type()) {
1625
+ t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
1626
+ switch (tbase) {
1627
+ case t_base_type::TYPE_VOID:
1628
+ throw "can't containerize void";
1629
+ case t_base_type::TYPE_BOOL:
1630
+ return "[NSNumber numberWithBool: " + fieldName + "]";
1631
+ case t_base_type::TYPE_BYTE:
1632
+ return "[NSNumber numberWithUnsignedChar: " + fieldName + "]";
1633
+ case t_base_type::TYPE_I16:
1634
+ return "[NSNumber numberWithShort: " + fieldName + "]";
1635
+ case t_base_type::TYPE_I32:
1636
+ return "[NSNumber numberWithLong: " + fieldName + "]";
1637
+ case t_base_type::TYPE_I64:
1638
+ return "[NSNumber numberWithLongLong: " + fieldName + "]";
1639
+ case t_base_type::TYPE_DOUBLE:
1640
+ return "[NSNumber numberWithDouble: " + fieldName + "]";
1641
+ default:
1642
+ break;
1643
+ }
1644
+ }
1645
+
1646
+ // do nothing
1647
+ return fieldName;
1648
+ }
1649
+
1650
+
1651
+ /**
1652
+ * Generates code to deserialize a map element
1653
+ */
1654
+ void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
1655
+ t_map* tmap,
1656
+ string fieldName) {
1657
+ string key = tmp("_key");
1658
+ string val = tmp("_val");
1659
+ t_type* keyType = tmap->get_key_type();
1660
+ t_type* valType = tmap->get_val_type();
1661
+ t_field fkey(keyType, key);
1662
+ t_field fval(valType, val);
1663
+
1664
+ generate_deserialize_field(out, &fkey, key);
1665
+ generate_deserialize_field(out, &fval, val);
1666
+
1667
+ indent(out) <<
1668
+ "[" << fieldName << " setObject: " << containerize(valType, val) <<
1669
+ " forKey: " << containerize(keyType, key) << "];" << endl;
1670
+
1671
+ if (type_can_be_null(keyType)) {
1672
+ if (!(get_true_type(keyType)->is_string())) {
1673
+ indent(out) << "[" << containerize(keyType, key) << " release];" << endl;
1674
+ }
1675
+ }
1676
+
1677
+ if (type_can_be_null(valType)) {
1678
+ if (!(get_true_type(valType)->is_string())) {
1679
+ indent(out) << "[" << containerize(valType, val) << " release];" << endl;
1680
+ }
1681
+ }
1682
+ }
1683
+
1684
+ /**
1685
+ * Deserializes a set element
1686
+ */
1687
+ void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
1688
+ t_set* tset,
1689
+ string fieldName) {
1690
+ string elem = tmp("_elem");
1691
+ t_type* type = tset->get_elem_type();
1692
+ t_field felem(type, elem);
1693
+
1694
+ generate_deserialize_field(out, &felem, elem);
1695
+
1696
+ indent(out) <<
1697
+ "[" << fieldName << " addObject: " << containerize(type, elem) << "];" << endl;
1698
+
1699
+ if (type_can_be_null(type)) {
1700
+ // deserialized strings are autorelease, so don't release them
1701
+ if (!(get_true_type(type)->is_string())) {
1702
+ indent(out) << "[" << containerize(type, elem) << " release];" << endl;
1703
+ }
1704
+ }
1705
+ }
1706
+
1707
+ /**
1708
+ * Deserializes a list element
1709
+ */
1710
+ void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
1711
+ t_list* tlist,
1712
+ string fieldName) {
1713
+ string elem = tmp("_elem");
1714
+ t_type* type = tlist->get_elem_type();
1715
+ t_field felem(type, elem);
1716
+
1717
+ generate_deserialize_field(out, &felem, elem);
1718
+
1719
+ indent(out) <<
1720
+ "[" << fieldName << " addObject: " << containerize(type, elem) << "];" << endl;
1721
+
1722
+ if (type_can_be_null(type)) {
1723
+ if (!(get_true_type(type)->is_string())) {
1724
+ indent(out) << "[" << containerize(type, elem) << " release];" << endl;
1725
+ }
1726
+ }
1727
+ }
1728
+
1729
+
1730
+ /**
1731
+ * Serializes a field of any type.
1732
+ *
1733
+ * @param tfield The field to serialize
1734
+ * @param fieldName Name to of the variable holding the field
1735
+ */
1736
+ void t_cocoa_generator::generate_serialize_field(ofstream& out,
1737
+ t_field* tfield,
1738
+ string fieldName) {
1739
+ t_type* type = get_true_type(tfield->get_type());
1740
+
1741
+ // Do nothing for void types
1742
+ if (type->is_void()) {
1743
+ throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " +
1744
+ tfield->get_name();
1745
+ }
1746
+
1747
+ if (type->is_struct() || type->is_xception()) {
1748
+ generate_serialize_struct(out,
1749
+ (t_struct*)type,
1750
+ fieldName);
1751
+ } else if (type->is_container()) {
1752
+ generate_serialize_container(out,
1753
+ type,
1754
+ fieldName);
1755
+ } else if (type->is_base_type() || type->is_enum()) {
1756
+ indent(out) <<
1757
+ "[outProtocol ";
1758
+
1759
+ if (type->is_base_type()) {
1760
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
1761
+ switch (tbase) {
1762
+ case t_base_type::TYPE_VOID:
1763
+ throw
1764
+ "compiler error: cannot serialize void field in a struct: " + fieldName;
1765
+ break;
1766
+ case t_base_type::TYPE_STRING:
1767
+ if (((t_base_type*)type)->is_binary()) {
1768
+ out << "writeBinary: " << fieldName << "];";
1769
+ } else {
1770
+ out << "writeString: " << fieldName << "];";
1771
+ }
1772
+ break;
1773
+ case t_base_type::TYPE_BOOL:
1774
+ out << "writeBool: " << fieldName << "];";
1775
+ break;
1776
+ case t_base_type::TYPE_BYTE:
1777
+ out << "writeByte: " << fieldName << "];";
1778
+ break;
1779
+ case t_base_type::TYPE_I16:
1780
+ out << "writeI16: " << fieldName << "];";
1781
+ break;
1782
+ case t_base_type::TYPE_I32:
1783
+ out << "writeI32: " << fieldName << "];";
1784
+ break;
1785
+ case t_base_type::TYPE_I64:
1786
+ out << "writeI64: " << fieldName << "];";
1787
+ break;
1788
+ case t_base_type::TYPE_DOUBLE:
1789
+ out << "writeDouble: " << fieldName << "];";
1790
+ break;
1791
+ default:
1792
+ throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase);
1793
+ }
1794
+ } else if (type->is_enum()) {
1795
+ out << "writeI32: " << fieldName << "];";
1796
+ }
1797
+ out << endl;
1798
+ } else {
1799
+ printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n",
1800
+ tfield->get_name().c_str(),
1801
+ type_name(type).c_str());
1802
+ }
1803
+ }
1804
+
1805
+ /**
1806
+ * Serialize a struct.
1807
+ *
1808
+ * @param tstruct The struct to serialize
1809
+ * @param fieldName Name of variable holding struct
1810
+ */
1811
+ void t_cocoa_generator::generate_serialize_struct(ofstream& out,
1812
+ t_struct* tstruct,
1813
+ string fieldName) {
1814
+ out <<
1815
+ indent() << "[" << fieldName << " write: outProtocol];" << endl;
1816
+ }
1817
+
1818
+ /**
1819
+ * Serializes a container by writing its size then the elements.
1820
+ *
1821
+ * @param ttype The type of container
1822
+ * @param fieldName Name of variable holding container
1823
+ */
1824
+ void t_cocoa_generator::generate_serialize_container(ofstream& out,
1825
+ t_type* ttype,
1826
+ string fieldName) {
1827
+ scope_up(out);
1828
+
1829
+ if (ttype->is_map()) {
1830
+ indent(out) <<
1831
+ "[outProtocol writeMapBeginWithKeyType: " <<
1832
+ type_to_enum(((t_map*)ttype)->get_key_type()) << " valueType: " <<
1833
+ type_to_enum(((t_map*)ttype)->get_val_type()) << " size: [" <<
1834
+ fieldName << " count]];" << endl;
1835
+ } else if (ttype->is_set()) {
1836
+ indent(out) <<
1837
+ "[outProtocol writeSetBeginWithElementType: " <<
1838
+ type_to_enum(((t_set*)ttype)->get_elem_type()) << " size: [" <<
1839
+ fieldName << " count]];" << endl;
1840
+ } else if (ttype->is_list()) {
1841
+ indent(out) <<
1842
+ "[outProtocol writeListBeginWithElementType: " <<
1843
+ type_to_enum(((t_list*)ttype)->get_elem_type()) << " size: [" <<
1844
+ fieldName << " count]];" << endl;
1845
+ }
1846
+
1847
+ string iter = tmp("_iter");
1848
+ string key;
1849
+ if (ttype->is_map()) {
1850
+ key = tmp("key");
1851
+ indent(out) << "NSEnumerator * " << iter << " = [" << fieldName << " keyEnumerator];" << endl;
1852
+ indent(out) << "id " << key << ";" << endl;
1853
+ indent(out) << "while ((" << key << " = [" << iter << " nextObject]))" << endl;
1854
+ } else if (ttype->is_set()) {
1855
+ key = tmp("obj");
1856
+ indent(out) << "NSEnumerator * " << iter << " = [" << fieldName << " objectEnumerator];" << endl;
1857
+ indent(out) << "id " << key << ";" << endl;
1858
+ indent(out) << "while ((" << key << " = [" << iter << " nextObject]))" << endl;
1859
+ } else if (ttype->is_list()) {
1860
+ key = tmp("i");
1861
+ indent(out) << "int " << key << ";" << endl;
1862
+ indent(out) <<
1863
+ "for (" << key << " = 0; " << key << " < [" << fieldName << " count]; " << key << "++)" << endl;
1864
+ }
1865
+
1866
+ scope_up(out);
1867
+
1868
+ if (ttype->is_map()) {
1869
+ generate_serialize_map_element(out, (t_map*)ttype, key, fieldName);
1870
+ } else if (ttype->is_set()) {
1871
+ generate_serialize_set_element(out, (t_set*)ttype, key);
1872
+ } else if (ttype->is_list()) {
1873
+ generate_serialize_list_element(out, (t_list*)ttype, key, fieldName);
1874
+ }
1875
+
1876
+ scope_down(out);
1877
+
1878
+ if (ttype->is_map()) {
1879
+ indent(out) <<
1880
+ "[outProtocol writeMapEnd];" << endl;
1881
+ } else if (ttype->is_set()) {
1882
+ indent(out) <<
1883
+ "[outProtocol writeSetEnd];" << endl;
1884
+ } else if (ttype->is_list()) {
1885
+ indent(out) <<
1886
+ "[outProtocol writeListEnd];" << endl;
1887
+ }
1888
+
1889
+ scope_down(out);
1890
+ }
1891
+
1892
+ /**
1893
+ * Given a field variable name, wrap it in code that converts it to a
1894
+ * primitive type, if necessary.
1895
+ */
1896
+ string t_cocoa_generator::decontainerize(t_field * tfield,
1897
+ string fieldName)
1898
+ {
1899
+ t_type * ttype = get_true_type(tfield->get_type());
1900
+ if (ttype->is_enum()) {
1901
+ return "[" + fieldName + " intValue]";
1902
+ } else if (ttype->is_base_type()) {
1903
+ t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
1904
+ switch (tbase) {
1905
+ case t_base_type::TYPE_VOID:
1906
+ throw "can't decontainerize void";
1907
+ case t_base_type::TYPE_BOOL:
1908
+ return "[" + fieldName + " boolValue]";
1909
+ case t_base_type::TYPE_BYTE:
1910
+ return "[" + fieldName + " unsignedCharValue]";
1911
+ case t_base_type::TYPE_I16:
1912
+ return "[" + fieldName + " shortValue]";
1913
+ case t_base_type::TYPE_I32:
1914
+ return "[" + fieldName + " longValue]";
1915
+ case t_base_type::TYPE_I64:
1916
+ return "[" + fieldName + " longLongValue]";
1917
+ case t_base_type::TYPE_DOUBLE:
1918
+ return "[" + fieldName + " doubleValue]";
1919
+ default:
1920
+ break;
1921
+ }
1922
+ }
1923
+
1924
+ // do nothing
1925
+ return fieldName;
1926
+ }
1927
+
1928
+
1929
+ /**
1930
+ * Serializes the members of a map.
1931
+ */
1932
+ void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
1933
+ t_map* tmap,
1934
+ string key,
1935
+ string mapName) {
1936
+ t_field kfield(tmap->get_key_type(), key);
1937
+ generate_serialize_field(out, &kfield, decontainerize(&kfield, key));
1938
+ t_field vfield(tmap->get_val_type(), "[" + mapName + " objectForKey: " + key + "]");
1939
+ generate_serialize_field(out, &vfield, decontainerize(&vfield, vfield.get_name()));
1940
+ }
1941
+
1942
+ /**
1943
+ * Serializes the members of a set.
1944
+ */
1945
+ void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
1946
+ t_set* tset,
1947
+ string elementName) {
1948
+ t_field efield(tset->get_elem_type(), elementName);
1949
+ generate_serialize_field(out, &efield, decontainerize(&efield, elementName));
1950
+ }
1951
+
1952
+ /**
1953
+ * Serializes the members of a list.
1954
+ */
1955
+ void t_cocoa_generator::generate_serialize_list_element(ofstream& out,
1956
+ t_list* tlist,
1957
+ string index,
1958
+ string listName) {
1959
+ t_field efield(tlist->get_elem_type(), "[" + listName + " objectAtIndex: " + index + "]");
1960
+ generate_serialize_field(out, &efield, decontainerize(&efield, efield.get_name()));
1961
+ }
1962
+
1963
+
1964
+ /**
1965
+ * Returns an Objective-C name
1966
+ *
1967
+ * @param ttype The type
1968
+ * @param class_ref Do we want a Class reference istead of a type reference?
1969
+ * @return Java type name, i.e. HashMap<Key,Value>
1970
+ */
1971
+ string t_cocoa_generator::type_name(t_type* ttype, bool class_ref) {
1972
+ if (ttype->is_typedef()) {
1973
+ return cocoa_prefix_ + ttype->get_name();
1974
+ }
1975
+
1976
+ string result;
1977
+ if (ttype->is_base_type()) {
1978
+ return base_type_name((t_base_type*)ttype);
1979
+ } else if (ttype->is_enum()) {
1980
+ return "int";
1981
+ } else if (ttype->is_map()) {
1982
+ result = "NSDictionary";
1983
+ } else if (ttype->is_set()) {
1984
+ result = "NSSet";
1985
+ } else if (ttype->is_list()) {
1986
+ result = "NSArray";
1987
+ } else {
1988
+ // Check for prefix
1989
+ t_program* program = ttype->get_program();
1990
+ if (program != NULL) {
1991
+ result = program->get_namespace("cocoa") + ttype->get_name();
1992
+ } else {
1993
+ result = ttype->get_name();
1994
+ }
1995
+ }
1996
+
1997
+ if (!class_ref) {
1998
+ result += " *";
1999
+ }
2000
+ return result;
2001
+ }
2002
+
2003
+ /**
2004
+ * Returns the Objective-C type that corresponds to the thrift type.
2005
+ *
2006
+ * @param tbase The base type
2007
+ */
2008
+ string t_cocoa_generator::base_type_name(t_base_type* type) {
2009
+ t_base_type::t_base tbase = type->get_base();
2010
+
2011
+ switch (tbase) {
2012
+ case t_base_type::TYPE_VOID:
2013
+ return "void";
2014
+ case t_base_type::TYPE_STRING:
2015
+ if (type->is_binary()) {
2016
+ return "NSData *";
2017
+ } else {
2018
+ return "NSString *";
2019
+ }
2020
+ case t_base_type::TYPE_BOOL:
2021
+ return "BOOL";
2022
+ case t_base_type::TYPE_BYTE:
2023
+ return "uint8_t";
2024
+ case t_base_type::TYPE_I16:
2025
+ return"int16_t";
2026
+ case t_base_type::TYPE_I32:
2027
+ return "int32_t";
2028
+ case t_base_type::TYPE_I64:
2029
+ return"int64_t";
2030
+ case t_base_type::TYPE_DOUBLE:
2031
+ return "double";
2032
+ default:
2033
+ throw "compiler error: no objective-c name for base type " + t_base_type::t_base_name(tbase);
2034
+ }
2035
+ }
2036
+
2037
+
2038
+ /**
2039
+ * Spit out code that evaluates to the specified constant value.
2040
+ */
2041
+ string t_cocoa_generator::render_const_value(string name,
2042
+ t_type* type,
2043
+ t_const_value* value,
2044
+ bool containerize_it) {
2045
+ type = get_true_type(type);
2046
+ std::ostringstream render;
2047
+
2048
+ if (type->is_base_type()) {
2049
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
2050
+ switch (tbase) {
2051
+ case t_base_type::TYPE_STRING:
2052
+ render << "@\"" << get_escaped_string(value) << '"';
2053
+ break;
2054
+ case t_base_type::TYPE_BOOL:
2055
+ render << ((value->get_integer() > 0) ? "YES" : "NO");
2056
+ break;
2057
+ case t_base_type::TYPE_BYTE:
2058
+ case t_base_type::TYPE_I16:
2059
+ case t_base_type::TYPE_I32:
2060
+ case t_base_type::TYPE_I64:
2061
+ render << value->get_integer();
2062
+ break;
2063
+ case t_base_type::TYPE_DOUBLE:
2064
+ if (value->get_type() == t_const_value::CV_INTEGER) {
2065
+ render << value->get_integer();
2066
+ } else {
2067
+ render << value->get_double();
2068
+ }
2069
+ break;
2070
+ default:
2071
+ throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
2072
+ }
2073
+ } else if (type->is_enum()) {
2074
+ render << value->get_integer();
2075
+ } else if (type->is_struct() || type->is_xception()) {
2076
+ render << "[[" << type_name(type, true) << " alloc] initWith";
2077
+ const vector<t_field*>& fields = ((t_struct*)type)->get_members();
2078
+ vector<t_field*>::const_iterator f_iter;
2079
+ const map<t_const_value*, t_const_value*>& val = value->get_map();
2080
+ map<t_const_value*, t_const_value*>::const_iterator v_iter;
2081
+ bool first = true;
2082
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
2083
+ t_type* field_type = NULL;
2084
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
2085
+ if ((*f_iter)->get_name() == v_iter->first->get_string()) {
2086
+ field_type = (*f_iter)->get_type();
2087
+ }
2088
+ }
2089
+ if (field_type == NULL) {
2090
+ throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
2091
+ }
2092
+ if (first) {
2093
+ render << capitalize(v_iter->first->get_string());
2094
+ first = false;
2095
+ } else {
2096
+ render << " " << v_iter->first->get_string();
2097
+ }
2098
+ render << ": " << render_const_value(name, field_type, v_iter->second);
2099
+ }
2100
+ render << "]";
2101
+ } else if (type->is_map()) {
2102
+ render << "[[NSDictionary alloc] initWithObjectsAndKeys: ";
2103
+ t_type* ktype = ((t_map*)type)->get_key_type();
2104
+ t_type* vtype = ((t_map*)type)->get_val_type();
2105
+ const map<t_const_value*, t_const_value*>& val = value->get_map();
2106
+ map<t_const_value*, t_const_value*>::const_iterator v_iter;
2107
+ bool first = true;
2108
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
2109
+ string key = render_const_value(name, ktype, v_iter->first, true);
2110
+ string val = render_const_value(name, vtype, v_iter->second, true);
2111
+ if (first) {
2112
+ first = false;
2113
+ } else {
2114
+ render << ", ";
2115
+ }
2116
+ render << val << ", " << key;
2117
+ }
2118
+ render << ", nil]";
2119
+ } else if (type->is_list()) {
2120
+ render << "[[NSArray alloc] initWithObjects: ";
2121
+ t_type * etype = ((t_list*)type)->get_elem_type();
2122
+ const vector<t_const_value*>& val = value->get_list();
2123
+ bool first = true;
2124
+ vector<t_const_value*>::const_iterator v_iter;
2125
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
2126
+ if (first) {
2127
+ first = false;
2128
+ } else {
2129
+ render << ", ";
2130
+ }
2131
+ render << render_const_value(name, etype, *v_iter, true);
2132
+ }
2133
+ render << ", nil]";
2134
+ } else if (type->is_set()) {
2135
+ render << "[[NSSet alloc] initWithObjects: ";
2136
+ t_type * etype = ((t_set*)type)->get_elem_type();
2137
+ const vector<t_const_value*>& val = value->get_list();
2138
+ bool first = true;
2139
+ vector<t_const_value*>::const_iterator v_iter;
2140
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
2141
+ if (first) {
2142
+ first = false;
2143
+ } else {
2144
+ render << ", ";
2145
+ }
2146
+ render << render_const_value(name, etype, *v_iter, true);
2147
+ }
2148
+ render << ", nil]";
2149
+ } else {
2150
+ throw "don't know how to render constant for type: " + type->get_name();
2151
+ }
2152
+
2153
+ if (containerize_it) {
2154
+ return containerize(type, render.str());
2155
+ }
2156
+
2157
+ return render.str();
2158
+ }
2159
+
2160
+
2161
+ /**
2162
+ * Declares a field.
2163
+ *
2164
+ * @param ttype The type
2165
+ */
2166
+ string t_cocoa_generator::declare_field(t_field* tfield) {
2167
+ return type_name(tfield->get_type()) + " __" + tfield->get_name() + ";";
2168
+ }
2169
+
2170
+ /**
2171
+ * Declares an Objective-C 2.0 property.
2172
+ *
2173
+ * @param tfield The field to declare a property for
2174
+ */
2175
+ string t_cocoa_generator::declare_property(t_field* tfield) {
2176
+ std::ostringstream render;
2177
+ render << "@property (nonatomic, ";
2178
+
2179
+ if (type_can_be_null(tfield->get_type()))
2180
+ render << "retain, ";
2181
+
2182
+ render << "getter=" << decapitalize(tfield->get_name()) <<
2183
+ ", setter=set" << capitalize(tfield->get_name()) + ":) " <<
2184
+ type_name(tfield->get_type()) << " " << tfield->get_name() << ";";
2185
+
2186
+ return render.str();
2187
+ }
2188
+
2189
+ /**
2190
+ * Synthesizes an Objective-C 2.0 property.
2191
+ *
2192
+ * @param tfield The field to synthesize a property for
2193
+ */
2194
+ string t_cocoa_generator::synthesize_property(t_field* tfield) {
2195
+ return "@synthesize " + tfield->get_name() + ";";
2196
+ }
2197
+
2198
+ /**
2199
+ * Renders a function signature
2200
+ *
2201
+ * @param tfunction Function definition
2202
+ * @return String of rendered function definition
2203
+ */
2204
+ string t_cocoa_generator::function_signature(t_function* tfunction) {
2205
+ t_type* ttype = tfunction->get_returntype();
2206
+ std::string result =
2207
+ "(" + type_name(ttype) + ") " + tfunction->get_name() + argument_list(tfunction->get_arglist());
2208
+ return result;
2209
+ }
2210
+
2211
+
2212
+ /**
2213
+ * Renders a colon separated list of types and names, suitable for an
2214
+ * objective-c parameter list
2215
+ */
2216
+ string t_cocoa_generator::argument_list(t_struct* tstruct) {
2217
+ string result = "";
2218
+
2219
+ const vector<t_field*>& fields = tstruct->get_members();
2220
+ vector<t_field*>::const_iterator f_iter;
2221
+ bool first = true;
2222
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
2223
+ if (first) {
2224
+ first = false;
2225
+ } else {
2226
+ result += " ";
2227
+ }
2228
+ result += ": (" + type_name((*f_iter)->get_type()) + ") " + (*f_iter)->get_name();
2229
+ }
2230
+ return result;
2231
+ }
2232
+
2233
+
2234
+ /**
2235
+ * Converts the parse type to an Objective-C enum string for the given type.
2236
+ */
2237
+ string t_cocoa_generator::type_to_enum(t_type* type) {
2238
+ type = get_true_type(type);
2239
+
2240
+ if (type->is_base_type()) {
2241
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
2242
+ switch (tbase) {
2243
+ case t_base_type::TYPE_VOID:
2244
+ throw "NO T_VOID CONSTRUCT";
2245
+ case t_base_type::TYPE_STRING:
2246
+ return "TType_STRING";
2247
+ case t_base_type::TYPE_BOOL:
2248
+ return "TType_BOOL";
2249
+ case t_base_type::TYPE_BYTE:
2250
+ return "TType_BYTE";
2251
+ case t_base_type::TYPE_I16:
2252
+ return "TType_I16";
2253
+ case t_base_type::TYPE_I32:
2254
+ return "TType_I32";
2255
+ case t_base_type::TYPE_I64:
2256
+ return "TType_I64";
2257
+ case t_base_type::TYPE_DOUBLE:
2258
+ return "TType_DOUBLE";
2259
+ }
2260
+ } else if (type->is_enum()) {
2261
+ return "TType_I32";
2262
+ } else if (type->is_struct() || type->is_xception()) {
2263
+ return "TType_STRUCT";
2264
+ } else if (type->is_map()) {
2265
+ return "TType_MAP";
2266
+ } else if (type->is_set()) {
2267
+ return "TType_SET";
2268
+ } else if (type->is_list()) {
2269
+ return "TType_LIST";
2270
+ }
2271
+
2272
+ throw "INVALID TYPE IN type_to_enum: " + type->get_name();
2273
+ }
2274
+
2275
+
2276
+ /**
2277
+ * Returns a format string specifier for the supplied parse type.
2278
+ */
2279
+ string t_cocoa_generator::format_string_for_type(t_type* type) {
2280
+ type = get_true_type(type);
2281
+
2282
+ if (type->is_base_type()) {
2283
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
2284
+ switch (tbase) {
2285
+ case t_base_type::TYPE_VOID:
2286
+ throw "NO T_VOID CONSTRUCT";
2287
+ case t_base_type::TYPE_STRING:
2288
+ return "\\\"%@\\\"";
2289
+ case t_base_type::TYPE_BOOL:
2290
+ return "%i";
2291
+ case t_base_type::TYPE_BYTE:
2292
+ return "%i";
2293
+ case t_base_type::TYPE_I16:
2294
+ return "%hi";
2295
+ case t_base_type::TYPE_I32:
2296
+ return "%i";
2297
+ case t_base_type::TYPE_I64:
2298
+ return "%qi";
2299
+ case t_base_type::TYPE_DOUBLE:
2300
+ return "%f";
2301
+ }
2302
+ } else if (type->is_enum()) {
2303
+ return "%i";
2304
+ } else if (type->is_struct() || type->is_xception()) {
2305
+ return "%@";
2306
+ } else if (type->is_map()) {
2307
+ return "%@";
2308
+ } else if (type->is_set()) {
2309
+ return "%@";
2310
+ } else if (type->is_list()) {
2311
+ return "%@";
2312
+ }
2313
+
2314
+ throw "INVALID TYPE IN format_string_for_type: " + type->get_name();
2315
+ }
2316
+
2317
+ /**
2318
+ * Generate a call to a field's setter.
2319
+ *
2320
+ * @param tfield Field the setter is being called on
2321
+ * @param fieldName Name of variable to pass to setter
2322
+ */
2323
+
2324
+ string t_cocoa_generator::call_field_setter(t_field* tfield, string fieldName) {
2325
+ return "[self set" + capitalize(tfield->get_name()) + ": " + fieldName + "];";
2326
+ }
2327
+
2328
+
2329
+ THRIFT_REGISTER_GENERATOR(cocoa, "Cocoa",
2330
+ " log_unexpected: Log every time an unexpected field ID or type is encountered.\n"
2331
+ );