transactd 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +46 -67
  3. data/BUILD_WIN-JA +106 -63
  4. data/CMakeLists.txt +40 -15
  5. data/README +219 -75
  6. data/README-JA +207 -76
  7. data/README_ORMSRCGEN +118 -0
  8. data/README_ORMSRCGEN-JA +115 -0
  9. data/bin/common/tdclc_32_2_0.dll +0 -0
  10. data/bin/common/tdclc_64_2_0.dll +0 -0
  11. data/build/common/check_for_link_iconv.cmake +18 -14
  12. data/build/common/create_symlink.cmake.in +25 -0
  13. data/build/common/get_boost_libs.cmake +23 -23
  14. data/build/common/options.cmake +0 -66
  15. data/build/common/smart_install.cmake +3 -3
  16. data/build/common/transactd.rc.in +15 -5
  17. data/build/common/transactd_cl_common.cmake +37 -18
  18. data/build/common/transactd_cl_output.cmake +55 -13
  19. data/build/common/transactd_common.cmake +108 -31
  20. data/build/swig/php/generate.cmake.in +15 -17
  21. data/build/swig/php/generate.cmd.in +15 -9
  22. data/build/swig/php/php.swg +124 -82
  23. data/build/swig/php/transactd.no_yield.php +4494 -0
  24. data/build/swig/php/transactd.no_yield.php.git.patch +685 -0
  25. data/build/swig/php/transactd.no_yield.php.patch +685 -0
  26. data/build/swig/php/transactd.yield.php +4461 -0
  27. data/build/swig/php/transactd.yield.php.git.patch +652 -0
  28. data/build/swig/php/transactd.yield.php.patch +652 -0
  29. data/build/swig/referencecounter.h +79 -0
  30. data/build/swig/ruby/ruby.swg +226 -76
  31. data/build/swig/ruby/threadBlockRegionWrapper.h +71 -0
  32. data/build/swig/ruby/without_gvl.swg +87 -0
  33. data/build/swig/tdcl.i +659 -170
  34. data/build/swig/validatablepointer.h +91 -0
  35. data/build/tdclc/CMakeLists.txt +49 -34
  36. data/build/tdclc/{tdclc_64.cbproj → tdclc.cbproj} +65 -20
  37. data/build/tdclc/tdclc.rc +0 -0
  38. data/build/tdclcpp/CMakeLists.txt +84 -20
  39. data/build/tdclcpp/tdclcpp.rc +0 -0
  40. data/build/tdclcpp/{tdclcpp_bcb_64.cbproj → tdclcpp_bc.cbproj} +168 -44
  41. data/build/tdclrb/CMakeLists.txt +84 -66
  42. data/build/tdclrb/bldgem/extconf.rb +28 -3
  43. data/build/tdclrb/gem/helper.rb +11 -1
  44. data/build/tdclrb/gem_output.cmake +20 -16
  45. data/index_ja.html +15 -0
  46. data/source/bzs/db/IBlobBuffer.h +15 -17
  47. data/source/bzs/db/blobBuffer.h +186 -140
  48. data/source/bzs/db/blobStructs.h +37 -37
  49. data/source/bzs/db/engine/mysql/IReadRecords.h +34 -34
  50. data/source/bzs/db/engine/mysql/bookmark.h +150 -147
  51. data/source/bzs/db/engine/mysql/database.cpp +1721 -1526
  52. data/source/bzs/db/engine/mysql/database.h +608 -370
  53. data/source/bzs/db/engine/mysql/dbManager.cpp +213 -201
  54. data/source/bzs/db/engine/mysql/dbManager.h +115 -104
  55. data/source/bzs/db/engine/mysql/errorMessage.cpp +49 -50
  56. data/source/bzs/db/engine/mysql/errorMessage.h +25 -26
  57. data/source/bzs/db/engine/mysql/fieldAccess.h +55 -61
  58. data/source/bzs/db/engine/mysql/mydebuglog.cpp +326 -292
  59. data/source/bzs/db/engine/mysql/mydebuglog.h +63 -55
  60. data/source/bzs/db/engine/mysql/mysqlInternal.h +182 -125
  61. data/source/bzs/db/engine/mysql/mysqlThd.cpp +121 -121
  62. data/source/bzs/db/engine/mysql/mysqlThd.h +20 -20
  63. data/source/bzs/db/engine/mysql/percentageKey.h +241 -228
  64. data/source/bzs/db/protocol/ICommandExecuter.h +18 -17
  65. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +543 -514
  66. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +155 -158
  67. data/source/bzs/db/protocol/tdap/btrDate.cpp +213 -180
  68. data/source/bzs/db/protocol/tdap/btrDate.h +39 -37
  69. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +173 -0
  70. data/source/bzs/db/protocol/tdap/client/activeTable.h +165 -0
  71. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +370 -0
  72. data/source/bzs/db/protocol/tdap/client/bulkInsert.h +13 -23
  73. data/source/bzs/db/protocol/tdap/client/client.cpp +81 -68
  74. data/source/bzs/db/protocol/tdap/client/client.h +361 -320
  75. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +17 -22
  76. data/source/bzs/db/protocol/tdap/client/connMgr.h +17 -19
  77. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +243 -0
  78. data/source/bzs/db/protocol/tdap/client/connectionPool.h +109 -0
  79. data/source/bzs/db/protocol/tdap/client/database.cpp +327 -219
  80. data/source/bzs/db/protocol/tdap/client/database.h +141 -118
  81. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +60 -62
  82. data/source/bzs/db/protocol/tdap/client/databaseManager.h +255 -0
  83. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +315 -202
  84. data/source/bzs/db/protocol/tdap/client/dbDef.h +40 -32
  85. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +390 -371
  86. data/source/bzs/db/protocol/tdap/client/errorMessage.cpp +148 -56
  87. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +149 -57
  88. data/source/bzs/db/protocol/tdap/client/export.h +35 -0
  89. data/source/bzs/db/protocol/tdap/client/field.cpp +1985 -0
  90. data/source/bzs/db/protocol/tdap/client/field.h +393 -0
  91. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +14 -14
  92. data/source/bzs/db/protocol/tdap/client/fieldDDF.h +11 -14
  93. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +123 -0
  94. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +58 -0
  95. data/source/bzs/db/protocol/tdap/client/fields.h +178 -0
  96. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +13 -16
  97. data/source/bzs/db/protocol/tdap/client/fileDDF.h +11 -17
  98. data/source/bzs/db/protocol/tdap/client/filter.h +423 -259
  99. data/source/bzs/db/protocol/tdap/client/groupComp.h +117 -0
  100. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +818 -0
  101. data/source/bzs/db/protocol/tdap/client/groupQuery.h +281 -0
  102. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +14 -17
  103. data/source/bzs/db/protocol/tdap/client/indexDDF.h +11 -14
  104. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +231 -0
  105. data/source/bzs/db/protocol/tdap/client/memRecord.h +145 -0
  106. data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +448 -0
  107. data/source/bzs/db/protocol/tdap/client/memRecordset.h +159 -0
  108. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +300 -173
  109. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +53 -36
  110. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +171 -128
  111. data/source/bzs/db/protocol/tdap/client/nsTable.h +121 -87
  112. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +173 -0
  113. data/source/bzs/db/protocol/tdap/client/recordset.cpp +209 -0
  114. data/source/bzs/db/protocol/tdap/client/recordset.h +86 -0
  115. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +596 -0
  116. data/source/bzs/db/protocol/tdap/client/request.h +227 -170
  117. data/source/bzs/db/protocol/tdap/client/serializer.cpp +1288 -0
  118. data/source/bzs/db/protocol/tdap/client/serializer.h +295 -0
  119. data/source/bzs/db/protocol/tdap/client/sharedData.cpp +9 -12
  120. data/source/bzs/db/protocol/tdap/client/sharedData.h +18 -16
  121. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +494 -473
  122. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +51 -53
  123. data/source/bzs/db/protocol/tdap/client/stringConverter.h +214 -148
  124. data/source/bzs/db/protocol/tdap/client/table.cpp +929 -1665
  125. data/source/bzs/db/protocol/tdap/client/table.h +413 -87
  126. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +642 -534
  127. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +25 -40
  128. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +11 -15
  129. data/source/bzs/db/protocol/tdap/client/trdormapi.h +378 -437
  130. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -1
  131. data/source/bzs/db/protocol/tdap/fieldComp.h +127 -0
  132. data/source/bzs/db/protocol/tdap/myDateTime.cpp +352 -345
  133. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +75 -78
  134. data/source/bzs/db/protocol/tdap/mysql/characterset.h +18 -19
  135. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +216 -199
  136. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +23 -14
  137. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +354 -314
  138. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +57 -47
  139. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +905 -739
  140. data/source/bzs/db/protocol/tdap/mysql/request.h +152 -159
  141. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +1044 -879
  142. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +87 -81
  143. data/source/bzs/db/protocol/tdap/tdapRequest.h +162 -130
  144. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +368 -166
  145. data/source/bzs/db/protocol/tdap/tdapSchema.h +702 -566
  146. data/source/bzs/db/protocol/tdap/tdapcapi.h +387 -353
  147. data/source/bzs/db/transactd/appBuilderImple.h +21 -20
  148. data/source/bzs/db/transactd/appModule.cpp +350 -98
  149. data/source/bzs/db/transactd/appModule.h +31 -37
  150. data/source/bzs/db/transactd/connManager.cpp +138 -135
  151. data/source/bzs/db/transactd/connManager.h +28 -21
  152. data/source/bzs/db/transactd/connectionRecord.h +39 -39
  153. data/source/bzs/db/transactd/transactd.cpp +217 -203
  154. data/source/bzs/env/boost_bcb_link.h +131 -0
  155. data/source/bzs/env/compiler.h +136 -79
  156. data/source/bzs/env/crosscompile.cpp +57 -57
  157. data/source/bzs/env/crosscompile.h +130 -115
  158. data/source/bzs/env/fileopen.h +7 -8
  159. data/source/bzs/env/mbcswchrLinux.cpp +4 -9
  160. data/source/bzs/env/mbcswchrLinux.h +37 -34
  161. data/source/bzs/env/tcharMinGW.h +59 -0
  162. data/source/bzs/env/tstring.h +90 -95
  163. data/source/bzs/example/changeSchema.cpp +22 -23
  164. data/source/bzs/example/changeSchema_c.cpp +22 -24
  165. data/source/bzs/example/connection_pool_c.cpp +49 -104
  166. data/source/bzs/example/createDatabase.cpp +40 -47
  167. data/source/bzs/example/createDatabase_c.cpp +38 -43
  168. data/source/bzs/example/deleteRecords.cpp +10 -15
  169. data/source/bzs/example/deleteRecords_c.cpp +10 -14
  170. data/source/bzs/example/dropDatabase.cpp +3 -9
  171. data/source/bzs/example/dropDatabase_c.cpp +5 -6
  172. data/source/bzs/example/insertRecords.cpp +37 -29
  173. data/source/bzs/example/insertRecords_c.cpp +19 -25
  174. data/source/bzs/example/ormap_c.cpp +621 -0
  175. data/source/bzs/example/queryData.cpp +371 -0
  176. data/source/bzs/example/queryData.h +16 -0
  177. data/source/bzs/example/query_c.cpp +109 -0
  178. data/source/bzs/example/readRecords.cpp +27 -27
  179. data/source/bzs/example/readRecords_c.cpp +25 -23
  180. data/source/bzs/example/updateRecords.cpp +16 -21
  181. data/source/bzs/example/updateRecords_c.cpp +8 -12
  182. data/source/bzs/example/update_with_transaction.cpp +21 -24
  183. data/source/bzs/example/update_with_transaction_c.cpp +12 -15
  184. data/source/bzs/example/useORMRecord.cpp +177 -0
  185. data/source/bzs/netsvc/client/tcpClient.cpp +167 -156
  186. data/source/bzs/netsvc/client/tcpClient.h +541 -489
  187. data/source/bzs/netsvc/server/IAppModule.h +119 -32
  188. data/source/bzs/netsvc/server/iserver.h +21 -23
  189. data/source/bzs/netsvc/server/serverCpt.cpp +421 -391
  190. data/source/bzs/netsvc/server/serverCpt.h +41 -43
  191. data/source/bzs/netsvc/server/serverPipe.cpp +580 -565
  192. data/source/bzs/netsvc/server/serverPipe.h +44 -45
  193. data/source/bzs/netsvc/server/serverTpool.cpp +333 -303
  194. data/source/bzs/netsvc/server/serverTpool.h +38 -43
  195. data/source/bzs/rtl/benchmark.cpp +91 -31
  196. data/source/bzs/rtl/benchmark.h +76 -22
  197. data/source/bzs/rtl/datetime.cpp +231 -233
  198. data/source/bzs/rtl/datetime.h +16 -16
  199. data/source/bzs/rtl/debuglog.cpp +48 -51
  200. data/source/bzs/rtl/debuglog.h +55 -44
  201. data/source/bzs/rtl/exception.h +55 -48
  202. data/source/bzs/rtl/stl_uty.cpp +27 -28
  203. data/source/bzs/rtl/stl_uty.h +28 -29
  204. data/source/bzs/rtl/stringBuffers.cpp +8 -6
  205. data/source/bzs/rtl/stringBuffers.h +16 -9
  206. data/source/bzs/rtl/strtrim.cpp +90 -91
  207. data/source/bzs/rtl/strtrim.h +14 -16
  208. data/source/bzs/test/tdclatl/bench_query_atl.js +647 -0
  209. data/source/bzs/test/tdclatl/bench_tdclatl.js +303 -303
  210. data/source/bzs/test/tdclatl/test_query_atl.js +669 -0
  211. data/source/bzs/test/tdclphp/bench.php +357 -0
  212. data/source/bzs/test/tdclphp/transactd_Test.php +907 -303
  213. data/source/bzs/test/tdclphp/transactd_blob_Test.php +21 -49
  214. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +41 -75
  215. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +23 -37
  216. data/source/bzs/test/tdclphp/transactd_pool_Test.php +120 -0
  217. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +4 -6
  218. data/source/bzs/test/tdclrb/prepare.rb +15 -12
  219. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +29 -32
  220. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -29
  221. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +18 -19
  222. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +107 -0
  223. data/source/bzs/test/tdclrb/transactd_spec.rb +734 -142
  224. data/source/bzs/test/transactdBench/query_bench.cpp +156 -0
  225. data/source/bzs/test/transactdBench/scaling_bench.cpp +265 -0
  226. data/source/bzs/test/transactdBench/transactdBench.cpp +107 -83
  227. data/source/bzs/test/transactdBench/transactdBench2.cpp +122 -83
  228. data/source/bzs/test/transactdBench/workerBase.cpp +5 -0
  229. data/source/bzs/test/transactdBench/workerBase.h +88 -0
  230. data/source/bzs/test/transactdBench/workerMySQLImple.h +333 -0
  231. data/source/bzs/test/transactdBench/workerTransactdImple.h +201 -0
  232. data/source/bzs/test/trdclengn/test_blob.cpp +121 -73
  233. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1244 -426
  234. data/source/global/ormsrcgen/confParam.h +80 -0
  235. data/source/global/ormsrcgen/fieldName.cpp +77 -0
  236. data/source/global/ormsrcgen/fieldName.h +43 -0
  237. data/source/global/ormsrcgen/main.cpp +196 -0
  238. data/source/global/ormsrcgen/srcgen.cpp +763 -0
  239. data/source/global/ormsrcgen/srcgen.h +72 -0
  240. data/source/global/ormsrcgen/template/fieldNameList_sample.txt +2 -0
  241. data/source/global/ormsrcgen/template/ormDataClass_template.cpp +48 -0
  242. data/source/global/ormsrcgen/template/ormDataClass_template.h +34 -0
  243. data/source/global/ormsrcgen/template/ormMapClass_template.cpp +51 -0
  244. data/source/global/ormsrcgen/template/ormMapClass_template.h +62 -0
  245. data/source/global/ormsrcgen/template/template.cnf +38 -0
  246. data/source/global/querystmts/querystmts.cpp +237 -0
  247. data/source/global/tdclatl/ConnectParams.cpp +77 -0
  248. data/source/global/tdclatl/ConnectParams.h +70 -0
  249. data/source/global/tdclatl/Database.cpp +132 -128
  250. data/source/global/tdclatl/Database.h +60 -49
  251. data/source/global/tdclatl/DbDef.cpp +68 -64
  252. data/source/global/tdclatl/DbDef.h +36 -36
  253. data/source/global/tdclatl/Field.cpp +12 -17
  254. data/source/global/tdclatl/Field.h +15 -12
  255. data/source/global/tdclatl/FieldDef.cpp +75 -36
  256. data/source/global/tdclatl/FieldDef.h +38 -19
  257. data/source/global/tdclatl/FieldDefs.cpp +74 -0
  258. data/source/global/tdclatl/FieldDefs.h +56 -0
  259. data/source/global/tdclatl/FieldNames.cpp +99 -0
  260. data/source/global/tdclatl/FieldNames.h +66 -0
  261. data/source/global/tdclatl/Flags.cpp +75 -37
  262. data/source/global/tdclatl/Flags.h +13 -12
  263. data/source/global/tdclatl/GroupQuery.cpp +119 -0
  264. data/source/global/tdclatl/GroupQuery.h +65 -0
  265. data/source/global/tdclatl/KeyDef.cpp +15 -14
  266. data/source/global/tdclatl/KeyDef.h +20 -17
  267. data/source/global/tdclatl/KeySegment.cpp +13 -12
  268. data/source/global/tdclatl/PooledDbManager.cpp +223 -0
  269. data/source/global/tdclatl/PooledDbManager.h +76 -0
  270. data/source/global/tdclatl/QueryBase.cpp +206 -127
  271. data/source/global/tdclatl/QueryBase.h +55 -59
  272. data/source/global/tdclatl/Record.cpp +214 -0
  273. data/source/global/tdclatl/Record.h +96 -0
  274. data/source/global/tdclatl/Recordset.cpp +278 -0
  275. data/source/global/tdclatl/Recordset.h +83 -0
  276. data/source/global/tdclatl/RecordsetQuery.cpp +118 -0
  277. data/source/global/tdclatl/RecordsetQuery.h +126 -0
  278. data/source/global/tdclatl/Table.cpp +57 -60
  279. data/source/global/tdclatl/Table.h +32 -29
  280. data/source/global/tdclatl/TableDef.cpp +63 -62
  281. data/source/global/tdclatl/TableDef.h +20 -22
  282. data/source/global/tdclatl/TdVersion.cpp +3 -3
  283. data/source/global/tdclatl/TdVersion.h +15 -11
  284. data/source/global/tdclatl/_IDatabaseEvents_CP.h +99 -92
  285. data/source/global/tdclatl/activeTable.cpp +355 -0
  286. data/source/global/tdclatl/activeTable.h +79 -0
  287. data/source/global/tdclatl/dllmain.cpp +4 -3
  288. data/source/global/tdclatl/dllmain.h +7 -6
  289. data/source/global/tdclatl/keySegment.h +22 -18
  290. data/source/global/tdclatl/resource.h +0 -0
  291. data/source/global/tdclatl/stdafx.h +6 -4
  292. data/source/global/tdclatl/targetver.h +0 -1
  293. data/source/global/tdclatl/tdclatl.cpp +10 -5
  294. data/source/global/tdclatl/tdclatl.idl +530 -14
  295. data/source/linux/charsetConvert.h +78 -79
  296. data/source/linux/linuxTypes.h +9 -12
  297. data/source/linux/tchar.h +168 -166
  298. data/transactd.gemspec +24 -16
  299. metadata +98 -12
  300. data/bin/common/tdclc_32_1_2.dll +0 -0
  301. data/bin/common/tdclc_64_1_2.dll +0 -0
  302. data/build/tdclc/tdclc_32.cbproj +0 -173
  303. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +0 -232
  304. data/build/tdclrb/GEM_VERSION +0 -3
  305. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -43
  306. data/source/bzs/example/useORM.cpp +0 -585
@@ -1,489 +1,541 @@
1
- #ifndef BZS_NETSVC_CLINET_TCPCLIENT_H
2
- #define BZS_NETSVC_CLINET_TCPCLIENT_H
3
- /*=================================================================
4
- Copyright (C) 2012 2013 BizStation Corp All rights reserved.
5
-
6
- This program is free software; you can redistribute it and/or
7
- modify it under the terms of the GNU General Public License
8
- as published by the Free Software Foundation; either version 2
9
- of the License, or (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program; if not, write to the Free Software
18
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
- 02111-1307, USA.
20
- =================================================================*/
21
-
22
- #ifdef __BCPLUSPLUS__
23
- #pragma warn -8012
24
- #endif
25
- #include <boost/asio/buffer.hpp>
26
- #include <boost/asio/windows/stream_handle.hpp>
27
- #include <boost/asio/io_service.hpp>
28
- #include <boost/asio/windows/basic_handle.hpp>
29
- #include <boost/asio/ip/tcp.hpp>
30
- #include <boost/asio/read.hpp>
31
- #include <boost/asio/write.hpp>
32
- #include <boost/bind.hpp>
33
- #include <boost/asio/placeholders.hpp>
34
-
35
- #include <boost/system/system_error.hpp>
36
- #include <boost/thread/mutex.hpp>
37
- #include <stdio.h>
38
-
39
- #ifdef __BCPLUSPLUS__
40
- #pragma warn +8012
41
- #endif
42
- #include <vector>
43
- using namespace boost;
44
- using namespace boost::system;
45
-
46
- #ifdef WIN32
47
- #define USE_PIPE_CLIENT
48
- #endif
49
-
50
- #ifdef USE_PIPE_CLIENT
51
- using boost::asio::windows::stream_handle;
52
- typedef stream_handle platform_stream;
53
- typedef HANDLE platform_descriptor;
54
- #define PIPE_EOF_ERROR_CODE boost::system::windows_error::broken_pipe
55
- typedef DWORD thread_id;
56
- #define threadid GetCurrentThreadId
57
-
58
- #else
59
-
60
- typedef pthread_t thread_id;
61
- #define threadid pthread_self
62
- #endif
63
-
64
-
65
- #define READBUF_SIZE 66000
66
- #define WRITEBUF_SIZE 66000
67
-
68
-
69
-
70
- #define PORTNUMBUF_SIZE 10
71
- #define CLIENT_ERROR_CANT_CREATEPIPE 3106
72
- #define CLIENT_ERROR_SHAREMEM_DENIED 3104
73
-
74
- namespace bzs
75
- {
76
- namespace netsvc
77
- {
78
- namespace client
79
- {
80
-
81
- typedef std::vector<boost::asio::const_buffer> buffers;
82
-
83
- class connection;
84
-
85
- class connections
86
- {
87
- std::vector<connection*> m_conns;
88
- boost::asio::io_service m_ios;
89
- mutex m_mutex;
90
- connection* getConnection(asio::ip::tcp::endpoint& ep);
91
- asio::ip::tcp::endpoint endpoint(const std::string& host);
92
-
93
- bool isUseNamedPipe(asio::ip::tcp::endpoint& ep);
94
- static bool m_usePipedLocal;
95
- std::string m_pipeName;
96
- #ifdef USE_PIPE_CLIENT
97
- connection* getConnectionPipe();
98
- #endif
99
- public:
100
- connections(const char* pipeName);
101
- ~connections();
102
- connection* connect(const std::string& host, bool newConnection= false);
103
- connection* getConnection(const std::string& host);
104
-
105
- bool disconnect(connection* c);
106
- static char port[PORTNUMBUF_SIZE];
107
- int connectionCount();
108
- };
109
-
110
- /** The connection interface
111
- *
112
- */
113
- class connection
114
- {
115
- public:
116
- virtual ~connection(){};
117
- virtual void connect() = 0;
118
- virtual void addref() = 0;
119
- virtual void release() = 0;
120
- virtual int refCount() const = 0;
121
- virtual bool isConnected()const = 0;
122
- virtual const asio::ip::tcp::endpoint& endpoint() const = 0;
123
- virtual thread_id tid()const = 0;
124
- virtual char* sendBuffer()=0;
125
- virtual unsigned int sendBufferSize()=0;
126
- virtual buffers* optionalBuffers()=0;
127
- virtual char* asyncWriteRead(unsigned int writeSize)=0;
128
-
129
- };
130
-
131
- /** Implementation of Part of the connection interface
132
- */
133
- class connectionBase : public connection
134
- {
135
- protected:
136
- friend class connections;
137
- asio::io_service m_ios;
138
- asio::ip::tcp::endpoint m_ep;
139
- int m_refCount;
140
- thread_id m_tid;
141
- std::vector<char> m_readbuf;
142
- std::vector<char> m_sendbuf;
143
- size_t m_readLen;
144
- bool m_connected;
145
- void addref(){++m_refCount;}
146
- void release() {--m_refCount;}
147
- int refCount()const{return m_refCount;}
148
- bool isConnected()const{return m_connected;};
149
- const asio::ip::tcp::endpoint& endpoint()const{return m_ep;}
150
- thread_id tid()const{return m_tid;};
151
- public:
152
- connectionBase(asio::ip::tcp::endpoint& ep)
153
- :m_ep(ep),m_refCount(0),m_tid(threadid()),m_connected(false)
154
- {
155
-
156
- }
157
- char* sendBuffer(){return &m_sendbuf[0];};
158
- unsigned int sendBufferSize(){return (unsigned int)m_sendbuf.size();};
159
- };
160
-
161
- /** Implementation of the connection template
162
- */
163
- template <class T>
164
- class connectionImple : public connectionBase
165
- {
166
- protected:
167
- T m_socket;
168
- buffers m_optionalBuffes;
169
-
170
- void handle_read(const boost::system::error_code& e
171
- , std::size_t bytes_transferred)
172
- {
173
- if (!e)
174
- {
175
- unsigned int* n=NULL;
176
- if (bytes_transferred==0)
177
- return ;
178
- m_readLen += bytes_transferred;
179
- n = (unsigned int*)(&m_readbuf[0]);
180
- if (*n == m_readLen)
181
- return;
182
- else if (*n > m_readbuf.size())
183
- m_readbuf.resize(*n);
184
-
185
- m_socket.async_read_some(asio::buffer(&m_readbuf[m_readLen] ,m_readbuf.size()-m_readLen)
186
- ,boost::bind(&connectionImple::handle_read, this
187
- ,boost::asio::placeholders::error
188
- ,boost::asio::placeholders::bytes_transferred));
189
- }
190
-
191
- }
192
-
193
- void handle_write(const boost::system::error_code& e)
194
- {
195
- if (!e)
196
- {
197
- m_optionalBuffes.clear();
198
- m_readLen = 0;
199
- m_socket.async_read_some(asio::buffer(&m_readbuf[0], m_readbuf.size()),
200
- boost::bind(&connectionImple::handle_read, this,
201
- boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
202
- }
203
- }
204
-
205
- void read()
206
- {
207
- if (!m_connected)
208
- throw system_error(asio::error::not_connected);
209
- boost::system::error_code e;
210
- m_readLen = 0;
211
- m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&m_readbuf[m_readLen], m_readbuf.size()-m_readLen)
212
- ,boost::asio::transfer_at_least(4));
213
- unsigned int* n=NULL;
214
- n = (unsigned int*)(&m_readbuf[0]);
215
-
216
- if (*n > m_readbuf.size()) m_readbuf.resize(*n);
217
- if (m_readLen != *n)
218
- m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&m_readbuf[m_readLen], *n-m_readLen)
219
- , boost::asio::transfer_all());
220
- }
221
-
222
- void write(unsigned int writeSize)
223
- {
224
- if (!m_connected)
225
- throw system_error(asio::error::not_connected);
226
- m_optionalBuffes.insert(m_optionalBuffes.begin(), asio::buffer(sendBuffer(), writeSize));
227
- boost::asio::write(m_socket, m_optionalBuffes, boost::asio::transfer_all());
228
- m_optionalBuffes.clear();
229
-
230
- }
231
-
232
- public:
233
- connectionImple(asio::ip::tcp::endpoint& ep)
234
- :connectionBase(ep),m_socket(m_ios)
235
- {
236
-
237
- }
238
-
239
- ~connectionImple()
240
- {
241
- m_ios.stop();
242
- try
243
- {
244
- m_socket.close();
245
- }
246
- catch(...){}
247
-
248
- }
249
-
250
- char* asyncWriteRead(unsigned int writeSize)
251
- {
252
- write(writeSize);
253
- read();
254
-
255
- return &m_readbuf[0];
256
- }
257
-
258
- buffers* optionalBuffers(){return &m_optionalBuffes;};
259
-
260
- };
261
-
262
- #define TIMEOUT_SEC 3
263
- /** Implementation of The TCP connection.
264
- */
265
- class tcpConnection : public connectionImple<asio::ip::tcp::socket>
266
- {
267
-
268
- public:
269
- tcpConnection(asio::ip::tcp::endpoint& ep)
270
- :connectionImple<asio::ip::tcp::socket>(ep)
271
- {
272
- m_readbuf.resize(READBUF_SIZE);
273
- m_sendbuf.resize(WRITEBUF_SIZE);
274
-
275
- }
276
-
277
- void setupTimeouts()
278
- {
279
- #if defined _WIN32
280
- int32_t timeout = TIMEOUT_SEC*1000;
281
- setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
282
- setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
283
- #else
284
- struct timeval timeout;
285
- timeout.tv_usec = 0;
286
- timeout.tv_sec = TIMEOUT_SEC;
287
- setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
288
- setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
289
- #endif
290
- }
291
-
292
- void connect()
293
- {
294
- setupTimeouts();
295
- m_socket.connect(m_ep);
296
- m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
297
- char tmp[20];
298
- m_socket.read_some(boost::asio::buffer(tmp, 10));
299
- m_connected = true;
300
-
301
- }
302
- };
303
-
304
- class exception: public std::exception
305
- {
306
- int m_error;
307
- std::string m_msg;
308
-
309
- public:
310
-
311
- exception(int errorCode, const char* const &message)
312
- :std::exception(),m_error(errorCode),m_msg(message){}
313
- ~exception() throw(){};
314
- const char *what() const throw(){return m_msg.c_str();};
315
- int error(){return m_error;};
316
-
317
- };
318
-
319
- #ifdef USE_PIPE_CLIENT
320
- /** Implementation of The Named pipe connection.
321
- */
322
- class pipeConnection : public connectionImple<platform_stream>
323
- {
324
- const std::string& m_pipeName;
325
- char* m_readbuf_p;
326
- char* m_writebuf_p;
327
- unsigned int m_sendBufferSize;
328
-
329
- HANDLE m_recvEvent;
330
- HANDLE m_sendEvent;
331
- HANDLE m_mapFile;
332
- char* GetErrorMessage( DWORD ErrorCode)
333
- {
334
- LPVOID lpMsgBuf;
335
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
336
- NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
337
- (LPTSTR) &lpMsgBuf, 0, NULL);
338
- return (char*)lpMsgBuf;
339
- }
340
-
341
- void throwException(const char* msg, int errorCode)
342
- {
343
- char buf[4096];
344
- char user[128];
345
- char* p = GetErrorMessage(GetLastError());
346
- DWORD size = 128;
347
- GetUserName(user, &size);
348
- sprintf_s(buf, 4096, "User:%s %s %d %s",user, msg, GetLastError(), p);
349
- LocalFree(p);
350
- throw exception(errorCode, buf);
351
- }
352
-
353
- char* getUniqName(const char* name)
354
- {
355
-
356
- connectionBase::m_readbuf.resize(120);
357
- char* p = &connectionBase::m_readbuf[0];
358
- DWORD threadId = GetCurrentThreadId();
359
- __int64 clientid = (__int64)this;
360
- sprintf_s(p, 120, "%s_%u_%Lu", name, threadId, clientid);
361
- return p;
362
- }
363
-
364
- void createKernelObjects(unsigned int shareMemSize)
365
- {
366
- char tmp[50];
367
- SYSTEM_INFO SystemInfo;
368
- GetSystemInfo(&SystemInfo);
369
- int size = shareMemSize/SystemInfo.dwAllocationGranularity + 1;
370
- m_sendBufferSize = size*SystemInfo.dwAllocationGranularity;
371
-
372
- sprintf_s(tmp, 50, "Global\\%s", m_pipeName.c_str());
373
- m_mapFile = CreateFileMapping(INVALID_HANDLE_VALUE
374
- ,NULL, PAGE_READWRITE, 0,m_sendBufferSize*2, getUniqName(tmp));
375
- if (m_mapFile == NULL)
376
- throwException("CreateFileMapping", CLIENT_ERROR_SHAREMEM_DENIED);
377
-
378
- m_writebuf_p = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS
379
- , 0, 0, m_sendBufferSize);
380
- if (m_writebuf_p == NULL)
381
- throwException("MapViewOfFile R", CLIENT_ERROR_SHAREMEM_DENIED);
382
-
383
- m_readbuf_p = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS
384
- , 0, m_sendBufferSize, m_sendBufferSize);
385
- if (m_readbuf_p == NULL)
386
- throwException("MapViewOfFile W", CLIENT_ERROR_SHAREMEM_DENIED);
387
-
388
- sprintf_s(tmp, 50, "Global\\%sToClnt", m_pipeName.c_str());
389
- m_recvEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
390
- if (m_recvEvent==NULL)
391
- throwException("OpenEvent Client", CLIENT_ERROR_SHAREMEM_DENIED);
392
-
393
- sprintf_s(tmp, 50, "Global\\%sToSrv", m_pipeName.c_str());
394
- m_sendEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
395
- if (m_sendEvent==NULL)
396
- throwException("OpenEvent Server", CLIENT_ERROR_SHAREMEM_DENIED);
397
- }
398
-
399
- public:
400
-
401
- pipeConnection(asio::ip::tcp::endpoint& ep,const std::string& pipeName)
402
- :connectionImple<platform_stream>(ep)
403
- ,m_pipeName(pipeName)
404
- ,m_mapFile(NULL)
405
- ,m_recvEvent(NULL)
406
- ,m_sendEvent(NULL)
407
- ,m_writebuf_p(NULL)
408
- ,m_readbuf_p(NULL)
409
- ,m_sendBufferSize(0)
410
-
411
- {
412
-
413
- }
414
-
415
- ~pipeConnection()
416
- {
417
- memset(m_writebuf_p, 0, sizeof(unsigned int));
418
-
419
- SetEvent(m_sendEvent);
420
- WaitForSingleObject(m_recvEvent, INFINITE);
421
-
422
- if (m_recvEvent)
423
- CloseHandle(m_recvEvent);
424
- if (m_sendEvent)
425
- CloseHandle(m_sendEvent);
426
- if (m_writebuf_p)
427
- UnmapViewOfFile(m_writebuf_p);
428
- if (m_readbuf_p)
429
- UnmapViewOfFile(m_readbuf_p);
430
- if (m_mapFile)
431
- CloseHandle(m_mapFile);
432
- }
433
-
434
- void connect()
435
- {
436
- platform_descriptor fd;
437
- #ifdef WIN32
438
- char pipeName[100];
439
- sprintf_s(pipeName, 100, "\\\\.\\pipe\\%s", m_pipeName.c_str());
440
- int i=1000;
441
- while (--i)
442
- {
443
- fd = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE , 0, NULL
444
- , OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
445
- if (fd != INVALID_HANDLE_VALUE)
446
- break;
447
- if (ERROR_PIPE_BUSY != GetLastError())
448
- break;
449
- Sleep(1);
450
- }
451
- if (fd == INVALID_HANDLE_VALUE)
452
- throwException("CreateFile", CLIENT_ERROR_CANT_CREATEPIPE);
453
- #endif
454
- m_socket.assign(fd);
455
- m_connected = true;
456
-
457
- //send thredid;
458
- DWORD threadId = GetCurrentThreadId();
459
- int size = 16;
460
- connectionBase::m_readbuf.resize(size);
461
- char* p = &connectionBase::m_readbuf[0];
462
- memcpy(p, &size, sizeof(int));
463
- memcpy(p+4, &threadId, sizeof(DWORD));
464
- __int64 clientid = (__int64)this;
465
- memcpy(p+8, &clientid, sizeof(__int64));
466
- boost::asio::write(m_socket, boost::asio::buffer(p, size));
467
- boost::asio::read(m_socket, boost::asio::buffer(p, 7));
468
- unsigned int* shareMemSize = (unsigned int*)(p+3);
469
- createKernelObjects(*shareMemSize);
470
- }
471
-
472
- char* asyncWriteRead(unsigned int writeSize)
473
- {
474
- SetEvent(m_sendEvent);
475
- WaitForSingleObject(m_recvEvent, INFINITE);
476
- return m_readbuf_p;
477
- }
478
-
479
- char* sendBuffer(){return m_writebuf_p;}
480
- unsigned int sendBufferSize(){return m_sendBufferSize;};
481
- buffers* optionalBuffers(){return NULL;}; //not support
482
- };
483
- #endif
484
-
485
- }//namespace client
486
- }//namespace netsvc
487
- }//namespace bzs
488
-
489
- #endif//BZS_NETSVC_CLINET_TCPCLIENT_H
1
+ #ifndef BZS_NETSVC_CLINET_TCPCLIENT_H
2
+ #define BZS_NETSVC_CLINET_TCPCLIENT_H
3
+ /* =================================================================
4
+ Copyright (C) 2012 2013 BizStation Corp All rights reserved.
5
+
6
+ This program is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU General Public License
8
+ as published by the Free Software Foundation; either version 2
9
+ of the License, or (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program; if not, write to the Free Software
18
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
+ 02111-1307, USA.
20
+ ================================================================= */
21
+
22
+ #ifdef __BCPLUSPLUS__
23
+ #pragma warn -8012
24
+ #endif
25
+ #include <boost/asio/buffer.hpp>
26
+ #include <boost/asio/windows/stream_handle.hpp>
27
+ #include <boost/asio/io_service.hpp>
28
+ #include <boost/asio/windows/basic_handle.hpp>
29
+ #include <boost/asio/ip/tcp.hpp>
30
+ #include <boost/asio/read.hpp>
31
+ #include <boost/asio/write.hpp>
32
+ #include <boost/bind.hpp>
33
+ #include <boost/asio/placeholders.hpp>
34
+
35
+ #include <boost/system/system_error.hpp>
36
+ #include <boost/thread/mutex.hpp>
37
+ #include <stdio.h>
38
+
39
+ #ifdef __BCPLUSPLUS__
40
+ #pragma warn +8012
41
+ #endif
42
+ #include <vector>
43
+ using namespace boost;
44
+ using namespace boost::system;
45
+
46
+ #ifdef _WIN32
47
+ #define USE_PIPE_CLIENT
48
+ #endif
49
+
50
+ #ifdef USE_PIPE_CLIENT
51
+ using boost::asio::windows::stream_handle;
52
+ typedef stream_handle platform_stream;
53
+ typedef HANDLE platform_descriptor;
54
+ #define PIPE_EOF_ERROR_CODE boost::system::windows_error::broken_pipe
55
+ typedef DWORD thread_id;
56
+ #define threadid GetCurrentThreadId
57
+ #else // NOT USE_PIPE_CLIENT
58
+ typedef pthread_t thread_id;
59
+ #define threadid pthread_self
60
+ #endif // NOT USE_PIPE_CLIENT
61
+
62
+ #define READBUF_SIZE 66000
63
+ #define WRITEBUF_SIZE 66000
64
+
65
+ #define PORTNUMBUF_SIZE 10
66
+ #define CLIENT_ERROR_CANT_CREATEPIPE 3106
67
+ #define CLIENT_ERROR_SHAREMEM_DENIED 3104
68
+
69
+ namespace bzs
70
+ {
71
+ namespace netsvc
72
+ {
73
+ namespace client
74
+ {
75
+
76
+ typedef std::vector<boost::asio::const_buffer> buffers;
77
+
78
+ class connection;
79
+
80
+ class connections
81
+ {
82
+ std::vector<connection*> m_conns;
83
+ boost::asio::io_service m_ios;
84
+
85
+ mutex m_mutex;
86
+
87
+ connection* getConnection(asio::ip::tcp::endpoint& ep);
88
+ asio::ip::tcp::endpoint endpoint(const std::string& host,
89
+ boost::system::error_code& ec);
90
+
91
+ bool isUseNamedPipe(asio::ip::tcp::endpoint& ep);
92
+
93
+ static bool m_usePipedLocal;
94
+
95
+ std::string m_pipeName;
96
+ #ifdef USE_PIPE_CLIENT
97
+ connection* getConnectionPipe();
98
+ #endif
99
+
100
+ public:
101
+ connections(const char* pipeName);
102
+ ~connections();
103
+ connection* connect(const std::string& host, bool newConnection = false);
104
+ connection* getConnection(const std::string& host);
105
+
106
+ bool disconnect(connection* c);
107
+
108
+ static char port[PORTNUMBUF_SIZE];
109
+
110
+ int connectionCount();
111
+ };
112
+
113
+ /** The connection interface
114
+ *
115
+ */
116
+ class connection
117
+ {
118
+ public:
119
+ virtual ~connection(){};
120
+ virtual void connect() = 0;
121
+ virtual void addref() = 0;
122
+ virtual void release() = 0;
123
+ virtual int refCount() const = 0;
124
+ virtual bool isConnected() const = 0;
125
+ virtual const asio::ip::tcp::endpoint& endpoint() const = 0;
126
+ virtual thread_id tid() const = 0;
127
+ virtual char* sendBuffer(size_t size) = 0;
128
+ virtual unsigned int sendBufferSize() = 0;
129
+ virtual buffers* optionalBuffers() = 0;
130
+ virtual char* asyncWriteRead(unsigned int writeSize) = 0;
131
+ virtual unsigned int datalen() const = 0; // additinal info at segment read
132
+ virtual unsigned short rows() const = 0; // additinal info at segment read
133
+ virtual void setReadBufferSizeIf(size_t size) = 0;
134
+ };
135
+
136
+ /** Implementation of Part of the connection interface
137
+ */
138
+ class connectionBase : public connection
139
+ {
140
+ protected:
141
+ friend class connections;
142
+
143
+ asio::io_service m_ios;
144
+ asio::ip::tcp::endpoint m_ep;
145
+
146
+ int m_refCount;
147
+ thread_id m_tid;
148
+
149
+ std::vector<char> m_readbuf;
150
+ std::vector<char> m_sendbuf;
151
+
152
+ size_t m_readLen;
153
+ bool m_connected;
154
+
155
+ void addref() { ++m_refCount; }
156
+
157
+ void release() { --m_refCount; }
158
+
159
+ int refCount() const { return m_refCount; }
160
+
161
+ bool isConnected() const { return m_connected; };
162
+
163
+ const asio::ip::tcp::endpoint& endpoint() const { return m_ep; }
164
+
165
+ thread_id tid() const { return m_tid; };
166
+
167
+ public:
168
+ connectionBase(asio::ip::tcp::endpoint& ep)
169
+ : m_ep(ep), m_refCount(0), m_tid(threadid()), m_connected(false)
170
+ {
171
+ }
172
+
173
+ char* sendBuffer(size_t size)
174
+ {
175
+ if (size > m_sendbuf.size())
176
+ m_sendbuf.resize(size);
177
+ return &m_sendbuf[0];
178
+ };
179
+
180
+ unsigned int sendBufferSize() { return (unsigned int)m_sendbuf.size(); };
181
+
182
+ void setReadBufferSizeIf(size_t size)
183
+ {
184
+ if (m_readbuf.size() < size)
185
+ m_readbuf.resize(size);
186
+ }
187
+ };
188
+
189
+ /** Implementation of the connection template
190
+ */
191
+ template <class T> class connectionImple : public connectionBase
192
+ {
193
+ protected:
194
+ unsigned int m_datalen;
195
+ unsigned short m_rows;
196
+ T m_socket;
197
+ buffers m_optionalBuffes;
198
+
199
+ unsigned int datalen() const { return m_datalen; }
200
+
201
+ unsigned short rows() const { return m_rows; }
202
+
203
+ // server send any segment of lower than 0xFFFF data by asyncWrite
204
+ // last 4byte is 0xFFFFFFFF, that is specify end of data
205
+ void segmentRead()
206
+ {
207
+ bool end = false;
208
+ unsigned short n;
209
+ while (!end)
210
+ {
211
+ boost::asio::read(m_socket, boost::asio::buffer(&n, 2),
212
+ boost::asio::transfer_all());
213
+
214
+ if (m_readLen + n > m_readbuf.size())
215
+ m_readbuf.resize(m_readLen + n);
216
+
217
+ m_readLen += boost::asio::read(
218
+ m_socket, boost::asio::buffer(&m_readbuf[m_readLen], n),
219
+ boost::asio::transfer_all());
220
+
221
+ end = (*((unsigned int*)(&m_readbuf[m_readLen - 4])) == 0xFFFFFFFF);
222
+ }
223
+ m_readLen -= 4;
224
+ // additinal data length info
225
+ boost::asio::read(m_socket, boost::asio::buffer(&m_datalen, 4),
226
+ boost::asio::transfer_all());
227
+ boost::asio::read(m_socket, boost::asio::buffer(&m_rows, 2),
228
+ boost::asio::transfer_all());
229
+ }
230
+
231
+ void read()
232
+ {
233
+ if (!m_connected)
234
+ throw system_error(asio::error::not_connected);
235
+ boost::system::error_code e;
236
+ m_readLen = 0;
237
+ m_datalen = 0;
238
+ m_rows = 0;
239
+ unsigned int n;
240
+ m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&n, 4),
241
+ boost::asio::transfer_all());
242
+ if (n == 0xFFFFFFFF)
243
+ {
244
+ segmentRead();
245
+ m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&n, 4),
246
+ boost::asio::transfer_all());
247
+ }
248
+ if (n > m_readbuf.size())
249
+ m_readbuf.resize(n);
250
+ if (m_readLen != n)
251
+ m_readLen += boost::asio::read(
252
+ m_socket,
253
+ boost::asio::buffer(&m_readbuf[m_readLen], n - m_readLen),
254
+ boost::asio::transfer_all());
255
+ }
256
+
257
+ void write(unsigned int writeSize)
258
+ {
259
+ if (!m_connected)
260
+ throw system_error(asio::error::not_connected);
261
+ if (m_optionalBuffes.size())
262
+ {
263
+ m_optionalBuffes.insert(m_optionalBuffes.begin(),
264
+ asio::buffer(sendBuffer(0), writeSize));
265
+ boost::asio::write(m_socket, m_optionalBuffes,
266
+ boost::asio::transfer_all());
267
+ m_optionalBuffes.clear();
268
+ }
269
+ else
270
+ boost::asio::write(m_socket, asio::buffer(sendBuffer(0), writeSize),
271
+ boost::asio::transfer_all());
272
+ }
273
+
274
+ public:
275
+ connectionImple(asio::ip::tcp::endpoint& ep)
276
+ : connectionBase(ep), m_datalen(0), m_socket(m_ios)
277
+ {
278
+ }
279
+
280
+ ~connectionImple()
281
+ {
282
+ m_ios.stop();
283
+ try
284
+ {
285
+ m_socket.close();
286
+ }
287
+ catch (...)
288
+ {
289
+ }
290
+ }
291
+
292
+ char* asyncWriteRead(unsigned int writeSize)
293
+ {
294
+ write(writeSize);
295
+ read();
296
+ return &m_readbuf[0];
297
+ }
298
+
299
+ buffers* optionalBuffers() { return &m_optionalBuffes; }
300
+ };
301
+
302
+ #define TIMEOUT_SEC 3
303
+
304
+ /** Implementation of The TCP connection.
305
+ */
306
+ class tcpConnection : public connectionImple<asio::ip::tcp::socket>
307
+ {
308
+
309
+ public:
310
+ tcpConnection(asio::ip::tcp::endpoint& ep)
311
+ : connectionImple<asio::ip::tcp::socket>(ep)
312
+ {
313
+ m_readbuf.resize(READBUF_SIZE);
314
+ m_sendbuf.resize(WRITEBUF_SIZE);
315
+ }
316
+
317
+ void setupTimeouts()
318
+ {
319
+ #if defined _WIN32
320
+ int32_t timeout = TIMEOUT_SEC * 1000;
321
+ setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO,
322
+ (const char*)&timeout, sizeof(timeout));
323
+ setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO,
324
+ (const char*)&timeout, sizeof(timeout));
325
+ #else
326
+ struct timeval timeout;
327
+ timeout.tv_usec = 0;
328
+ timeout.tv_sec = TIMEOUT_SEC;
329
+ setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO, &timeout,
330
+ sizeof(timeout));
331
+ setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO, &timeout,
332
+ sizeof(timeout));
333
+ #endif
334
+ }
335
+
336
+ void connect()
337
+ {
338
+ setupTimeouts();
339
+ m_socket.connect(m_ep);
340
+ m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
341
+ char tmp[20];
342
+ m_socket.read_some(boost::asio::buffer(tmp, 10));
343
+ m_connected = true;
344
+ }
345
+ };
346
+
347
+ class exception : public std::exception
348
+ {
349
+ int m_error;
350
+
351
+ std::string m_msg;
352
+
353
+ public:
354
+ exception(int errorCode, const char* const& message)
355
+ : std::exception(), m_error(errorCode), m_msg(message)
356
+ {
357
+ }
358
+
359
+ ~exception() throw() {}
360
+
361
+ const char* what() const throw() { return m_msg.c_str(); }
362
+
363
+ int error() { return m_error; }
364
+ };
365
+
366
+ #ifdef USE_PIPE_CLIENT
367
+
368
+ /** Implementation of The Named pipe connection.
369
+ */
370
+ class pipeConnection : public connectionImple<platform_stream>
371
+ {
372
+ const std::string& m_pipeName;
373
+
374
+ char* m_readbuf_p;
375
+ char* m_writebuf_p;
376
+ unsigned int m_sendBufferSize;
377
+
378
+ HANDLE m_recvEvent;
379
+ HANDLE m_sendEvent;
380
+ HANDLE m_mapFile;
381
+
382
+ char* GetErrorMessage(DWORD ErrorCode)
383
+ {
384
+ LPVOID lpMsgBuf;
385
+ FormatMessage(
386
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
387
+ ErrorCode,
388
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
389
+ (LPTSTR)&lpMsgBuf, 0, NULL);
390
+ return (char*)lpMsgBuf;
391
+ }
392
+
393
+ void throwException(const char* msg, int errorCode)
394
+ {
395
+ char buf[4096];
396
+ char user[128];
397
+ char* p = GetErrorMessage(GetLastError());
398
+ DWORD size = 128;
399
+ GetUserName(user, &size);
400
+ sprintf_s(buf, 4096, "User:%s %s %d %s", user, msg, GetLastError(), p);
401
+ LocalFree(p);
402
+ throw exception(errorCode, buf);
403
+ }
404
+
405
+ char* getUniqName(const char* name)
406
+ {
407
+ connectionBase::m_readbuf.resize(120);
408
+ char* p = &connectionBase::m_readbuf[0];
409
+ DWORD processId = GetCurrentProcessId();
410
+ __int64 clientid = (__int64) this;
411
+ sprintf_s(p, 120, "%s_%u_%Lu", name, processId, clientid);
412
+ return p;
413
+ }
414
+
415
+ void createKernelObjects(unsigned int shareMemSize)
416
+ {
417
+ char tmp[50];
418
+ SYSTEM_INFO SystemInfo;
419
+ GetSystemInfo(&SystemInfo);
420
+ int size = shareMemSize / SystemInfo.dwAllocationGranularity + 1;
421
+ m_sendBufferSize = size * SystemInfo.dwAllocationGranularity;
422
+
423
+ sprintf_s(tmp, 50, "Global\\%s", m_pipeName.c_str());
424
+ m_mapFile =
425
+ CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
426
+ m_sendBufferSize * 2, getUniqName(tmp));
427
+ if (m_mapFile == NULL)
428
+ throwException("CreateFileMapping", CLIENT_ERROR_SHAREMEM_DENIED);
429
+
430
+ m_writebuf_p = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS, 0,
431
+ 0, m_sendBufferSize);
432
+ if (m_writebuf_p == NULL)
433
+ throwException("MapViewOfFile R", CLIENT_ERROR_SHAREMEM_DENIED);
434
+
435
+ m_readbuf_p = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS, 0,
436
+ m_sendBufferSize, m_sendBufferSize);
437
+ if (m_readbuf_p == NULL)
438
+ throwException("MapViewOfFile W", CLIENT_ERROR_SHAREMEM_DENIED);
439
+
440
+ sprintf_s(tmp, 50, "Global\\%sToClnt", m_pipeName.c_str());
441
+ m_recvEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
442
+ if (m_recvEvent == NULL)
443
+ throwException("OpenEvent Client", CLIENT_ERROR_SHAREMEM_DENIED);
444
+
445
+ sprintf_s(tmp, 50, "Global\\%sToSrv", m_pipeName.c_str());
446
+ m_sendEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
447
+ if (m_sendEvent == NULL)
448
+ throwException("OpenEvent Server", CLIENT_ERROR_SHAREMEM_DENIED);
449
+ }
450
+
451
+ public:
452
+ pipeConnection(asio::ip::tcp::endpoint& ep, const std::string& pipeName)
453
+ : connectionImple<platform_stream>(ep), m_pipeName(pipeName),
454
+ m_mapFile(NULL), m_recvEvent(NULL), m_sendEvent(NULL),
455
+ m_writebuf_p(NULL), m_readbuf_p(NULL), m_sendBufferSize(0)
456
+
457
+ {
458
+ }
459
+
460
+ ~pipeConnection()
461
+ {
462
+ memset(m_writebuf_p, 0, sizeof(unsigned int));
463
+
464
+ SetEvent(m_sendEvent);
465
+ WaitForSingleObject(m_recvEvent, INFINITE);
466
+
467
+ if (m_recvEvent)
468
+ CloseHandle(m_recvEvent);
469
+ if (m_sendEvent)
470
+ CloseHandle(m_sendEvent);
471
+ if (m_writebuf_p)
472
+ UnmapViewOfFile(m_writebuf_p);
473
+ if (m_readbuf_p)
474
+ UnmapViewOfFile(m_readbuf_p);
475
+ if (m_mapFile)
476
+ CloseHandle(m_mapFile);
477
+ }
478
+
479
+ void connect()
480
+ {
481
+ platform_descriptor fd;
482
+ #ifdef WIN32
483
+ char pipeName[100];
484
+ sprintf_s(pipeName, 100, "\\\\.\\pipe\\%s", m_pipeName.c_str());
485
+ int i = 1000;
486
+ while (--i)
487
+ {
488
+ fd = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
489
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
490
+ if (fd != INVALID_HANDLE_VALUE)
491
+ break;
492
+ if (ERROR_PIPE_BUSY != GetLastError())
493
+ break;
494
+ Sleep(1);
495
+ }
496
+ if (fd == INVALID_HANDLE_VALUE)
497
+ throwException("CreateFile", CLIENT_ERROR_CANT_CREATEPIPE);
498
+ #endif // NOT WIN32
499
+ m_socket.assign(fd);
500
+ m_connected = true;
501
+
502
+ // send processId;
503
+
504
+ DWORD processId = GetCurrentProcessId();
505
+ int size = 16;
506
+ connectionBase::m_readbuf.resize(size);
507
+ char* p = &connectionBase::m_readbuf[0];
508
+ memcpy(p, &size, sizeof(int));
509
+ memcpy(p + 4, &processId, sizeof(DWORD));
510
+ __int64 clientid = (__int64) this;
511
+ memcpy(p + 8, &clientid, sizeof(__int64));
512
+ boost::asio::write(m_socket, boost::asio::buffer(p, size));
513
+ boost::asio::read(m_socket, boost::asio::buffer(p, 7));
514
+ unsigned int* shareMemSize = (unsigned int*)(p + 3);
515
+ createKernelObjects(*shareMemSize);
516
+ }
517
+
518
+ char* asyncWriteRead(unsigned int writeSize)
519
+ {
520
+ m_datalen = 0;
521
+ m_rows = 0;
522
+ SetEvent(m_sendEvent);
523
+ WaitForSingleObject(m_recvEvent, INFINITE);
524
+ return m_readbuf_p;
525
+ }
526
+
527
+ char* sendBuffer(size_t size) { return m_writebuf_p; }
528
+
529
+ unsigned int sendBufferSize() { return m_sendBufferSize; }
530
+
531
+ buffers* optionalBuffers() { return NULL; } // not support
532
+
533
+ void setReadBufferSizeIf(size_t size) {} // not support
534
+ };
535
+ #endif // NOT WIN32
536
+
537
+ } // namespace client
538
+ } // namespace netsvc
539
+ } // namespace bzs
540
+
541
+ #endif // BZS_NETSVC_CLINET_TCPCLIENT_H