nio4r 2.0.0.pre-java → 2.1.0-java

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +31 -38
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +9 -19
  6. data/CHANGES.md +94 -42
  7. data/Gemfile +11 -3
  8. data/Guardfile +10 -0
  9. data/LICENSE.txt +1 -1
  10. data/README.md +43 -136
  11. data/Rakefile +2 -0
  12. data/examples/echo_server.rb +1 -0
  13. data/ext/libev/Changes +9 -13
  14. data/ext/libev/ev.c +100 -74
  15. data/ext/libev/ev.h +4 -9
  16. data/ext/libev/ev_epoll.c +6 -3
  17. data/ext/libev/ev_kqueue.c +8 -4
  18. data/ext/libev/ev_poll.c +6 -3
  19. data/ext/libev/ev_port.c +8 -4
  20. data/ext/libev/ev_select.c +4 -2
  21. data/ext/nio4r/bytebuffer.c +265 -257
  22. data/ext/nio4r/extconf.rb +3 -9
  23. data/ext/nio4r/monitor.c +93 -46
  24. data/ext/nio4r/nio4r.h +6 -16
  25. data/ext/nio4r/org/nio4r/ByteBuffer.java +193 -209
  26. data/ext/nio4r/org/nio4r/Monitor.java +164 -0
  27. data/ext/nio4r/org/nio4r/Nio4r.java +13 -391
  28. data/ext/nio4r/org/nio4r/Selector.java +278 -0
  29. data/ext/nio4r/selector.c +72 -64
  30. data/lib/nio.rb +3 -3
  31. data/lib/nio/bytebuffer.rb +179 -132
  32. data/lib/nio/monitor.rb +64 -4
  33. data/lib/nio/selector.rb +36 -13
  34. data/lib/nio/version.rb +1 -1
  35. data/nio4r.gemspec +25 -19
  36. data/spec/nio/acceptables_spec.rb +6 -4
  37. data/spec/nio/bytebuffer_spec.rb +323 -51
  38. data/spec/nio/monitor_spec.rb +122 -79
  39. data/spec/nio/selectables/pipe_spec.rb +5 -1
  40. data/spec/nio/selectables/ssl_socket_spec.rb +15 -12
  41. data/spec/nio/selectables/tcp_socket_spec.rb +42 -31
  42. data/spec/nio/selectables/udp_socket_spec.rb +2 -0
  43. data/spec/nio/selector_spec.rb +10 -4
  44. data/spec/spec_helper.rb +24 -3
  45. data/spec/support/selectable_examples.rb +7 -5
  46. data/tasks/extension.rake +2 -0
  47. data/tasks/rspec.rake +2 -0
  48. data/tasks/rubocop.rake +2 -0
  49. metadata +18 -15
  50. data/.rubocop_todo.yml +0 -35
data/ext/libev/ev.h CHANGED
@@ -56,11 +56,6 @@ EV_CPP(extern "C" {)
56
56
 
57
57
  /*****************************************************************************/
58
58
 
59
- /* pre-4.0 compatibility */
60
- #ifndef EV_COMPAT3
61
- # define EV_COMPAT3 1
62
- #endif
63
-
64
59
  #ifndef EV_FEATURES
65
60
  # if defined __OPTIMIZE_SIZE__
66
61
  # define EV_FEATURES 0x7c
@@ -211,7 +206,7 @@ struct ev_loop;
211
206
  /*****************************************************************************/
212
207
 
213
208
  #define EV_VERSION_MAJOR 4
214
- #define EV_VERSION_MINOR 22
209
+ #define EV_VERSION_MINOR 24
215
210
 
216
211
  /* eventmask, revents, events... */
217
212
  enum {
@@ -515,10 +510,10 @@ enum {
515
510
 
516
511
  /* method bits to be ored together */
517
512
  enum {
518
- EVBACKEND_SELECT = 0x00000001U, /* about anywhere */
519
- EVBACKEND_POLL = 0x00000002U, /* !win */
513
+ EVBACKEND_SELECT = 0x00000001U, /* available just about anywhere */
514
+ EVBACKEND_POLL = 0x00000002U, /* !win, !aix, broken on osx */
520
515
  EVBACKEND_EPOLL = 0x00000004U, /* linux */
521
- EVBACKEND_KQUEUE = 0x00000008U, /* bsd */
516
+ EVBACKEND_KQUEUE = 0x00000008U, /* bsd, broken on osx */
522
517
  EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
523
518
  EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
524
519
  EVBACKEND_ALL = 0x0000003FU, /* all known backends */
data/ext/libev/ev_epoll.c CHANGED
@@ -235,7 +235,8 @@ epoll_poll (EV_P_ ev_tstamp timeout)
235
235
  }
236
236
  }
237
237
 
238
- int inline_size
238
+ inline_size
239
+ int
239
240
  epoll_init (EV_P_ int flags)
240
241
  {
241
242
  #ifdef EPOLL_CLOEXEC
@@ -260,14 +261,16 @@ epoll_init (EV_P_ int flags)
260
261
  return EVBACKEND_EPOLL;
261
262
  }
262
263
 
263
- void inline_size
264
+ inline_size
265
+ void
264
266
  epoll_destroy (EV_P)
265
267
  {
266
268
  ev_free (epoll_events);
267
269
  array_free (epoll_eperm, EMPTY);
268
270
  }
269
271
 
270
- void inline_size
272
+ inline_size
273
+ void
271
274
  epoll_fork (EV_P)
272
275
  {
273
276
  close (backend_fd);
@@ -43,7 +43,8 @@
43
43
  #include <string.h>
44
44
  #include <errno.h>
45
45
 
46
- void inline_speed
46
+ inline_speed
47
+ void
47
48
  kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
48
49
  {
49
50
  ++kqueue_changecnt;
@@ -152,7 +153,8 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
152
153
  }
153
154
  }
154
155
 
155
- int inline_size
156
+ inline_size
157
+ int
156
158
  kqueue_init (EV_P_ int flags)
157
159
  {
158
160
  /* initialize the kernel queue */
@@ -176,14 +178,16 @@ kqueue_init (EV_P_ int flags)
176
178
  return EVBACKEND_KQUEUE;
177
179
  }
178
180
 
179
- void inline_size
181
+ inline_size
182
+ void
180
183
  kqueue_destroy (EV_P)
181
184
  {
182
185
  ev_free (kqueue_events);
183
186
  ev_free (kqueue_changes);
184
187
  }
185
188
 
186
- void inline_size
189
+ inline_size
190
+ void
187
191
  kqueue_fork (EV_P)
188
192
  {
189
193
  /* some BSD kernels don't just destroy the kqueue itself,
data/ext/libev/ev_poll.c CHANGED
@@ -39,7 +39,8 @@
39
39
 
40
40
  #include <poll.h>
41
41
 
42
- void inline_size
42
+ inline_size
43
+ void
43
44
  pollidx_init (int *base, int count)
44
45
  {
45
46
  /* consider using memset (.., -1, ...), which is practically guaranteed
@@ -126,7 +127,8 @@ poll_poll (EV_P_ ev_tstamp timeout)
126
127
  }
127
128
  }
128
129
 
129
- int inline_size
130
+ inline_size
131
+ int
130
132
  poll_init (EV_P_ int flags)
131
133
  {
132
134
  backend_mintime = 1e-3;
@@ -139,7 +141,8 @@ poll_init (EV_P_ int flags)
139
141
  return EVBACKEND_POLL;
140
142
  }
141
143
 
142
- void inline_size
144
+ inline_size
145
+ void
143
146
  poll_destroy (EV_P)
144
147
  {
145
148
  ev_free (pollidxs);
data/ext/libev/ev_port.c CHANGED
@@ -55,7 +55,8 @@
55
55
  #include <string.h>
56
56
  #include <errno.h>
57
57
 
58
- void inline_speed
58
+ inline_speed
59
+ void
59
60
  port_associate_and_check (EV_P_ int fd, int ev)
60
61
  {
61
62
  if (0 >
@@ -136,7 +137,8 @@ port_poll (EV_P_ ev_tstamp timeout)
136
137
  }
137
138
  }
138
139
 
139
- int inline_size
140
+ inline_size
141
+ int
140
142
  port_init (EV_P_ int flags)
141
143
  {
142
144
  /* Initialize the kernel queue */
@@ -163,13 +165,15 @@ port_init (EV_P_ int flags)
163
165
  return EVBACKEND_PORT;
164
166
  }
165
167
 
166
- void inline_size
168
+ inline_size
169
+ void
167
170
  port_destroy (EV_P)
168
171
  {
169
172
  ev_free (port_events);
170
173
  }
171
174
 
172
- void inline_size
175
+ inline_size
176
+ void
173
177
  port_fork (EV_P)
174
178
  {
175
179
  close (backend_fd);
@@ -271,7 +271,8 @@ select_poll (EV_P_ ev_tstamp timeout)
271
271
  #endif
272
272
  }
273
273
 
274
- int inline_size
274
+ inline_size
275
+ int
275
276
  select_init (EV_P_ int flags)
276
277
  {
277
278
  backend_mintime = 1e-6;
@@ -300,7 +301,8 @@ select_init (EV_P_ int flags)
300
301
  return EVBACKEND_SELECT;
301
302
  }
302
303
 
303
- void inline_size
304
+ inline_size
305
+ void
304
306
  select_destroy (EV_P)
305
307
  {
306
308
  ev_free (vec_ri);
@@ -2,34 +2,39 @@
2
2
 
3
3
  static VALUE mNIO = Qnil;
4
4
  static VALUE cNIO_ByteBuffer = Qnil;
5
+ static VALUE cNIO_ByteBuffer_OverflowError = Qnil;
6
+ static VALUE cNIO_ByteBuffer_UnderflowError = Qnil;
7
+ static VALUE cNIO_ByteBuffer_MarkUnsetError = Qnil;
5
8
 
6
9
  /* Allocator/deallocator */
7
10
  static VALUE NIO_ByteBuffer_allocate(VALUE klass);
8
- static void NIO_ByteBuffer_mark(struct NIO_ByteBuffer *byteBuffer);
11
+ static void NIO_ByteBuffer_gc_mark(struct NIO_ByteBuffer *byteBuffer);
9
12
  static void NIO_ByteBuffer_free(struct NIO_ByteBuffer *byteBuffer);
10
13
 
11
14
  /* Methods */
12
- static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE value, VALUE offset, VALUE length);
13
- static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string);
14
- static VALUE NIO_ByteBuffer_get(VALUE self);
15
- static VALUE NIO_ByteBuffer_readnext(VALUE self, VALUE amount);
16
- static VALUE NIO_ByteBuffer_writeTo(VALUE self, VALUE file);
17
- static VALUE NIO_ByteBuffer_readFrom(VALUE self, VALUE file);
15
+ static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity);
16
+ static VALUE NIO_ByteBuffer_clear(VALUE self);
17
+ static VALUE NIO_ByteBuffer_get_position(VALUE self);
18
+ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position);
19
+ static VALUE NIO_ByteBuffer_get_limit(VALUE self);
20
+ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit);
21
+ static VALUE NIO_ByteBuffer_capacity(VALUE self);
18
22
  static VALUE NIO_ByteBuffer_remaining(VALUE self);
19
- static VALUE NIO_ByteBuffer_hasRemaining(VALUE self);
20
- static VALUE NIO_ByteBuffer_getOffset(VALUE self);
21
- static VALUE NIO_ByteBuffer_equals(VALUE self, VALUE other);
23
+ static VALUE NIO_ByteBuffer_full(VALUE self);
24
+ static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self);
25
+ static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index);
26
+ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string);
27
+ static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE file);
28
+ static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE file);
22
29
  static VALUE NIO_ByteBuffer_flip(VALUE self);
23
30
  static VALUE NIO_ByteBuffer_rewind(VALUE self);
31
+ static VALUE NIO_ByteBuffer_mark(VALUE self);
24
32
  static VALUE NIO_ByteBuffer_reset(VALUE self);
25
- static VALUE NIO_ByteBuffer_markBuffer(VALUE self);
26
- static VALUE NIO_ByteBuffer_clear(VALUE self);
27
33
  static VALUE NIO_ByteBuffer_compact(VALUE self);
28
- static VALUE NIO_ByteBuffer_capacity(VALUE self);
29
- static VALUE NIO_ByteBuffer_position(VALUE self, VALUE newPosition);
30
- static VALUE NIO_ByteBuffer_setLimit(VALUE self, VALUE newLimit);
31
- static VALUE NIO_ByteBuffer_getLimit(VALUE self);
32
- static VALUE NIO_ByteBuffer_toString(VALUE self);
34
+ static VALUE NIO_ByteBuffer_each(VALUE self);
35
+ static VALUE NIO_ByteBuffer_inspect(VALUE self);
36
+
37
+ #define MARK_UNSET -1
33
38
 
34
39
  void Init_NIO_ByteBuffer()
35
40
  {
@@ -37,36 +42,43 @@ void Init_NIO_ByteBuffer()
37
42
  cNIO_ByteBuffer = rb_define_class_under(mNIO, "ByteBuffer", rb_cObject);
38
43
  rb_define_alloc_func(cNIO_ByteBuffer, NIO_ByteBuffer_allocate);
39
44
 
40
- rb_define_method(cNIO_ByteBuffer, "initialize", NIO_ByteBuffer_initialize, 3);
41
- rb_define_method(cNIO_ByteBuffer, "<<", NIO_ByteBuffer_put, 1);
42
- rb_define_method(cNIO_ByteBuffer, "get", NIO_ByteBuffer_get, 0);
43
- rb_define_method(cNIO_ByteBuffer, "read_next", NIO_ByteBuffer_readnext, 1);
44
- rb_define_method(cNIO_ByteBuffer, "write_to", NIO_ByteBuffer_writeTo, 1);
45
- rb_define_method(cNIO_ByteBuffer, "read_from", NIO_ByteBuffer_readFrom, 1);
45
+ cNIO_ByteBuffer_OverflowError = rb_define_class_under(cNIO_ByteBuffer, "OverflowError", rb_eIOError);
46
+ cNIO_ByteBuffer_UnderflowError = rb_define_class_under(cNIO_ByteBuffer, "UnderflowError", rb_eIOError);
47
+ cNIO_ByteBuffer_MarkUnsetError = rb_define_class_under(cNIO_ByteBuffer, "MarkUnsetError", rb_eIOError);
48
+
49
+ rb_include_module(cNIO_ByteBuffer, rb_mEnumerable);
50
+
51
+ rb_define_method(cNIO_ByteBuffer, "initialize", NIO_ByteBuffer_initialize, 1);
52
+ rb_define_method(cNIO_ByteBuffer, "clear", NIO_ByteBuffer_clear, 0);
53
+ rb_define_method(cNIO_ByteBuffer, "position", NIO_ByteBuffer_get_position, 0);
54
+ rb_define_method(cNIO_ByteBuffer, "position=", NIO_ByteBuffer_set_position, 1);
55
+ rb_define_method(cNIO_ByteBuffer, "limit", NIO_ByteBuffer_get_limit, 0);
56
+ rb_define_method(cNIO_ByteBuffer, "limit=", NIO_ByteBuffer_set_limit, 1);
57
+ rb_define_method(cNIO_ByteBuffer, "capacity", NIO_ByteBuffer_capacity, 0);
58
+ rb_define_method(cNIO_ByteBuffer, "size", NIO_ByteBuffer_capacity, 0);
46
59
  rb_define_method(cNIO_ByteBuffer, "remaining", NIO_ByteBuffer_remaining, 0);
47
- rb_define_method(cNIO_ByteBuffer, "remaining?", NIO_ByteBuffer_hasRemaining, 0);
48
- rb_define_method(cNIO_ByteBuffer, "offset?", NIO_ByteBuffer_getOffset, 0);
49
- rb_define_method(cNIO_ByteBuffer, "equals", NIO_ByteBuffer_equals, 1);
60
+ rb_define_method(cNIO_ByteBuffer, "full?", NIO_ByteBuffer_full, 0);
61
+ rb_define_method(cNIO_ByteBuffer, "get", NIO_ByteBuffer_get, -1);
62
+ rb_define_method(cNIO_ByteBuffer, "[]", NIO_ByteBuffer_fetch, 1);
63
+ rb_define_method(cNIO_ByteBuffer, "<<", NIO_ByteBuffer_put, 1);
64
+ rb_define_method(cNIO_ByteBuffer, "read_from", NIO_ByteBuffer_read_from, 1);
65
+ rb_define_method(cNIO_ByteBuffer, "write_to", NIO_ByteBuffer_write_to, 1);
50
66
  rb_define_method(cNIO_ByteBuffer, "flip", NIO_ByteBuffer_flip, 0);
51
67
  rb_define_method(cNIO_ByteBuffer, "rewind", NIO_ByteBuffer_rewind, 0);
68
+ rb_define_method(cNIO_ByteBuffer, "mark", NIO_ByteBuffer_mark, 0);
52
69
  rb_define_method(cNIO_ByteBuffer, "reset", NIO_ByteBuffer_reset, 0);
53
- rb_define_method(cNIO_ByteBuffer, "mark", NIO_ByteBuffer_markBuffer, 0);
54
- rb_define_method(cNIO_ByteBuffer, "clear", NIO_ByteBuffer_clear, 0);
55
70
  rb_define_method(cNIO_ByteBuffer, "compact", NIO_ByteBuffer_compact, 0);
56
- rb_define_method(cNIO_ByteBuffer, "capacity", NIO_ByteBuffer_capacity, 0);
57
- rb_define_method(cNIO_ByteBuffer, "position", NIO_ByteBuffer_position, 1);
58
- rb_define_method(cNIO_ByteBuffer, "limit", NIO_ByteBuffer_setLimit, 1);
59
- rb_define_method(cNIO_ByteBuffer, "limit?", NIO_ByteBuffer_getLimit, 0);
60
- rb_define_method(cNIO_ByteBuffer, "to_s", NIO_ByteBuffer_toString, 0);
71
+ rb_define_method(cNIO_ByteBuffer, "each", NIO_ByteBuffer_each, 0);
72
+ rb_define_method(cNIO_ByteBuffer, "inspect", NIO_ByteBuffer_inspect, 0);
61
73
  }
62
74
 
63
75
  static VALUE NIO_ByteBuffer_allocate(VALUE klass)
64
76
  {
65
77
  struct NIO_ByteBuffer *bytebuffer = (struct NIO_ByteBuffer *)xmalloc(sizeof(struct NIO_ByteBuffer));
66
- return Data_Wrap_Struct(klass, NIO_ByteBuffer_mark, NIO_ByteBuffer_free, bytebuffer);
78
+ return Data_Wrap_Struct(klass, NIO_ByteBuffer_gc_mark, NIO_ByteBuffer_free, bytebuffer);
67
79
  }
68
80
 
69
- static void NIO_ByteBuffer_mark(struct NIO_ByteBuffer *buffer)
81
+ static void NIO_ByteBuffer_gc_mark(struct NIO_ByteBuffer *buffer)
70
82
  {
71
83
  }
72
84
 
@@ -75,339 +87,335 @@ static void NIO_ByteBuffer_free(struct NIO_ByteBuffer *buffer)
75
87
  xfree(buffer);
76
88
  }
77
89
 
78
- static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE value, VALUE i_offset, VALUE i_length)
90
+ static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity)
79
91
  {
80
- //Value can be either.
81
- //NUM -> Size of the buffer
82
- //STRING -> Data to be stored on the buffer
83
- struct NIO_ByteBuffer *byteBuffer;
84
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
85
-
86
- switch (TYPE(value)) {
87
- case T_FIXNUM:
88
- byteBuffer->size = NUM2INT(value);
89
- byteBuffer->buffer = malloc(sizeof(char) * byteBuffer->size);
90
- break;
91
- case T_STRING:
92
- byteBuffer->size = RSTRING_LEN(value);
93
- byteBuffer->buffer = StringValuePtr(value);
94
- //buffer = RSTRING_PTR(str);
95
- break;
96
- default:
97
- /* raise exception */
98
- rb_raise(rb_eTypeError, "not a valid input");
99
- break;
100
- }
101
-
102
- byteBuffer->position = 0;
103
- byteBuffer->offset = 0;
104
- byteBuffer->limit = byteBuffer->size - 1;
105
- byteBuffer->self = self;
92
+ struct NIO_ByteBuffer *buffer;
93
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
106
94
 
107
- if(i_offset != Qnil && TYPE(i_offset) == T_FIXNUM) {
108
- byteBuffer->offset = NUM2INT(i_offset);
109
- byteBuffer->position = byteBuffer->offset;
95
+ buffer->capacity = NUM2INT(capacity);
96
+ buffer->buffer = xmalloc(buffer->capacity);
110
97
 
111
- if(i_length != Qnil && TYPE(i_length) == T_FIXNUM) {
112
- int length = NUM2INT(i_length);
113
-
114
- if(byteBuffer->offset + length < byteBuffer->size) {
115
- byteBuffer->limit = byteBuffer->offset + length;
116
- } else {
117
- rb_raise(rb_eRuntimeError, "Invalid Arguiments Exception");
118
- }
119
- }
120
- }
121
-
122
- if(byteBuffer->size == 0) {
123
- rb_raise(rb_eRuntimeError, "Invalid Arguiments Exception");
124
- }
98
+ NIO_ByteBuffer_clear(self);
125
99
 
126
100
  return self;
127
101
  }
128
102
 
129
- static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
103
+ static VALUE NIO_ByteBuffer_clear(VALUE self)
130
104
  {
131
- struct NIO_ByteBuffer *byteBuffer;
132
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
105
+ struct NIO_ByteBuffer *buffer;
106
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
133
107
 
134
- if(TYPE(string) == T_STRING) {
135
- char *temp = StringValuePtr(string);
136
- int i = 0;
137
- int limit = RSTRING_LEN(string);
108
+ memset(buffer->buffer, 0, buffer->capacity);
138
109
 
139
- for(byteBuffer->position; i < limit; byteBuffer->position++) {
140
- byteBuffer->buffer[byteBuffer->position] = temp[i++];
141
- }
142
- }
110
+ buffer->position = 0;
111
+ buffer->limit = buffer->capacity;
112
+ buffer->mark = MARK_UNSET;
143
113
 
144
114
  return self;
145
115
  }
146
116
 
147
- static VALUE NIO_ByteBuffer_get(VALUE self)
117
+ static VALUE NIO_ByteBuffer_get_position(VALUE self)
118
+ {
119
+ struct NIO_ByteBuffer *buffer;
120
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
121
+
122
+ return INT2NUM(buffer->position);
123
+ }
124
+
125
+ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position)
148
126
  {
149
- struct NIO_ByteBuffer *byteBuffer;
150
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
127
+ struct NIO_ByteBuffer *buffer;
128
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
129
+
130
+ int pos = NUM2INT(new_position);
151
131
 
152
- int remaining = NUM2INT(NIO_ByteBuffer_remaining(self));
132
+ if(pos < 0) {
133
+ rb_raise(rb_eArgError, "negative position given");
134
+ }
153
135
 
154
- if(remaining == 0) {
155
- return rb_str_new2("");
136
+ if(pos > buffer->limit) {
137
+ rb_raise(rb_eArgError, "specified position exceeds limit");
156
138
  }
157
139
 
158
- char tempArray[remaining+1];
159
- int i = 0;
140
+ buffer->position = pos;
160
141
 
161
- for(byteBuffer->position; byteBuffer->position <= byteBuffer->limit; byteBuffer->position++) {
162
- tempArray[i++] = byteBuffer->buffer[byteBuffer->position];
142
+ if(buffer->mark > buffer->position) {
143
+ buffer->mark = MARK_UNSET;
163
144
  }
164
145
 
165
- tempArray[remaining] = '\0';
166
- return rb_str_new2(tempArray);
146
+ return new_position;
147
+ }
148
+
149
+ static VALUE NIO_ByteBuffer_get_limit(VALUE self)
150
+ {
151
+ struct NIO_ByteBuffer *buffer;
152
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
153
+
154
+ return INT2NUM(buffer->limit);
167
155
  }
168
156
 
169
- static VALUE NIO_ByteBuffer_readnext(VALUE self, VALUE amount)
157
+ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit)
170
158
  {
171
- int amnt = NUM2INT(amount);
172
- if(amnt < 1) {
173
- rb_raise(rb_eTypeError, "not a valid input");
159
+ struct NIO_ByteBuffer *buffer;
160
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
161
+
162
+ int lim = NUM2INT(new_limit);
163
+
164
+ if(lim < 0) {
165
+ rb_raise(rb_eArgError, "negative limit given");
174
166
  }
175
167
 
176
- if(amnt > NUM2INT(NIO_ByteBuffer_remaining(self))) {
177
- rb_raise(rb_eTypeError, "Less number of elements remaining");
168
+ if(lim > buffer->capacity) {
169
+ rb_raise(rb_eArgError, "specified limit exceeds capacity");
178
170
  }
179
171
 
180
- char tempArray[amnt+1];
181
- int c = 0;
182
- struct NIO_ByteBuffer *byteBuffer;
183
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
172
+ buffer->limit = lim;
173
+
174
+ if(buffer->position > lim) {
175
+ buffer->position = lim;
176
+ }
184
177
 
185
- while(c < amnt) {
186
- tempArray[c++] = byteBuffer->buffer[byteBuffer->position];
187
- byteBuffer->position++;
178
+ if(buffer->mark > lim) {
179
+ buffer->mark = MARK_UNSET;
188
180
  }
189
181
 
190
- tempArray[amnt] = '\0';
191
- return rb_str_new2(tempArray);
182
+ return new_limit;
192
183
  }
193
184
 
194
- static VALUE NIO_ByteBuffer_writeTo(VALUE self, VALUE io)
185
+ static VALUE NIO_ByteBuffer_capacity(VALUE self)
195
186
  {
196
- struct NIO_ByteBuffer *byteBuffer;
197
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
198
- int size = byteBuffer->limit + 1 - byteBuffer->position;
187
+ struct NIO_ByteBuffer *buffer;
188
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
199
189
 
200
- #if HAVE_RB_IO_T
201
- rb_io_t *fptr;
202
- #else
203
- OpenFile *fptr;
204
- #endif
190
+ return INT2NUM(buffer->capacity);
191
+ }
205
192
 
206
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
207
- rb_io_set_nonblock(fptr);
193
+ static VALUE NIO_ByteBuffer_remaining(VALUE self)
194
+ {
195
+ struct NIO_ByteBuffer *buffer;
196
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
208
197
 
209
- VALUE content = NIO_ByteBuffer_get(self);
210
- char* contentAsPointer = StringValuePtr(content);
198
+ return INT2NUM(buffer->limit - buffer->position);
199
+ }
211
200
 
212
- write(FPTR_TO_FD(fptr), contentAsPointer , size);
201
+ static VALUE NIO_ByteBuffer_full(VALUE self)
202
+ {
203
+ struct NIO_ByteBuffer *buffer;
204
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
213
205
 
214
- return self;
206
+ return buffer->position == buffer->limit ? Qtrue : Qfalse;
215
207
  }
216
208
 
217
- static VALUE NIO_ByteBuffer_readFrom(VALUE self, VALUE io)
209
+ static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self)
218
210
  {
219
- struct NIO_ByteBuffer *byteBuffer;
220
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
221
- int size = byteBuffer->limit + 1 - byteBuffer->position;
211
+ int len;
212
+ VALUE length, result;
213
+ struct NIO_ByteBuffer *buffer;
214
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
222
215
 
223
- #if HAVE_RB_IO_T
224
- rb_io_t *fptr;
225
- #else
226
- OpenFile *fptr;
227
- #endif
216
+ rb_scan_args(argc, argv, "01", &length);
228
217
 
229
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
230
- rb_io_set_nonblock(fptr);
218
+ if(length == Qnil) {
219
+ len = buffer->limit - buffer->position;
220
+ } else {
221
+ len = NUM2INT(length);
222
+ }
231
223
 
232
- while(NIO_ByteBuffer_hasRemaining(self) == Qtrue) {
233
- char* nextByte;
234
- read(FPTR_TO_FD(fptr), &nextByte, 1);
235
- VALUE byte = rb_str_new2(nextByte);
236
- NIO_ByteBuffer_put(self, byte);
224
+ if(len < 0) {
225
+ rb_raise(rb_eArgError, "negative length given");
237
226
  }
238
227
 
239
- return self;
240
- }
228
+ if(len > buffer->limit - buffer->position) {
229
+ rb_raise(cNIO_ByteBuffer_UnderflowError, "not enough data in buffer");
230
+ }
241
231
 
242
- static VALUE NIO_ByteBuffer_remaining(VALUE self)
243
- {
244
- struct NIO_ByteBuffer *byteBuffer;
245
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
232
+ result = rb_str_new(buffer->buffer + buffer->position, len);
233
+ buffer->position += len;
246
234
 
247
- return INT2NUM(byteBuffer->limit + 1 - byteBuffer->position);
235
+ return result;
248
236
  }
249
237
 
250
- static VALUE NIO_ByteBuffer_hasRemaining(VALUE self)
238
+ static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index)
251
239
  {
252
- struct NIO_ByteBuffer *byteBuffer;
253
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
240
+ struct NIO_ByteBuffer *buffer;
241
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
254
242
 
255
- return ((byteBuffer->limit + 1 - byteBuffer->position) > 0) ? Qtrue : Qfalse;
256
- }
243
+ int i = NUM2INT(index);
257
244
 
258
- static VALUE NIO_ByteBuffer_getOffset(VALUE self)
259
- {
260
- struct NIO_ByteBuffer *byteBuffer;
261
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
262
- return INT2NUM(byteBuffer->offset);
263
- }
245
+ if(i < 0) {
246
+ rb_raise(rb_eArgError, "negative index given");
247
+ }
264
248
 
265
- static VALUE NIO_ByteBuffer_equals(VALUE self, VALUE other)
266
- {
267
- return self == other ? Qtrue : Qfalse;
249
+ if(i >= buffer->limit) {
250
+ rb_raise(rb_eArgError, "specified index exceeds limit");
251
+ }
252
+
253
+ return INT2NUM(buffer->buffer[i]);
268
254
  }
269
255
 
270
- static VALUE NIO_ByteBuffer_flip(VALUE self)
256
+ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
271
257
  {
272
- struct NIO_ByteBuffer *byteBuffer;
273
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
258
+ struct NIO_ByteBuffer *buffer;
259
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
260
+
261
+ long length = RSTRING_LEN(string);
262
+
263
+ if(length > buffer->limit - buffer->position) {
264
+ rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
265
+ }
274
266
 
275
- byteBuffer->limit = (byteBuffer->position > 0) ? byteBuffer->position - 1 : 0;
276
- byteBuffer->position = 0;
277
- byteBuffer->mark = -1;
267
+ memcpy(buffer->buffer + buffer->position, StringValuePtr(string), length);
268
+ buffer->position += length;
278
269
 
279
270
  return self;
280
271
  }
281
272
 
282
- static VALUE NIO_ByteBuffer_rewind(VALUE self)
273
+ static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
283
274
  {
284
- struct NIO_ByteBuffer *byteBuffer;
285
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
275
+ struct NIO_ByteBuffer *buffer;
276
+ rb_io_t *fptr;
277
+ ssize_t nbytes, bytes_read;
286
278
 
287
- byteBuffer->position = 0;
288
- byteBuffer->mark = -1;
279
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
280
+ GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
281
+ rb_io_set_nonblock(fptr);
289
282
 
290
- return self;
291
- }
283
+ nbytes = buffer->limit - buffer->position;
284
+ if(nbytes == 0) {
285
+ rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
286
+ }
292
287
 
293
- static VALUE NIO_ByteBuffer_reset(VALUE self)
294
- {
295
- struct NIO_ByteBuffer *byteBuffer;
296
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
288
+ bytes_read = read(FPTR_TO_FD(fptr), buffer->buffer + buffer->position, nbytes);
297
289
 
298
- if(byteBuffer->mark < 0){
299
- rb_raise(rb_eRuntimeError, "Invalid Mark Exception");
300
- } else {
301
- byteBuffer->position = byteBuffer->mark;
290
+ if(bytes_read < 0) {
291
+ if(errno == EAGAIN) {
292
+ return INT2NUM(0);
293
+ } else {
294
+ rb_sys_fail("write");
295
+ }
302
296
  }
303
297
 
304
- return self;
298
+ buffer->position += bytes_read;
299
+
300
+ return INT2NUM(bytes_read);
305
301
  }
306
302
 
307
- static VALUE NIO_ByteBuffer_markBuffer(VALUE self)
303
+ static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io)
308
304
  {
309
- struct NIO_ByteBuffer *byteBuffer;
310
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
305
+ struct NIO_ByteBuffer *buffer;
306
+ rb_io_t *fptr;
307
+ ssize_t nbytes, bytes_written;
311
308
 
312
- byteBuffer->mark = byteBuffer->position;
313
- return self;
309
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
310
+ GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
311
+ rb_io_set_nonblock(fptr);
312
+
313
+ nbytes = buffer->limit - buffer->position;
314
+ if(nbytes == 0) {
315
+ rb_raise(cNIO_ByteBuffer_UnderflowError, "no data remaining in buffer");
316
+ }
317
+
318
+ bytes_written = write(FPTR_TO_FD(fptr), buffer->buffer + buffer->position, nbytes);
319
+
320
+ if(bytes_written < 0) {
321
+ if(errno == EAGAIN) {
322
+ return INT2NUM(0);
323
+ } else {
324
+ rb_sys_fail("write");
325
+ }
326
+ }
327
+
328
+ buffer->position += bytes_written;
329
+
330
+ return INT2NUM(bytes_written);
314
331
  }
315
332
 
316
- static VALUE NIO_ByteBuffer_clear(VALUE self)
333
+ static VALUE NIO_ByteBuffer_flip(VALUE self)
317
334
  {
318
- struct NIO_ByteBuffer *byteBuffer;
319
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
335
+ struct NIO_ByteBuffer *buffer;
336
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
320
337
 
321
- byteBuffer->position = 0;
322
- byteBuffer->limit = byteBuffer->size - 1;
323
- byteBuffer->mark = -1;
338
+ buffer->limit = buffer->position;
339
+ buffer->position = 0;
340
+ buffer->mark = MARK_UNSET;
324
341
 
325
342
  return self;
326
343
  }
327
344
 
328
- static VALUE NIO_ByteBuffer_compact(VALUE self)
345
+ static VALUE NIO_ByteBuffer_rewind(VALUE self)
329
346
  {
330
- struct NIO_ByteBuffer *byteBuffer;
331
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
332
-
333
- if(NIO_ByteBuffer_hasRemaining(self) == Qtrue) {
334
- //move content
335
- int i = 0, j = byteBuffer->position;
336
- for(j = byteBuffer->position; j <= byteBuffer->limit; j++) {
337
- byteBuffer->buffer[i++] = byteBuffer->buffer[j];
338
- }
347
+ struct NIO_ByteBuffer *buffer;
348
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
339
349
 
340
- byteBuffer->position = i;
341
- byteBuffer->limit = byteBuffer->size - 1;
342
- }
350
+ buffer->position = 0;
351
+ buffer->mark = MARK_UNSET;
343
352
 
344
353
  return self;
345
354
  }
346
355
 
347
- static VALUE NIO_ByteBuffer_capacity(VALUE self)
356
+ static VALUE NIO_ByteBuffer_mark(VALUE self)
348
357
  {
349
- struct NIO_ByteBuffer *byteBuffer;
350
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
358
+ struct NIO_ByteBuffer *buffer;
359
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
351
360
 
352
- return INT2NUM(byteBuffer->size);
361
+ buffer->mark = buffer->position;
362
+ return self;
353
363
  }
354
364
 
355
- static VALUE NIO_ByteBuffer_position(VALUE self, VALUE newposition)
365
+ static VALUE NIO_ByteBuffer_reset(VALUE self)
356
366
  {
357
- struct NIO_ByteBuffer *byteBuffer;
358
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
367
+ struct NIO_ByteBuffer *buffer;
368
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
359
369
 
360
- int newPosition = NUM2INT(newposition);
361
-
362
- if(newPosition < 0 || newPosition > byteBuffer->limit) {
363
- rb_raise(rb_eRuntimeError, "Illegal Argument Exception");
370
+ if(buffer->mark < 0) {
371
+ rb_raise(cNIO_ByteBuffer_MarkUnsetError, "mark has not been set");
364
372
  } else {
365
- byteBuffer->position = newPosition;
366
-
367
- if(byteBuffer->mark > newPosition) {
368
- byteBuffer->mark = -1;
369
- }
373
+ buffer->position = buffer->mark;
370
374
  }
375
+
371
376
  return self;
372
377
  }
373
378
 
374
- static VALUE NIO_ByteBuffer_setLimit(VALUE self, VALUE newlimit)
379
+ static VALUE NIO_ByteBuffer_compact(VALUE self)
375
380
  {
376
- struct NIO_ByteBuffer *byteBuffer;
377
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
381
+ struct NIO_ByteBuffer *buffer;
382
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
378
383
 
379
- int newLimit = NUM2INT(newlimit);
384
+ memmove(buffer->buffer, buffer->buffer + buffer->position, buffer->limit - buffer->position);
385
+ buffer->position = buffer->limit - buffer->position;
386
+ buffer->limit = buffer->capacity;
380
387
 
381
- if(newLimit < byteBuffer->size && newLimit >= 0)
382
- {
383
- byteBuffer->limit = newLimit;
388
+ return self;
389
+ }
384
390
 
385
- if(byteBuffer->position > byteBuffer->limit) {
386
- byteBuffer->position = newLimit;
387
- }
391
+ static VALUE NIO_ByteBuffer_each(VALUE self)
392
+ {
393
+ int i;
394
+ struct NIO_ByteBuffer *buffer;
395
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
388
396
 
389
- if(byteBuffer->mark > byteBuffer->limit) {
390
- byteBuffer->mark = -1;
397
+ if(rb_block_given_p()) {
398
+ for(i = 0; i < buffer->limit; i++) {
399
+ rb_yield(INT2NUM(buffer->buffer[i]));
391
400
  }
392
401
  } else {
393
- rb_raise(rb_eRuntimeError, "Illegal Argument Exception");
402
+ rb_raise(rb_eArgError, "no block given");
394
403
  }
395
404
 
396
405
  return self;
397
406
  }
398
407
 
399
- static VALUE NIO_ByteBuffer_getLimit(VALUE self)
408
+ static VALUE NIO_ByteBuffer_inspect(VALUE self)
400
409
  {
401
- struct NIO_ByteBuffer *byteBuffer;
402
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
403
-
404
- return INT2NUM(byteBuffer->limit);
405
- }
406
-
407
- static VALUE NIO_ByteBuffer_toString(VALUE self)
408
- {
409
- struct NIO_ByteBuffer *byteBuffer;
410
- Data_Get_Struct(self, struct NIO_ByteBuffer, byteBuffer);
411
-
412
- return rb_sprintf ("ByteBuffer [pos=%d lim=%d cap=%d]\n", byteBuffer->position, byteBuffer->limit, byteBuffer->size);
410
+ struct NIO_ByteBuffer *buffer;
411
+ Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
412
+
413
+ return rb_sprintf(
414
+ "#<%s:%p @position=%d @limit=%d @capacity=%d>",
415
+ rb_class2name(CLASS_OF(self)),
416
+ (void*)self,
417
+ buffer->position,
418
+ buffer->limit,
419
+ buffer->capacity
420
+ );
413
421
  }