vincentchu-handlersocket 0.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.
- data/ext/HandlerSocket-Plugin-for-MySQL/AUTHORS +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/COPYING +30 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/ChangeLog +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/Makefile.am +87 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/README +78 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/autogen.sh +117 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/Makefile.am +24 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp +1041 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl +224 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.cpp +1532 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.pl +228 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs.sh +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs_more50.sh +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_md.sh +7 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my.sh +3 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my_more50.sh +3 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/configure.ac +144 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/about-handlersocket.en.txt +72 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/configuration-options.en.txt +99 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/installation.en.txt +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/perl-client.en.txt +135 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/protocol.en.txt +205 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/about-handlersocket.ja.txt +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/installation.ja.txt +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/perl-client.ja.txt +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/protocol.ja.txt +180 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.am +10 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.plain.template +31 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.cpp +1190 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.hpp +142 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.cpp +222 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.spec.template +29 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.cpp +149 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.hpp +58 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.cpp +951 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.hpp +35 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/mysql_incl.hpp +50 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.am +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.plain +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/allocator.hpp +64 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_addrinfo.hpp +49 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_file.hpp +64 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_ptrcontainer.hpp +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.cpp +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.hpp +32 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.cpp +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.hpp +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.cpp +36 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.hpp +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.cpp +441 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.hpp +62 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/libhsclient.spec.template +39 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/mutex.hpp +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.cpp +186 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.hpp +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_buffer.hpp +118 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_ref.hpp +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.cpp +182 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.hpp +53 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/thread.hpp +84 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/util.hpp +25 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-hs.log +130 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-my.log +125 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Changes +6 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/HandlerSocket.xs +632 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/MANIFEST +8 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL +18 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL.installed +20 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/README +30 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm +68 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm +362 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/ppport.h +6375 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/t/Net-HandlerSocket.t +15 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/Makefile +79 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/binary_my.cnf +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/compat.sh +29 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/hstest.pm +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/Makefile +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/run.sh +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.expected +100 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.pl +38 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.expected +100 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.pl +49 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.pl +61 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.expected +0 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.pl +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.pl +59 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.expected +644 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.pl +90 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.expected +304 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.pl +98 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.expected +2 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.pl +48 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.expected +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.pl +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.pl +93 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.expected +37 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.pl +112 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.expected +273 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.pl +134 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.expected +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.pl +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.expected +144 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.pl +80 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.expected +764 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.pl +114 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.expected +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.pl +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.expected +0 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.pl +125 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.expected +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.pl +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.expected +14894 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.pl +190 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.expected +2 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.pl +33 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.expected +11 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.pl +58 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.expected +9 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.pl +61 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.expected +101 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.pl +53 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/README +33 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/extconf.rb +27 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.cpp +437 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.h +32 -0
- metadata +200 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef DENA_CONFIG_HPP
|
|
10
|
+
#define DENA_CONFIG_HPP
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <map>
|
|
14
|
+
|
|
15
|
+
#define DENA_VERBOSE(lv, x) if (dena::verbose_level >= (lv)) { (x); }
|
|
16
|
+
|
|
17
|
+
namespace dena {
|
|
18
|
+
|
|
19
|
+
struct config : public std::map<std::string, std::string> {
|
|
20
|
+
std::string get_str(const std::string& key, const std::string& def = "")
|
|
21
|
+
const;
|
|
22
|
+
long long get_int(const std::string& key, long long def = 0) const;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
void parse_args(int argc, char **argv, config& conf);
|
|
26
|
+
|
|
27
|
+
extern unsigned int verbose_level;
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
#endif
|
|
32
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
|
|
11
|
+
#include "escape.hpp"
|
|
12
|
+
#include "string_buffer.hpp"
|
|
13
|
+
#include "fatal.hpp"
|
|
14
|
+
#include "string_util.hpp"
|
|
15
|
+
|
|
16
|
+
#define DBG_OP(x)
|
|
17
|
+
#define DBG_BUF(x)
|
|
18
|
+
|
|
19
|
+
namespace dena {
|
|
20
|
+
|
|
21
|
+
enum special_char_t {
|
|
22
|
+
special_char_escape_prefix = 0x01, /* SOH */
|
|
23
|
+
special_char_noescape_min = 0x10, /* DLE */
|
|
24
|
+
special_char_escape_shift = 0x40, /* '@' */
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
void
|
|
28
|
+
escape_string(char *& wp, const char *start, const char *finish)
|
|
29
|
+
{
|
|
30
|
+
while (start != finish) {
|
|
31
|
+
const unsigned char c = *start;
|
|
32
|
+
if (c >= special_char_noescape_min) {
|
|
33
|
+
wp[0] = c; /* no need to escape */
|
|
34
|
+
} else {
|
|
35
|
+
wp[0] = special_char_escape_prefix;
|
|
36
|
+
++wp;
|
|
37
|
+
wp[0] = c + special_char_escape_shift;
|
|
38
|
+
}
|
|
39
|
+
++start;
|
|
40
|
+
++wp;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void
|
|
45
|
+
escape_string(string_buffer& ar, const char *start, const char *finish)
|
|
46
|
+
{
|
|
47
|
+
const size_t buflen = (finish - start) * 2;
|
|
48
|
+
char *const wp_begin = ar.make_space(buflen);
|
|
49
|
+
char *wp = wp_begin;
|
|
50
|
+
escape_string(wp, start, finish);
|
|
51
|
+
ar.space_wrote(wp - wp_begin);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
bool
|
|
55
|
+
unescape_string(char *& wp, const char *start, const char *finish)
|
|
56
|
+
{
|
|
57
|
+
/* works even if wp == start */
|
|
58
|
+
while (start != finish) {
|
|
59
|
+
const unsigned char c = *start;
|
|
60
|
+
if (c != special_char_escape_prefix) {
|
|
61
|
+
wp[0] = c;
|
|
62
|
+
} else if (start + 1 != finish) {
|
|
63
|
+
++start;
|
|
64
|
+
const unsigned char cn = *start;
|
|
65
|
+
if (cn < special_char_escape_shift) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
wp[0] = cn - special_char_escape_shift;
|
|
69
|
+
} else {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
++start;
|
|
73
|
+
++wp;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
bool
|
|
79
|
+
unescape_string(string_buffer& ar, const char *start, const char *finish)
|
|
80
|
+
{
|
|
81
|
+
const size_t buflen = finish - start;
|
|
82
|
+
char *const wp_begin = ar.make_space(buflen);
|
|
83
|
+
char *wp = wp_begin;
|
|
84
|
+
const bool r = unescape_string(wp, start, finish);
|
|
85
|
+
ar.space_wrote(wp - wp_begin);
|
|
86
|
+
return r;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
uint32_t
|
|
90
|
+
read_ui32(char *& start, char *finish)
|
|
91
|
+
{
|
|
92
|
+
char *const n_begin = start;
|
|
93
|
+
read_token(start, finish);
|
|
94
|
+
char *const n_end = start;
|
|
95
|
+
uint32_t v = 0;
|
|
96
|
+
for (char *p = n_begin; p != n_end; ++p) {
|
|
97
|
+
const char ch = p[0];
|
|
98
|
+
if (ch >= '0' && ch <= '9') {
|
|
99
|
+
v *= 10;
|
|
100
|
+
v += (ch - '0');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return v;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
void
|
|
107
|
+
write_ui32(string_buffer& buf, uint32_t v)
|
|
108
|
+
{
|
|
109
|
+
char *wp = buf.make_space(12);
|
|
110
|
+
int len = snprintf(wp, 12, "%u", v);
|
|
111
|
+
if (len > 0) {
|
|
112
|
+
buf.space_wrote(len);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void
|
|
117
|
+
write_ui64(string_buffer& buf, uint64_t v)
|
|
118
|
+
{
|
|
119
|
+
char *wp = buf.make_space(22);
|
|
120
|
+
int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v));
|
|
121
|
+
if (len > 0) {
|
|
122
|
+
buf.space_wrote(len);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
};
|
|
127
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
#include "string_buffer.hpp"
|
|
12
|
+
#include "string_ref.hpp"
|
|
13
|
+
#include "string_util.hpp"
|
|
14
|
+
|
|
15
|
+
#ifndef DENA_ESCAPE_HPP
|
|
16
|
+
#define DENA_ESCAPE_HPP
|
|
17
|
+
|
|
18
|
+
namespace dena {
|
|
19
|
+
|
|
20
|
+
void escape_string(char *& wp, const char *start, const char *finish);
|
|
21
|
+
void escape_string(string_buffer& ar, const char *start, const char *finish);
|
|
22
|
+
bool unescape_string(char *& wp, const char *start, const char *finish);
|
|
23
|
+
/* unescaped_string() works even if wp == start */
|
|
24
|
+
bool unescape_string(string_buffer& ar, const char *start, const char *finish);
|
|
25
|
+
|
|
26
|
+
uint32_t read_ui32(char *& start, char *finish);
|
|
27
|
+
void write_ui32(string_buffer& buf, uint32_t v);
|
|
28
|
+
void write_ui64(string_buffer& buf, uint64_t v);
|
|
29
|
+
|
|
30
|
+
inline bool
|
|
31
|
+
is_null_expression(const char *start, const char *finish)
|
|
32
|
+
{
|
|
33
|
+
return (finish == start + 1 && start[0] == 0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
inline void
|
|
37
|
+
read_token(char *& start, char *finish)
|
|
38
|
+
{
|
|
39
|
+
char *const p = memchr_char(start, '\t', finish - start);
|
|
40
|
+
if (p == 0) {
|
|
41
|
+
start = finish;
|
|
42
|
+
} else {
|
|
43
|
+
start = p;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
inline void
|
|
48
|
+
skip_token_delim_fold(char *& start, char *finish)
|
|
49
|
+
{
|
|
50
|
+
while (start != finish && start[0] == '\t') {
|
|
51
|
+
++start;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
inline void
|
|
56
|
+
skip_one(char *& start, char *finish)
|
|
57
|
+
{
|
|
58
|
+
if (start != finish) {
|
|
59
|
+
++start;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
#endif
|
|
66
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <syslog.h>
|
|
12
|
+
|
|
13
|
+
#include "fatal.hpp"
|
|
14
|
+
|
|
15
|
+
namespace dena {
|
|
16
|
+
|
|
17
|
+
const int opt_syslog = LOG_ERR | LOG_PID | LOG_CONS;
|
|
18
|
+
|
|
19
|
+
void
|
|
20
|
+
fatal_exit(const std::string& message)
|
|
21
|
+
{
|
|
22
|
+
fprintf(stderr, "FATAL_EXIT: %s\n", message.c_str());
|
|
23
|
+
syslog(opt_syslog, "FATAL_EXIT: %s", message.c_str());
|
|
24
|
+
_exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
void
|
|
28
|
+
fatal_abort(const std::string& message)
|
|
29
|
+
{
|
|
30
|
+
fprintf(stderr, "FATAL_COREDUMP: %s\n", message.c_str());
|
|
31
|
+
syslog(opt_syslog, "FATAL_COREDUMP: %s", message.c_str());
|
|
32
|
+
abort();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
};
|
|
36
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef DENA_FATAL_HPP
|
|
10
|
+
#define DENA_FATAL_HPP
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
|
|
14
|
+
namespace dena {
|
|
15
|
+
|
|
16
|
+
void fatal_exit(const std::string& message);
|
|
17
|
+
void fatal_abort(const std::string& message);
|
|
18
|
+
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
#endif
|
|
22
|
+
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
|
|
2
|
+
// vim:sw=2:ai
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
|
|
6
|
+
* See COPYRIGHT.txt for details.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdexcept>
|
|
10
|
+
|
|
11
|
+
#include "hstcpcli.hpp"
|
|
12
|
+
#include "auto_file.hpp"
|
|
13
|
+
#include "string_util.hpp"
|
|
14
|
+
#include "auto_addrinfo.hpp"
|
|
15
|
+
#include "escape.hpp"
|
|
16
|
+
#include "util.hpp"
|
|
17
|
+
|
|
18
|
+
/* TODO */
|
|
19
|
+
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(MSG_NOSIGNAL)
|
|
20
|
+
#define MSG_NOSIGNAL 0
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
#define DBG(x)
|
|
24
|
+
|
|
25
|
+
namespace dena {
|
|
26
|
+
|
|
27
|
+
struct hstcpcli : public hstcpcli_i, private noncopyable {
|
|
28
|
+
hstcpcli(const socket_args& args);
|
|
29
|
+
virtual void close();
|
|
30
|
+
virtual int reconnect();
|
|
31
|
+
virtual bool stable_point();
|
|
32
|
+
virtual void request_buf_open_index(size_t pst_id, const char *dbn,
|
|
33
|
+
const char *tbl, const char *idx, const char *retflds, const char *filflds);
|
|
34
|
+
virtual void request_buf_auth(const char *secret, const char *typ);
|
|
35
|
+
virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
|
|
36
|
+
const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
|
|
37
|
+
const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
|
|
38
|
+
const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
|
|
39
|
+
const string_ref *invalues, size_t invalueslen);
|
|
40
|
+
virtual int request_send();
|
|
41
|
+
virtual int response_recv(size_t& num_flds_r);
|
|
42
|
+
virtual const string_ref *get_next_row();
|
|
43
|
+
virtual void response_buf_remove();
|
|
44
|
+
virtual int get_error_code();
|
|
45
|
+
virtual std::string get_error();
|
|
46
|
+
private:
|
|
47
|
+
int read_more();
|
|
48
|
+
void clear_error();
|
|
49
|
+
int set_error(int code, const std::string& str);
|
|
50
|
+
private:
|
|
51
|
+
auto_file fd;
|
|
52
|
+
socket_args sargs;
|
|
53
|
+
string_buffer readbuf;
|
|
54
|
+
string_buffer writebuf;
|
|
55
|
+
size_t response_end_offset; /* incl newline */
|
|
56
|
+
size_t cur_row_offset;
|
|
57
|
+
size_t num_flds;
|
|
58
|
+
size_t num_req_bufd; /* buffered but not yet sent */
|
|
59
|
+
size_t num_req_sent; /* sent but not yet received */
|
|
60
|
+
size_t num_req_rcvd; /* received but not yet removed */
|
|
61
|
+
int error_code;
|
|
62
|
+
std::string error_str;
|
|
63
|
+
std::vector<string_ref> flds;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
hstcpcli::hstcpcli(const socket_args& args)
|
|
67
|
+
: sargs(args), response_end_offset(0), cur_row_offset(0), num_flds(0),
|
|
68
|
+
num_req_bufd(0), num_req_sent(0), num_req_rcvd(0), error_code(0)
|
|
69
|
+
{
|
|
70
|
+
std::string err;
|
|
71
|
+
if (socket_connect(fd, sargs, err) != 0) {
|
|
72
|
+
set_error(-1, err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void
|
|
77
|
+
hstcpcli::close()
|
|
78
|
+
{
|
|
79
|
+
fd.close();
|
|
80
|
+
readbuf.clear();
|
|
81
|
+
writebuf.clear();
|
|
82
|
+
flds.clear();
|
|
83
|
+
response_end_offset = 0;
|
|
84
|
+
cur_row_offset = 0;
|
|
85
|
+
num_flds = 0;
|
|
86
|
+
num_req_bufd = 0;
|
|
87
|
+
num_req_sent = 0;
|
|
88
|
+
num_req_rcvd = 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int
|
|
92
|
+
hstcpcli::reconnect()
|
|
93
|
+
{
|
|
94
|
+
clear_error();
|
|
95
|
+
close();
|
|
96
|
+
std::string err;
|
|
97
|
+
if (socket_connect(fd, sargs, err) != 0) {
|
|
98
|
+
set_error(-1, err);
|
|
99
|
+
}
|
|
100
|
+
return error_code;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
bool
|
|
104
|
+
hstcpcli::stable_point()
|
|
105
|
+
{
|
|
106
|
+
/* returns true if cli can send a new request */
|
|
107
|
+
return fd.get() >= 0 && num_req_bufd == 0 && num_req_sent == 0 &&
|
|
108
|
+
num_req_rcvd == 0 && response_end_offset == 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
int
|
|
112
|
+
hstcpcli::get_error_code()
|
|
113
|
+
{
|
|
114
|
+
return error_code;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
std::string
|
|
118
|
+
hstcpcli::get_error()
|
|
119
|
+
{
|
|
120
|
+
return error_str;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
int
|
|
124
|
+
hstcpcli::read_more()
|
|
125
|
+
{
|
|
126
|
+
const size_t block_size = 4096; // FIXME
|
|
127
|
+
char *const wp = readbuf.make_space(block_size);
|
|
128
|
+
const ssize_t rlen = read(fd.get(), wp, block_size);
|
|
129
|
+
if (rlen <= 0) {
|
|
130
|
+
if (rlen < 0) {
|
|
131
|
+
error_str = "read: failed";
|
|
132
|
+
} else {
|
|
133
|
+
error_str = "read: eof";
|
|
134
|
+
}
|
|
135
|
+
return rlen;
|
|
136
|
+
}
|
|
137
|
+
readbuf.space_wrote(rlen);
|
|
138
|
+
return rlen;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void
|
|
142
|
+
hstcpcli::clear_error()
|
|
143
|
+
{
|
|
144
|
+
DBG(fprintf(stderr, "CLEAR_ERROR: %d\n", error_code));
|
|
145
|
+
error_code = 0;
|
|
146
|
+
error_str.clear();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
int
|
|
150
|
+
hstcpcli::set_error(int code, const std::string& str)
|
|
151
|
+
{
|
|
152
|
+
DBG(fprintf(stderr, "SET_ERROR: %d\n", code));
|
|
153
|
+
error_code = code;
|
|
154
|
+
error_str = str;
|
|
155
|
+
return error_code;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
void
|
|
159
|
+
hstcpcli::request_buf_open_index(size_t pst_id, const char *dbn,
|
|
160
|
+
const char *tbl, const char *idx, const char *retflds, const char *filflds)
|
|
161
|
+
{
|
|
162
|
+
if (num_req_sent > 0 || num_req_rcvd > 0) {
|
|
163
|
+
close();
|
|
164
|
+
set_error(-1, "request_buf_open_index: protocol out of sync");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const string_ref dbn_ref(dbn, strlen(dbn));
|
|
168
|
+
const string_ref tbl_ref(tbl, strlen(tbl));
|
|
169
|
+
const string_ref idx_ref(idx, strlen(idx));
|
|
170
|
+
const string_ref rfs_ref(retflds, strlen(retflds));
|
|
171
|
+
writebuf.append_literal("P\t");
|
|
172
|
+
append_uint32(writebuf, pst_id); // FIXME size_t ?
|
|
173
|
+
writebuf.append_literal("\t");
|
|
174
|
+
writebuf.append(dbn_ref.begin(), dbn_ref.end());
|
|
175
|
+
writebuf.append_literal("\t");
|
|
176
|
+
writebuf.append(tbl_ref.begin(), tbl_ref.end());
|
|
177
|
+
writebuf.append_literal("\t");
|
|
178
|
+
writebuf.append(idx_ref.begin(), idx_ref.end());
|
|
179
|
+
writebuf.append_literal("\t");
|
|
180
|
+
writebuf.append(rfs_ref.begin(), rfs_ref.end());
|
|
181
|
+
if (filflds != 0) {
|
|
182
|
+
const string_ref fls_ref(filflds, strlen(filflds));
|
|
183
|
+
writebuf.append_literal("\t");
|
|
184
|
+
writebuf.append(fls_ref.begin(), fls_ref.end());
|
|
185
|
+
}
|
|
186
|
+
writebuf.append_literal("\n");
|
|
187
|
+
++num_req_bufd;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
void
|
|
191
|
+
hstcpcli::request_buf_auth(const char *secret, const char *typ)
|
|
192
|
+
{
|
|
193
|
+
if (num_req_sent > 0 || num_req_rcvd > 0) {
|
|
194
|
+
close();
|
|
195
|
+
set_error(-1, "request_buf_auth: protocol out of sync");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (typ == 0) {
|
|
199
|
+
typ = "1";
|
|
200
|
+
}
|
|
201
|
+
const string_ref typ_ref(typ, strlen(typ));
|
|
202
|
+
const string_ref secret_ref(secret, strlen(secret));
|
|
203
|
+
writebuf.append_literal("A\t");
|
|
204
|
+
writebuf.append(typ_ref.begin(), typ_ref.end());
|
|
205
|
+
writebuf.append_literal("\t");
|
|
206
|
+
writebuf.append(secret_ref.begin(), secret_ref.end());
|
|
207
|
+
writebuf.append_literal("\n");
|
|
208
|
+
++num_req_bufd;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
namespace {
|
|
212
|
+
|
|
213
|
+
void
|
|
214
|
+
append_delim_value(string_buffer& buf, const char *start, const char *finish)
|
|
215
|
+
{
|
|
216
|
+
if (start == 0) {
|
|
217
|
+
/* null */
|
|
218
|
+
const char t[] = "\t\0";
|
|
219
|
+
buf.append(t, t + 2);
|
|
220
|
+
} else {
|
|
221
|
+
/* non-null */
|
|
222
|
+
buf.append_literal("\t");
|
|
223
|
+
escape_string(buf, start, finish);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
void
|
|
230
|
+
hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
|
|
231
|
+
const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
|
|
232
|
+
const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
|
|
233
|
+
const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
|
|
234
|
+
const string_ref *invalues, size_t invalueslen)
|
|
235
|
+
{
|
|
236
|
+
if (num_req_sent > 0 || num_req_rcvd > 0) {
|
|
237
|
+
close();
|
|
238
|
+
set_error(-1, "request_buf_exec_generic: protocol out of sync");
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
append_uint32(writebuf, pst_id); // FIXME size_t ?
|
|
242
|
+
writebuf.append_literal("\t");
|
|
243
|
+
writebuf.append(op.begin(), op.end());
|
|
244
|
+
writebuf.append_literal("\t");
|
|
245
|
+
append_uint32(writebuf, kvslen); // FIXME size_t ?
|
|
246
|
+
for (size_t i = 0; i < kvslen; ++i) {
|
|
247
|
+
const string_ref& kv = kvs[i];
|
|
248
|
+
append_delim_value(writebuf, kv.begin(), kv.end());
|
|
249
|
+
}
|
|
250
|
+
if (limit != 0 || skip != 0 || invalues_keypart >= 0 ||
|
|
251
|
+
mod_op.size() != 0 || filslen != 0) {
|
|
252
|
+
/* has more option */
|
|
253
|
+
writebuf.append_literal("\t");
|
|
254
|
+
append_uint32(writebuf, limit); // FIXME size_t ?
|
|
255
|
+
if (skip != 0 || invalues_keypart >= 0 ||
|
|
256
|
+
mod_op.size() != 0 || filslen != 0) {
|
|
257
|
+
writebuf.append_literal("\t");
|
|
258
|
+
append_uint32(writebuf, skip); // FIXME size_t ?
|
|
259
|
+
}
|
|
260
|
+
if (invalues_keypart >= 0) {
|
|
261
|
+
writebuf.append_literal("\t@\t");
|
|
262
|
+
append_uint32(writebuf, invalues_keypart);
|
|
263
|
+
writebuf.append_literal("\t");
|
|
264
|
+
append_uint32(writebuf, invalueslen);
|
|
265
|
+
for (size_t i = 0; i < invalueslen; ++i) {
|
|
266
|
+
const string_ref& s = invalues[i];
|
|
267
|
+
append_delim_value(writebuf, s.begin(), s.end());
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
for (size_t i = 0; i < filslen; ++i) {
|
|
271
|
+
const hstcpcli_filter& f = fils[i];
|
|
272
|
+
writebuf.append_literal("\t");
|
|
273
|
+
writebuf.append(f.filter_type.begin(), f.filter_type.end());
|
|
274
|
+
writebuf.append_literal("\t");
|
|
275
|
+
writebuf.append(f.op.begin(), f.op.end());
|
|
276
|
+
writebuf.append_literal("\t");
|
|
277
|
+
append_uint32(writebuf, f.ff_offset);
|
|
278
|
+
append_delim_value(writebuf, f.val.begin(), f.val.end());
|
|
279
|
+
}
|
|
280
|
+
if (mod_op.size() != 0) {
|
|
281
|
+
writebuf.append_literal("\t");
|
|
282
|
+
writebuf.append(mod_op.begin(), mod_op.end());
|
|
283
|
+
for (size_t i = 0; i < mvslen; ++i) {
|
|
284
|
+
const string_ref& mv = mvs[i];
|
|
285
|
+
append_delim_value(writebuf, mv.begin(), mv.end());
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
writebuf.append_literal("\n");
|
|
290
|
+
++num_req_bufd;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
int
|
|
294
|
+
hstcpcli::request_send()
|
|
295
|
+
{
|
|
296
|
+
if (error_code < 0) {
|
|
297
|
+
return error_code;
|
|
298
|
+
}
|
|
299
|
+
clear_error();
|
|
300
|
+
if (fd.get() < 0) {
|
|
301
|
+
close();
|
|
302
|
+
return set_error(-1, "write: closed");
|
|
303
|
+
}
|
|
304
|
+
if (num_req_bufd == 0 || num_req_sent > 0 || num_req_rcvd > 0) {
|
|
305
|
+
close();
|
|
306
|
+
return set_error(-1, "request_send: protocol out of sync");
|
|
307
|
+
}
|
|
308
|
+
const size_t wrlen = writebuf.size();
|
|
309
|
+
const ssize_t r = send(fd.get(), writebuf.begin(), wrlen, MSG_NOSIGNAL);
|
|
310
|
+
if (r <= 0) {
|
|
311
|
+
close();
|
|
312
|
+
return set_error(-1, r < 0 ? "write: failed" : "write: eof");
|
|
313
|
+
}
|
|
314
|
+
writebuf.erase_front(r);
|
|
315
|
+
if (static_cast<size_t>(r) != wrlen) {
|
|
316
|
+
close();
|
|
317
|
+
return set_error(-1, "write: incomplete");
|
|
318
|
+
}
|
|
319
|
+
num_req_sent = num_req_bufd;
|
|
320
|
+
num_req_bufd = 0;
|
|
321
|
+
DBG(fprintf(stderr, "REQSEND 0\n"));
|
|
322
|
+
return 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
int
|
|
326
|
+
hstcpcli::response_recv(size_t& num_flds_r)
|
|
327
|
+
{
|
|
328
|
+
if (error_code < 0) {
|
|
329
|
+
return error_code;
|
|
330
|
+
}
|
|
331
|
+
clear_error();
|
|
332
|
+
if (num_req_bufd > 0 || num_req_sent == 0 || num_req_rcvd > 0 ||
|
|
333
|
+
response_end_offset != 0) {
|
|
334
|
+
close();
|
|
335
|
+
return set_error(-1, "response_recv: protocol out of sync");
|
|
336
|
+
}
|
|
337
|
+
cur_row_offset = 0;
|
|
338
|
+
num_flds_r = num_flds = 0;
|
|
339
|
+
if (fd.get() < 0) {
|
|
340
|
+
return set_error(-1, "read: closed");
|
|
341
|
+
}
|
|
342
|
+
size_t offset = 0;
|
|
343
|
+
while (true) {
|
|
344
|
+
const char *const lbegin = readbuf.begin() + offset;
|
|
345
|
+
const char *const lend = readbuf.end();
|
|
346
|
+
const char *const nl = memchr_char(lbegin, '\n', lend - lbegin);
|
|
347
|
+
if (nl != 0) {
|
|
348
|
+
offset = (nl + 1) - readbuf.begin();
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
if (read_more() <= 0) {
|
|
352
|
+
close();
|
|
353
|
+
return set_error(-1, "read: eof");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
response_end_offset = offset;
|
|
357
|
+
--num_req_sent;
|
|
358
|
+
++num_req_rcvd;
|
|
359
|
+
char *start = readbuf.begin();
|
|
360
|
+
char *const finish = start + response_end_offset - 1;
|
|
361
|
+
const size_t resp_code = read_ui32(start, finish);
|
|
362
|
+
skip_one(start, finish);
|
|
363
|
+
num_flds_r = num_flds = read_ui32(start, finish);
|
|
364
|
+
if (resp_code != 0) {
|
|
365
|
+
skip_one(start, finish);
|
|
366
|
+
char *const err_begin = start;
|
|
367
|
+
read_token(start, finish);
|
|
368
|
+
char *const err_end = start;
|
|
369
|
+
std::string e = std::string(err_begin, err_end - err_begin);
|
|
370
|
+
if (e.empty()) {
|
|
371
|
+
e = "unknown_error";
|
|
372
|
+
}
|
|
373
|
+
return set_error(resp_code, e);
|
|
374
|
+
}
|
|
375
|
+
cur_row_offset = start - readbuf.begin();
|
|
376
|
+
DBG(fprintf(stderr, "[%s] ro=%zu eol=%zu\n",
|
|
377
|
+
std::string(readbuf.begin(), readbuf.begin() + response_end_offset)
|
|
378
|
+
.c_str(),
|
|
379
|
+
cur_row_offset, response_end_offset));
|
|
380
|
+
DBG(fprintf(stderr, "RES 0\n"));
|
|
381
|
+
return 0;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const string_ref *
|
|
385
|
+
hstcpcli::get_next_row()
|
|
386
|
+
{
|
|
387
|
+
if (num_flds == 0) {
|
|
388
|
+
DBG(fprintf(stderr, "GNR NF 0\n"));
|
|
389
|
+
return 0;
|
|
390
|
+
}
|
|
391
|
+
if (flds.size() < num_flds) {
|
|
392
|
+
flds.resize(num_flds);
|
|
393
|
+
}
|
|
394
|
+
char *start = readbuf.begin() + cur_row_offset;
|
|
395
|
+
char *const finish = readbuf.begin() + response_end_offset - 1;
|
|
396
|
+
if (start >= finish) { /* start[0] == nl */
|
|
397
|
+
DBG(fprintf(stderr, "GNR FIN 0 %p %p\n", start, finish));
|
|
398
|
+
return 0;
|
|
399
|
+
}
|
|
400
|
+
for (size_t i = 0; i < num_flds; ++i) {
|
|
401
|
+
skip_one(start, finish);
|
|
402
|
+
char *const fld_begin = start;
|
|
403
|
+
read_token(start, finish);
|
|
404
|
+
char *const fld_end = start;
|
|
405
|
+
char *wp = fld_begin;
|
|
406
|
+
if (is_null_expression(fld_begin, fld_end)) {
|
|
407
|
+
/* null */
|
|
408
|
+
flds[i] = string_ref();
|
|
409
|
+
} else {
|
|
410
|
+
unescape_string(wp, fld_begin, fld_end); /* in-place */
|
|
411
|
+
flds[i] = string_ref(fld_begin, wp);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
cur_row_offset = start - readbuf.begin();
|
|
415
|
+
return &flds[0];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
void
|
|
419
|
+
hstcpcli::response_buf_remove()
|
|
420
|
+
{
|
|
421
|
+
if (response_end_offset == 0) {
|
|
422
|
+
close();
|
|
423
|
+
set_error(-1, "response_buf_remove: protocol out of sync");
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
readbuf.erase_front(response_end_offset);
|
|
427
|
+
response_end_offset = 0;
|
|
428
|
+
--num_req_rcvd;
|
|
429
|
+
cur_row_offset = 0;
|
|
430
|
+
num_flds = 0;
|
|
431
|
+
flds.clear();
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
hstcpcli_ptr
|
|
435
|
+
hstcpcli_i::create(const socket_args& args)
|
|
436
|
+
{
|
|
437
|
+
return hstcpcli_ptr(new hstcpcli(args));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
};
|
|
441
|
+
|