transactd 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. checksums.yaml +7 -0
  2. data/BUILD_UNIX-JA +174 -0
  3. data/BUILD_WIN-JA +256 -0
  4. data/CMakeLists.txt +96 -0
  5. data/COPYING +339 -0
  6. data/README +406 -0
  7. data/README-JA +424 -0
  8. data/bin/common/tdclc_32_1_0.dll +0 -0
  9. data/bin/common/tdclc_64_1_0.dll +0 -0
  10. data/build/common/check_for_link_iconv.cmake +73 -0
  11. data/build/common/copyifgreater.cmd +30 -0
  12. data/build/common/copyifgreater.js +290 -0
  13. data/build/common/get_boost_libs.cmake +106 -0
  14. data/build/common/get_ruby_path.cmake +115 -0
  15. data/build/common/options.cmake +127 -0
  16. data/build/common/smart_install.cmake +263 -0
  17. data/build/common/system.cmake +122 -0
  18. data/build/common/transactd.rc.in +52 -0
  19. data/build/common/transactd_cl_common.cmake +101 -0
  20. data/build/common/transactd_cl_output.cmake +93 -0
  21. data/build/common/transactd_common.cmake +237 -0
  22. data/build/common/transactd_required.cmake +28 -0
  23. data/build/swig/ruby/generate.cmake.in +35 -0
  24. data/build/swig/ruby/generate.cmd.in +19 -0
  25. data/build/swig/ruby/ruby.swg +101 -0
  26. data/build/swig/tdcl.i +188 -0
  27. data/build/tdclc/BUILDNUMBER.txt +1 -0
  28. data/build/tdclc/CMakeLists.txt +170 -0
  29. data/build/tdclc/tdclc_32.cbproj +181 -0
  30. data/build/tdclc/tdclc_64.cbproj +205 -0
  31. data/build/tdclcpp/BUILDNUMBER.txt +1 -0
  32. data/build/tdclcpp/CMakeLists.txt +142 -0
  33. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +239 -0
  34. data/build/tdclcpp/tdclcpp_bcb_64.cbproj +304 -0
  35. data/build/tdclrb/BUILDNUMBER.txt +1 -0
  36. data/build/tdclrb/CMakeLists.txt +258 -0
  37. data/build/tdclrb/GEM_VERSION +3 -0
  38. data/build/tdclrb/bldgem/extconf.rb +123 -0
  39. data/build/tdclrb/gem/INSTALLLOG.win32 +9 -0
  40. data/build/tdclrb/gem/Makefile.win32-VS +65 -0
  41. data/build/tdclrb/gem/Makefile.win32-prebuilt +48 -0
  42. data/build/tdclrb/gem/detect.rb +31 -0
  43. data/build/tdclrb/gem/helper.rb +113 -0
  44. data/build/tdclrb/gem/transactd.rb +22 -0
  45. data/build/tdclrb/gem_output.cmake +44 -0
  46. data/source/bzs/db/IBlobBuffer.h +51 -0
  47. data/source/bzs/db/blobBuffer.h +177 -0
  48. data/source/bzs/db/blobStructs.h +85 -0
  49. data/source/bzs/db/engine/mysql/IReadRecords.h +52 -0
  50. data/source/bzs/db/engine/mysql/bookmark.h +195 -0
  51. data/source/bzs/db/engine/mysql/database.cpp +1882 -0
  52. data/source/bzs/db/engine/mysql/database.h +465 -0
  53. data/source/bzs/db/engine/mysql/dbManager.cpp +303 -0
  54. data/source/bzs/db/engine/mysql/dbManager.h +143 -0
  55. data/source/bzs/db/engine/mysql/errorMessage.cpp +75 -0
  56. data/source/bzs/db/engine/mysql/errorMessage.h +43 -0
  57. data/source/bzs/db/engine/mysql/fieldAccess.h +158 -0
  58. data/source/bzs/db/engine/mysql/mydebuglog.cpp +349 -0
  59. data/source/bzs/db/engine/mysql/mydebuglog.h +89 -0
  60. data/source/bzs/db/engine/mysql/mysqlInternal.h +171 -0
  61. data/source/bzs/db/engine/mysql/mysqlThd.cpp +169 -0
  62. data/source/bzs/db/engine/mysql/mysqlThd.h +35 -0
  63. data/source/bzs/db/engine/mysql/percentageKey.h +260 -0
  64. data/source/bzs/db/protocol/ICommandExecuter.h +49 -0
  65. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +689 -0
  66. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +228 -0
  67. data/source/bzs/db/protocol/tdap/btrDate.cpp +437 -0
  68. data/source/bzs/db/protocol/tdap/btrDate.h +227 -0
  69. data/source/bzs/db/protocol/tdap/client/bulkInsert.h +127 -0
  70. data/source/bzs/db/protocol/tdap/client/client.cpp +106 -0
  71. data/source/bzs/db/protocol/tdap/client/client.h +292 -0
  72. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +144 -0
  73. data/source/bzs/db/protocol/tdap/client/connMgr.h +82 -0
  74. data/source/bzs/db/protocol/tdap/client/database.cpp +863 -0
  75. data/source/bzs/db/protocol/tdap/client/database.h +118 -0
  76. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +100 -0
  77. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +1640 -0
  78. data/source/bzs/db/protocol/tdap/client/dbDef.h +135 -0
  79. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +434 -0
  80. data/source/bzs/db/protocol/tdap/client/errorMessage.cpp +92 -0
  81. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +98 -0
  82. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +174 -0
  83. data/source/bzs/db/protocol/tdap/client/fieldDDF.h +91 -0
  84. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +140 -0
  85. data/source/bzs/db/protocol/tdap/client/fileDDF.h +86 -0
  86. data/source/bzs/db/protocol/tdap/client/filter.cpp +527 -0
  87. data/source/bzs/db/protocol/tdap/client/filter.h +154 -0
  88. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +137 -0
  89. data/source/bzs/db/protocol/tdap/client/indexDDF.h +84 -0
  90. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +724 -0
  91. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +123 -0
  92. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +899 -0
  93. data/source/bzs/db/protocol/tdap/client/nsTable.h +199 -0
  94. data/source/bzs/db/protocol/tdap/client/request.h +198 -0
  95. data/source/bzs/db/protocol/tdap/client/sharedData.cpp +58 -0
  96. data/source/bzs/db/protocol/tdap/client/sharedData.h +56 -0
  97. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +574 -0
  98. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +53 -0
  99. data/source/bzs/db/protocol/tdap/client/stringConverter.h +627 -0
  100. data/source/bzs/db/protocol/tdap/client/table.cpp +2613 -0
  101. data/source/bzs/db/protocol/tdap/client/table.h +221 -0
  102. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +1096 -0
  103. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +179 -0
  104. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +40 -0
  105. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +11 -0
  106. data/source/bzs/db/protocol/tdap/myDateTime.cpp +500 -0
  107. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +184 -0
  108. data/source/bzs/db/protocol/tdap/mysql/characterset.h +60 -0
  109. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +284 -0
  110. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +53 -0
  111. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +383 -0
  112. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +106 -0
  113. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +680 -0
  114. data/source/bzs/db/protocol/tdap/mysql/request.h +202 -0
  115. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +1020 -0
  116. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +141 -0
  117. data/source/bzs/db/protocol/tdap/tdapRequest.h +190 -0
  118. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +295 -0
  119. data/source/bzs/db/protocol/tdap/tdapSchema.h +558 -0
  120. data/source/bzs/db/protocol/tdap/tdapcapi.h +423 -0
  121. data/source/bzs/db/transactd/appBuilderImple.h +55 -0
  122. data/source/bzs/db/transactd/appModule.cpp +183 -0
  123. data/source/bzs/db/transactd/appModule.h +80 -0
  124. data/source/bzs/db/transactd/connManager.cpp +201 -0
  125. data/source/bzs/db/transactd/connManager.h +60 -0
  126. data/source/bzs/db/transactd/connectionRecord.h +69 -0
  127. data/source/bzs/db/transactd/transactd.cpp +325 -0
  128. data/source/bzs/env/compiler.h +135 -0
  129. data/source/bzs/env/crosscompile.cpp +130 -0
  130. data/source/bzs/env/crosscompile.h +150 -0
  131. data/source/bzs/env/fileopen.h +36 -0
  132. data/source/bzs/env/mbcswchrLinux.cpp +40 -0
  133. data/source/bzs/env/mbcswchrLinux.h +88 -0
  134. data/source/bzs/env/tstring.h +183 -0
  135. data/source/bzs/example/changeSchema.cpp +117 -0
  136. data/source/bzs/example/changeSchema_c.cpp +78 -0
  137. data/source/bzs/example/connection_pool_c.cpp +171 -0
  138. data/source/bzs/example/createDatabase.cpp +305 -0
  139. data/source/bzs/example/createDatabase_c.cpp +202 -0
  140. data/source/bzs/example/deleteRecords.cpp +87 -0
  141. data/source/bzs/example/deleteRecords_c.cpp +57 -0
  142. data/source/bzs/example/dropDatabase.cpp +59 -0
  143. data/source/bzs/example/dropDatabase_c.cpp +34 -0
  144. data/source/bzs/example/insertRecords.cpp +212 -0
  145. data/source/bzs/example/insertRecords_c.cpp +153 -0
  146. data/source/bzs/example/readRecords.cpp +141 -0
  147. data/source/bzs/example/readRecords_c.cpp +107 -0
  148. data/source/bzs/example/updateRecords.cpp +99 -0
  149. data/source/bzs/example/updateRecords_c.cpp +71 -0
  150. data/source/bzs/example/update_with_transaction.cpp +104 -0
  151. data/source/bzs/example/update_with_transaction_c.cpp +80 -0
  152. data/source/bzs/netsvc/client/tcpClient.cpp +226 -0
  153. data/source/bzs/netsvc/client/tcpClient.h +489 -0
  154. data/source/bzs/netsvc/server/IAppModule.h +94 -0
  155. data/source/bzs/netsvc/server/iserver.h +65 -0
  156. data/source/bzs/netsvc/server/serverCpt.cpp +522 -0
  157. data/source/bzs/netsvc/server/serverCpt.h +88 -0
  158. data/source/bzs/netsvc/server/serverPipe.cpp +705 -0
  159. data/source/bzs/netsvc/server/serverPipe.h +96 -0
  160. data/source/bzs/netsvc/server/serverTpool.cpp +416 -0
  161. data/source/bzs/netsvc/server/serverTpool.h +84 -0
  162. data/source/bzs/rtl/benchmark.cpp +96 -0
  163. data/source/bzs/rtl/benchmark.h +65 -0
  164. data/source/bzs/rtl/datetime.cpp +375 -0
  165. data/source/bzs/rtl/datetime.h +53 -0
  166. data/source/bzs/rtl/debuglog.cpp +106 -0
  167. data/source/bzs/rtl/debuglog.h +97 -0
  168. data/source/bzs/rtl/exception.h +116 -0
  169. data/source/bzs/rtl/stl_uty.cpp +35 -0
  170. data/source/bzs/rtl/stl_uty.h +29 -0
  171. data/source/bzs/rtl/stringBuffers.cpp +101 -0
  172. data/source/bzs/rtl/stringBuffers.h +58 -0
  173. data/source/bzs/rtl/strtrim.cpp +135 -0
  174. data/source/bzs/rtl/strtrim.h +46 -0
  175. data/source/bzs/test/tdclatl/bench_tdclatl.js +445 -0
  176. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +375 -0
  177. data/source/bzs/test/tdclrb/prepare.rb +226 -0
  178. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +172 -0
  179. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +208 -0
  180. data/source/bzs/test/tdclrb/transactd_spec.rb +1536 -0
  181. data/source/bzs/test/transactdBench/transactdBench.cpp +430 -0
  182. data/source/bzs/test/transactdBench/transactdBench2.cpp +342 -0
  183. data/source/bzs/test/trdclengn/test_trdclengn.cpp +2030 -0
  184. data/source/global/tdclatl/Database.cpp +503 -0
  185. data/source/global/tdclatl/Database.h +139 -0
  186. data/source/global/tdclatl/DbDef.cpp +242 -0
  187. data/source/global/tdclatl/DbDef.h +79 -0
  188. data/source/global/tdclatl/Field.cpp +92 -0
  189. data/source/global/tdclatl/Field.h +59 -0
  190. data/source/global/tdclatl/FieldDef.cpp +238 -0
  191. data/source/global/tdclatl/FieldDef.h +87 -0
  192. data/source/global/tdclatl/Flags.cpp +111 -0
  193. data/source/global/tdclatl/Flags.h +55 -0
  194. data/source/global/tdclatl/KeyDef.cpp +51 -0
  195. data/source/global/tdclatl/KeyDef.h +55 -0
  196. data/source/global/tdclatl/KeySegment.cpp +55 -0
  197. data/source/global/tdclatl/Table.cpp +600 -0
  198. data/source/global/tdclatl/Table.h +144 -0
  199. data/source/global/tdclatl/TableDef.cpp +291 -0
  200. data/source/global/tdclatl/TableDef.h +86 -0
  201. data/source/global/tdclatl/TdVersion.cpp +74 -0
  202. data/source/global/tdclatl/TdVersion.h +54 -0
  203. data/source/global/tdclatl/_IDatabaseEvents_CP.h +113 -0
  204. data/source/global/tdclatl/dllmain.cpp +30 -0
  205. data/source/global/tdclatl/dllmain.h +27 -0
  206. data/source/global/tdclatl/keySegment.h +57 -0
  207. data/source/global/tdclatl/resource.h +0 -0
  208. data/source/global/tdclatl/stdafx.cpp +2 -0
  209. data/source/global/tdclatl/stdafx.h +25 -0
  210. data/source/global/tdclatl/targetver.h +4 -0
  211. data/source/global/tdclatl/tdclatl.cpp +68 -0
  212. data/source/global/tdclatl/tdclatl.def +10 -0
  213. data/source/global/tdclatl/tdclatl.idl +1035 -0
  214. data/source/linux/charsetConvert.h +112 -0
  215. data/source/linux/linuxTypes.h +33 -0
  216. data/source/linux/tchar.h +428 -0
  217. data/transactd.gemspec +97 -0
  218. metadata +267 -0
@@ -0,0 +1,226 @@
1
+ /*=================================================================
2
+ Copyright (C) 2012 2013 BizStation Corp All rights reserved.
3
+
4
+ This program is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU General Public License
6
+ as published by the Free Software Foundation; either version 2
7
+ of the License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program; if not, write to the Free Software
16
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
+ 02111-1307, USA.
18
+ =================================================================*/
19
+
20
+ #include "tcpClient.h"
21
+ #include <bzs/env/crosscompile.h>
22
+ #ifndef _WIN32
23
+ #include <boost/property_tree/ptree.hpp>
24
+ #include <boost/property_tree/ini_parser.hpp>
25
+ #include <boost/filesystem.hpp>
26
+ #endif
27
+
28
+ using namespace boost;
29
+ using namespace boost::asio;
30
+ using namespace boost::asio::ip;
31
+
32
+ // ---------------------------------------------------------------------------
33
+ #ifdef __BCPLUSPLUS__
34
+ #pragma package(smart_init)
35
+ #endif
36
+
37
+
38
+
39
+ namespace bzs
40
+ {
41
+ namespace netsvc
42
+ {
43
+ namespace client
44
+ {
45
+
46
+ char connections::port[PORTNUMBUF_SIZE] = {"8610"};
47
+ bool connections::m_usePipedLocal = true;
48
+
49
+ connections::connections(const char* pipeName):m_pipeName(pipeName)
50
+ {
51
+ #ifdef _WIN32
52
+ DWORD len = MAX_PATH;
53
+ char buf[MAX_PATH];
54
+ if (GetWindowsDirectory(buf, len))
55
+ {
56
+ strcat_s(buf, MAX_PATH, "\\transactd.ini");
57
+ char tmp[30];
58
+ GetPrivateProfileString("transctd_client","use_piped_local", "1"
59
+ , tmp, 30, buf);
60
+ m_usePipedLocal = (atol(tmp)!=0);
61
+ GetPrivateProfileString("transctd_client","port", "8610"
62
+ , tmp, 30, buf);
63
+ strcpy_s(port, PORTNUMBUF_SIZE, tmp);
64
+
65
+ }
66
+ #else
67
+ namespace fs = boost::filesystem;
68
+ const fs::path path("/etc/transactd.cnf");
69
+ boost::system::error_code error;
70
+ const bool result = fs::exists(path, error);
71
+ if (result && !error)
72
+ {
73
+ boost::property_tree::ptree pt;
74
+ try
75
+ {
76
+ boost::property_tree::ini_parser::read_ini("/etc/transactd.cnf", pt);
77
+ std::string p = pt.get<std::string>("transctd_client.port");
78
+ if (p == "")
79
+ p = "8610";
80
+ strcpy_s(port, PORTNUMBUF_SIZE, p.c_str());
81
+ }
82
+ catch(...){}
83
+ }
84
+ #endif
85
+
86
+ }
87
+
88
+ /** Use by procces detach
89
+ *
90
+ */
91
+ connections::~connections()
92
+ {
93
+ for (int i=0;i<(int)m_conns.size();i++)
94
+ {
95
+ if (m_conns[i])
96
+ delete m_conns[i];
97
+
98
+ }
99
+ }
100
+
101
+ /** When threads differ, it have to make a different connection.
102
+ */
103
+ connection* connections::getConnection(asio::ip::tcp::endpoint& ep)
104
+ {
105
+ thread_id tid = threadid();
106
+ for (int i=0;i<(int)m_conns.size();i++)
107
+ {
108
+ if ((m_conns[i]->endpoint()==ep) && (m_conns[i]->tid()==tid))
109
+ return m_conns[i];
110
+ }
111
+ return NULL;
112
+ }
113
+
114
+ asio::ip::tcp::endpoint connections::endpoint(const std::string& host)
115
+ {
116
+ asio::ip::tcp::resolver resolver(m_ios);
117
+ asio::ip::tcp::resolver::query query(host, port);
118
+
119
+ boost::asio::ip::tcp::resolver::iterator dest = resolver.resolve(query);
120
+ asio::ip::tcp::endpoint endpoint;
121
+ while (dest != boost::asio::ip::tcp::resolver::iterator())
122
+ endpoint = *dest++;
123
+ return endpoint;
124
+ }
125
+
126
+ connection* connections::getConnection(const std::string& host)
127
+ {
128
+ mutex::scoped_lock lck(m_mutex);
129
+ asio::ip::tcp::endpoint ep = endpoint(host);
130
+ return getConnection(ep);
131
+ }
132
+
133
+ #ifdef USE_PIPE_CLIENT
134
+ connection* connections::getConnectionPipe()
135
+ {
136
+
137
+ thread_id tid = threadid();
138
+ for (int i=0;i<(int)m_conns.size();i++)
139
+ {
140
+ pipeConnection* pc = dynamic_cast<pipeConnection*>(m_conns[i]);
141
+ if (pc && (pc->tid()==tid))
142
+ return pc;
143
+ }
144
+ return NULL;
145
+ }
146
+ #endif
147
+
148
+ bool connections::disconnect(connection* c)
149
+ {
150
+ if (!c) return false;
151
+ mutex::scoped_lock lck(m_mutex);
152
+ c->release();
153
+ if (c->refCount()==0)
154
+ {
155
+ for (int i = (int)m_conns.size()-1;i>=0;--i)
156
+ {
157
+ if (c == m_conns[i])
158
+ {
159
+ m_conns.erase(m_conns.begin()+i);
160
+ break;
161
+ }
162
+ }
163
+ delete c;
164
+ }
165
+ return true;
166
+ }
167
+
168
+ /** If ep is local then isUseNamedPipe is true
169
+ */
170
+ bool connections::isUseNamedPipe(asio::ip::tcp::endpoint& ep)
171
+ {
172
+ asio::ip::tcp::endpoint local = endpoint("127.0.0.1");
173
+ if (local == ep)
174
+ return true;
175
+ char buf[MAX_PATH];
176
+ if (::gethostname(buf, MAX_PATH)==0)
177
+ {
178
+ local = endpoint(buf);
179
+ if (local == ep)
180
+ return true;
181
+ }
182
+ return false;
183
+ }
184
+
185
+ //The connection of found from connection list of same address is returned.
186
+ connection* connections::connect(const std::string& host, bool newConnection)
187
+ {
188
+ mutex::scoped_lock lck(m_mutex);
189
+ connection* c;
190
+ asio::ip::tcp::endpoint ep = endpoint(host);
191
+ #ifdef USE_PIPE_CLIENT
192
+ if (m_usePipedLocal && isUseNamedPipe(ep))
193
+ {
194
+ c = newConnection ? NULL: getConnectionPipe();
195
+ if(!c)
196
+ {
197
+ c = new pipeConnection(ep, m_pipeName);
198
+ c->connect();
199
+ m_conns.push_back(c);
200
+ }
201
+ }else
202
+ #endif
203
+ {
204
+
205
+ c = newConnection ? NULL: getConnection(ep);
206
+ if(!c)
207
+ {
208
+ c = new tcpConnection(ep);
209
+ c->connect();
210
+ m_conns.push_back(c);
211
+ }
212
+ }
213
+ c->addref();
214
+ return c;
215
+ }
216
+
217
+ int connections::connectionCount()
218
+ {
219
+
220
+ return (int)m_conns.size();
221
+ };
222
+
223
+ }//namespace client
224
+ }//namespace netsvc
225
+ }//namespace bzs
226
+
@@ -0,0 +1,489 @@
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