handlersocket 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 miyucy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = handlersocket
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 miyucy. See LICENSE for details.
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "handlersocket"
8
+ gem.summary = %Q{libhsclient(HandlerSocket) binding for Ruby}
9
+ gem.description = %Q{libhsclient(HandlerSocket) binding for Ruby}
10
+ gem.email = "miyucy@gmail.com"
11
+ gem.homepage = "http://github.com/miyucy/handlersocket"
12
+ gem.authors = ["miyucy"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "handlersocket #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,6 @@
1
+ require "mkmf"
2
+
3
+ $CFLAGS << " -I/usr/include/handlersocket"
4
+ have_library("hsclient")
5
+ have_library("stdc++")
6
+ create_makefile("handler_socket")
@@ -0,0 +1,411 @@
1
+ #include <ruby.h>
2
+ #include "hstcpcli.hpp"
3
+
4
+ typedef struct {
5
+ dena::hstcpcli_i *ptr;
6
+ } HandlerSocket;
7
+
8
+ void hs_free(HandlerSocket* hs)
9
+ {
10
+ if (hs) {
11
+ if (hs->ptr) {
12
+ hs->ptr->close();
13
+ delete hs->ptr;
14
+ }
15
+ xfree(hs);
16
+ }
17
+ }
18
+
19
+ void hs_mark(HandlerSocket* hs)
20
+ {
21
+ }
22
+
23
+ VALUE hs_alloc(VALUE self)
24
+ {
25
+ return Data_Wrap_Struct(self, hs_mark, hs_free, 0);
26
+ }
27
+
28
+ void parse_options(dena::config& conf, dena::socket_args& args, VALUE options)
29
+ {
30
+ VALUE val;
31
+
32
+ Check_Type(options, T_HASH);
33
+
34
+ val = rb_hash_aref(options, ID2SYM(rb_intern("host")));
35
+ if(val != Qnil)
36
+ {
37
+ conf["host"] = std::string(StringValuePtr(val));
38
+ }
39
+
40
+ val = rb_hash_aref(options, ID2SYM(rb_intern("port")));
41
+ if(val != Qnil)
42
+ {
43
+ conf["port"] = std::string(StringValuePtr(val));
44
+ }
45
+
46
+ val = rb_hash_aref(options, ID2SYM(rb_intern("timeout")));
47
+ if(val != Qnil)
48
+ {
49
+ conf["timeout"] = std::string(StringValuePtr(val));
50
+ }
51
+
52
+ val = rb_hash_aref(options, ID2SYM(rb_intern("listen_backlog")));
53
+ if(val != Qnil)
54
+ {
55
+ conf["listen_backlog"] = std::string(StringValuePtr(val));
56
+ }
57
+
58
+ val = rb_hash_aref(options, ID2SYM(rb_intern("sndbuf")));
59
+ if(val != Qnil)
60
+ {
61
+ conf["sndbuf"] = std::string(StringValuePtr(val));
62
+ }
63
+
64
+ val = rb_hash_aref(options, ID2SYM(rb_intern("rcvbuf")));
65
+ if(val != Qnil)
66
+ {
67
+ conf["rcvbuf"] = std::string(StringValuePtr(val));
68
+ }
69
+
70
+ args.set(conf);
71
+ }
72
+
73
+ VALUE hs_initialize(VALUE self, VALUE options)
74
+ {
75
+ HandlerSocket* hs;
76
+
77
+ Data_Get_Struct(self, HandlerSocket, hs);
78
+ if (!hs) {
79
+ hs = (HandlerSocket*)xmalloc(sizeof(HandlerSocket));
80
+ MEMZERO(hs, HandlerSocket, 1);
81
+ DATA_PTR(self) = hs;
82
+ }
83
+
84
+ dena::config conf;
85
+ dena::socket_args args;
86
+ parse_options(conf, args, options);
87
+
88
+ dena::hstcpcli_ptr ptr = dena::hstcpcli_i::create(args);
89
+ hs->ptr = ptr.get();
90
+ ptr.release();
91
+
92
+ return self;
93
+ }
94
+
95
+ VALUE hs_close(VALUE self)
96
+ {
97
+ HandlerSocket* hs;
98
+ Data_Get_Struct(self, HandlerSocket, hs);
99
+
100
+ hs->ptr->close();
101
+ return Qnil;
102
+ }
103
+
104
+ VALUE hs_reconnect(VALUE self)
105
+ {
106
+ HandlerSocket* hs;
107
+ Data_Get_Struct(self, HandlerSocket, hs);
108
+
109
+ return INT2FIX(hs->ptr->reconnect());
110
+ }
111
+
112
+ VALUE hs_stable_point(VALUE self)
113
+ {
114
+ HandlerSocket* hs;
115
+ Data_Get_Struct(self, HandlerSocket, hs);
116
+
117
+ return hs->ptr->stable_point() ? Qtrue : Qfalse;
118
+ }
119
+
120
+ VALUE hs_error(VALUE self)
121
+ {
122
+ HandlerSocket* hs;
123
+ Data_Get_Struct(self, HandlerSocket, hs);
124
+
125
+ VALUE val = Qnil;
126
+ std::string error = hs->ptr->get_error();
127
+
128
+ if (!error.empty()) {
129
+ val = rb_str_new2(error.c_str());
130
+ }
131
+ return val;
132
+ }
133
+
134
+ VALUE hs_error_code(VALUE self)
135
+ {
136
+ HandlerSocket* hs;
137
+ Data_Get_Struct(self, HandlerSocket, hs);
138
+
139
+ return INT2FIX(hs->ptr->get_error_code());
140
+ }
141
+
142
+ VALUE hs_open_index(VALUE self, VALUE id, VALUE db, VALUE table, VALUE index, VALUE fields)
143
+ {
144
+ HandlerSocket* hs;
145
+ Data_Get_Struct(self, HandlerSocket, hs);
146
+ dena::hstcpcli_i *const ptr = hs->ptr;
147
+ size_t _id = NUM2INT(id);
148
+ VALUE _db = rb_obj_dup(db),
149
+ _table = rb_obj_dup(table),
150
+ _index = rb_obj_dup(index),
151
+ _fields = rb_obj_dup(fields);
152
+ size_t nflds;
153
+ int result;
154
+
155
+ ptr->request_buf_open_index(_id,
156
+ StringValueCStr(_db),
157
+ StringValueCStr(_table),
158
+ StringValueCStr(_index),
159
+ StringValueCStr(_fields));
160
+ if(ptr->get_error_code() < 0)
161
+ {
162
+ return hs_error_code(self);
163
+ }
164
+
165
+ if (ptr->request_send() != 0) {
166
+ return hs_error_code(self);
167
+ }
168
+
169
+ result = ptr->response_recv(nflds);
170
+ if (result >= 0) {
171
+ ptr->response_buf_remove();
172
+ }
173
+
174
+ return hs_error_code(self);
175
+ }
176
+
177
+ VALUE ary_to_vector(VALUE ary, std::vector<dena::string_ref>& vec)
178
+ {
179
+ VALUE ret, val;
180
+
181
+ if (NIL_P(ary) || RARRAY_LEN(ary) == 0) {
182
+ return ary;
183
+ }
184
+
185
+ ret = rb_ary_new2(RARRAY_LEN(ary));
186
+ vec.reserve(RARRAY_LEN(ary));
187
+
188
+ for (size_t i=0; i<RARRAY_LEN(ary); i++) {
189
+ val = rb_ary_entry(ary, i);
190
+ if (FIXNUM_P(val)) {
191
+ val = rb_fix2str(val, 10);
192
+ }
193
+ StringValue(val);
194
+ vec.push_back(dena::string_ref(RSTRING_PTR(val), RSTRING_LEN(val)));
195
+ rb_ary_push(ret, val);
196
+ }
197
+
198
+ return ret;
199
+ }
200
+
201
+ VALUE hs_get_resultset(dena::hstcpcli_i *const ptr, size_t nflds)
202
+ {
203
+ VALUE arys, ary, val;
204
+
205
+ arys = rb_ary_new();
206
+ const dena::string_ref *row = 0;
207
+ while ((row = ptr->get_next_row()) != 0) {
208
+ ary = rb_ary_new2(nflds);
209
+ for (size_t i = 0; i < nflds; ++i) {
210
+ const dena::string_ref& v = row[i];
211
+ if (v.begin() != 0) {
212
+ val = rb_str_new(v.begin(), v.size());
213
+ rb_ary_push(ary, val);
214
+ } else {
215
+ rb_ary_push(ary, Qnil);
216
+ }
217
+ }
218
+ rb_ary_push(arys, ary);
219
+ }
220
+ return arys;
221
+ }
222
+
223
+ void hs_prepare(dena::hstcpcli_i *const ptr, VALUE id, VALUE op, VALUE keys, VALUE limit, VALUE skip, VALUE modop, VALUE modvals)
224
+ {
225
+ StringValue(op);
226
+ Check_Type(keys, T_ARRAY);
227
+
228
+ if (!NIL_P(modop)) {
229
+ StringValue(modop);
230
+ }
231
+
232
+ dena::string_ref op_ref, modop_ref;
233
+ std::vector<dena::string_ref> keyary, modary;
234
+
235
+ op_ref = dena::string_ref(RSTRING_PTR(op), RSTRING_LEN(op));
236
+ keys = ary_to_vector(keys, keyary);
237
+
238
+ if (!NIL_P(modop)) {
239
+ modop_ref = dena::string_ref(RSTRING_PTR(modop), RSTRING_LEN(modop));
240
+ modvals = ary_to_vector(modvals, modary);
241
+ }
242
+
243
+ if (NIL_P(limit)) {
244
+ limit = INT2FIX(1);
245
+ }
246
+
247
+ if (NIL_P(skip)) {
248
+ skip = INT2FIX(0);
249
+ }
250
+
251
+ ptr->request_buf_exec_generic(NUM2INT(id),
252
+ op_ref,
253
+ &keyary[0], keyary.size(),
254
+ NUM2INT(limit), NUM2INT(skip),
255
+ modop_ref,
256
+ &modary[0], modary.size());
257
+ }
258
+
259
+ VALUE hs_execute_single(int argc, VALUE *argv, VALUE self)
260
+ {
261
+ HandlerSocket* hs;
262
+ Data_Get_Struct(self, HandlerSocket, hs);
263
+ dena::hstcpcli_i *const ptr = hs->ptr;
264
+
265
+ VALUE id, op, keys, limit, skip, modop, modvals;
266
+ rb_scan_args(argc, argv, "34", &id, &op, &keys, &limit, &skip, &modop, &modvals);
267
+
268
+ hs_prepare(ptr, id, op, keys, limit, skip, modop, modvals);
269
+ if (ptr->request_send() != 0) {
270
+ return Qnil;
271
+ }
272
+
273
+ size_t nflds = 0;
274
+ int result = ptr->response_recv(nflds);
275
+ VALUE retval = rb_ary_new2(2);
276
+
277
+ rb_ary_push(retval, INT2FIX(result));
278
+ if (result != 0) {
279
+ rb_ary_push(retval, rb_str_new2(ptr->get_error().c_str()));
280
+ } else {
281
+ rb_ary_push(retval, hs_get_resultset(ptr, nflds));
282
+ }
283
+
284
+ if (result >= 0) {
285
+ ptr->response_buf_remove();
286
+ }
287
+
288
+ return retval;
289
+ }
290
+
291
+ VALUE hs_execute_multi(int argc, VALUE *argv, VALUE self)
292
+ {
293
+ HandlerSocket* hs;
294
+ Data_Get_Struct(self, HandlerSocket, hs);
295
+ dena::hstcpcli_i *const ptr = hs->ptr;
296
+
297
+ VALUE exec_args, exec_arg;
298
+
299
+ VALUE id, op, keys, limit, skip, modop, modvals;
300
+ int arg = rb_scan_args(argc, argv, "16", &id, &op, &keys, &limit, &skip, &modop, &modvals);
301
+ if (arg >= 3) {
302
+ VALUE tmp = rb_ary_new3(7, id, op, keys, limit, skip, modop, modvals);
303
+ exec_args = rb_ary_new3(1, tmp);
304
+ } else if (arg == 1) {
305
+ Check_Type(id, T_ARRAY);
306
+ exec_args = id;
307
+ } else {
308
+ rb_raise(rb_eArgError, "wrong number of arguments");
309
+ }
310
+
311
+ for (size_t i=0; i<RARRAY_LEN(exec_args); i++) {
312
+ exec_arg = rb_ary_entry(exec_args, i);
313
+ Check_Type(exec_arg, T_ARRAY);
314
+
315
+ id = rb_ary_entry(exec_arg, 0);
316
+ op = rb_ary_entry(exec_arg, 1);
317
+ keys = rb_ary_entry(exec_arg, 2);
318
+ limit = rb_ary_entry(exec_arg, 3);
319
+ skip = rb_ary_entry(exec_arg, 4);
320
+ modop = rb_ary_entry(exec_arg, 5);
321
+ modvals = rb_ary_entry(exec_arg, 6);
322
+
323
+ hs_prepare(ptr, id, op, keys, limit, skip, modop, modvals);
324
+ }
325
+
326
+ VALUE retvals, retval;
327
+ retvals = rb_ary_new();
328
+
329
+ if (ptr->request_send() != 0) {
330
+ retval = rb_ary_new2(2);
331
+ rb_ary_push(retval, INT2FIX(ptr->get_error_code()));
332
+ rb_ary_push(retval, rb_str_new2(ptr->get_error().c_str()));
333
+ rb_ary_push(retvals, retval);
334
+ return retvals;
335
+ }
336
+
337
+ for (size_t i=0; i<RARRAY_LEN(exec_args); i++) {
338
+ size_t nflds = 0;
339
+ int result = ptr->response_recv(nflds);
340
+
341
+ retval = rb_ary_new2(2);
342
+ rb_ary_push(retval, INT2FIX(result));
343
+ if (result != 0) {
344
+ rb_ary_push(retval, rb_str_new2(ptr->get_error().c_str()));
345
+ } else {
346
+ rb_ary_push(retval, hs_get_resultset(ptr, nflds));
347
+ }
348
+
349
+ if (result >= 0) {
350
+ ptr->response_buf_remove();
351
+ }
352
+
353
+ rb_ary_push(retvals, retval);
354
+
355
+ if (result < 0) {
356
+ break;
357
+ }
358
+ }
359
+
360
+ return retvals;
361
+ }
362
+
363
+
364
+ VALUE hs_execute_update(VALUE self, VALUE id, VALUE op, VALUE keys, VALUE limit, VALUE skip, VALUE modvals)
365
+ {
366
+ VALUE argv[7] = {
367
+ id, op, keys, limit, skip, rb_str_new2("U"), modvals,
368
+ };
369
+ return hs_execute_single(7, argv, self);
370
+ }
371
+
372
+ VALUE hs_execute_delete(VALUE self, VALUE id, VALUE op, VALUE keys, VALUE limit, VALUE skip)
373
+ {
374
+ VALUE argv[7] = {
375
+ id, op, keys, limit, skip, rb_str_new2("D"), Qnil,
376
+ };
377
+ return hs_execute_single(7, argv, self);
378
+ }
379
+
380
+ VALUE hs_execute_insert(VALUE self, VALUE id, VALUE fvals)
381
+ {
382
+ VALUE argv[5] = {
383
+ id, rb_str_new2("+"), fvals, INT2FIX(0), INT2FIX(0),
384
+ };
385
+ return hs_execute_single(5, argv, self);
386
+ }
387
+
388
+ extern "C" {
389
+ void Init_handler_socket(void)
390
+ {
391
+ VALUE rb_cHandlerSocket = rb_define_class("HandlerSocket", rb_cObject);
392
+
393
+ rb_define_alloc_func(rb_cHandlerSocket, hs_alloc);
394
+ rb_define_private_method(rb_cHandlerSocket, "initialize", (VALUE(*)(...))hs_initialize, 1);
395
+
396
+ rb_define_method(rb_cHandlerSocket, "close", (VALUE(*)(...))hs_close, 0);
397
+ rb_define_method(rb_cHandlerSocket, "reconnect", (VALUE(*)(...))hs_reconnect, 0);
398
+ rb_define_method(rb_cHandlerSocket, "stable_point", (VALUE(*)(...))hs_stable_point, 0);
399
+
400
+ rb_define_method(rb_cHandlerSocket, "error", (VALUE(*)(...))hs_error, 0);
401
+ rb_define_method(rb_cHandlerSocket, "error_code", (VALUE(*)(...))hs_error_code, 0);
402
+
403
+ rb_define_method(rb_cHandlerSocket, "open_index", (VALUE(*)(...))hs_open_index, 5);
404
+ rb_define_method(rb_cHandlerSocket, "execute_single", (VALUE(*)(...))hs_execute_single, -1);
405
+ rb_define_method(rb_cHandlerSocket, "execute_multi", (VALUE(*)(...))hs_execute_multi, -1);
406
+ rb_define_alias(rb_cHandlerSocket, "execute_find", "execute_single");
407
+ rb_define_method(rb_cHandlerSocket, "execute_update", (VALUE(*)(...))hs_execute_update, 6);
408
+ rb_define_method(rb_cHandlerSocket, "execute_delete", (VALUE(*)(...))hs_execute_delete, 5);
409
+ rb_define_method(rb_cHandlerSocket, "execute_insert", (VALUE(*)(...))hs_execute_insert, 2);
410
+ }
411
+ }
@@ -0,0 +1 @@
1
+ require 'handler_socket'
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe HandlerSocket do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'handlersocket'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: handlersocket
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - miyucy
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-22 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: libhsclient(HandlerSocket) binding for Ruby
38
+ email: miyucy@gmail.com
39
+ executables: []
40
+
41
+ extensions:
42
+ - ext/extconf.rb
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README.rdoc
46
+ files:
47
+ - .document
48
+ - .gitignore
49
+ - LICENSE
50
+ - README.rdoc
51
+ - Rakefile
52
+ - VERSION
53
+ - ext/extconf.rb
54
+ - ext/handler_socket.cc
55
+ - lib/handlersocket.rb
56
+ - spec/handlersocket_spec.rb
57
+ - spec/spec.opts
58
+ - spec/spec_helper.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/miyucy/handlersocket
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.3.7
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: libhsclient(HandlerSocket) binding for Ruby
93
+ test_files:
94
+ - spec/handlersocket_spec.rb
95
+ - spec/spec_helper.rb