nng 0.1.0 → 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.
@@ -1,217 +1,126 @@
1
- /*
2
- * Copyright (c) 2021 Adib Saad
3
- *
4
- */
5
- #include <nng/nng.h>
6
- #include <ruby.h>
1
+ #include "rbnng.h"
7
2
 
8
- VALUE rbnng_eBase = Qnil;
9
-
10
- VALUE rbnng_eInterrupted = Qnil;
11
- VALUE rbnng_eOutOfMemory = Qnil;
12
- VALUE rbnng_eInvalidArgument = Qnil;
13
- VALUE rbnng_eResourceBusy = Qnil;
14
- VALUE rbnng_eTimedOut = Qnil;
15
- VALUE rbnng_eConnectionRefused = Qnil;
16
- VALUE rbnng_eObjectClosed = Qnil;
17
- VALUE rbnng_eTryAgain = Qnil;
18
- VALUE rbnng_eNotSupported = Qnil;
19
- VALUE rbnng_eAddressInUse = Qnil;
20
- VALUE rbnng_eIncorrectState = Qnil;
21
- VALUE rbnng_eEntryNotFound = Qnil;
22
- VALUE rbnng_eProtocolError = Qnil;
23
- VALUE rbnng_eDestinationUnreachable = Qnil;
24
- VALUE rbnng_eAddressInvalid = Qnil;
25
- VALUE rbnng_ePermissionDenied = Qnil;
26
- VALUE rbnng_eMessageTooLarge = Qnil;
27
- VALUE rbnng_eConnectionReset = Qnil;
28
- VALUE rbnng_eConnectionAborted = Qnil;
29
- VALUE rbnng_eOperationCanceled = Qnil;
30
- VALUE rbnng_eOutOfFiles = Qnil;
31
- VALUE rbnng_eOutOfSpace = Qnil;
32
- VALUE rbnng_eResourceAlreadyExists = Qnil;
33
- VALUE rbnng_eReadOnlyResource = Qnil;
34
- VALUE rbnng_eWriteOnlyResource = Qnil;
35
- VALUE rbnng_eCryptographicError = Qnil;
36
- VALUE rbnng_ePeerCouldNotBeAuthenticated = Qnil;
37
- VALUE rbnng_eOptionRequiresArgument = Qnil;
38
- VALUE rbnng_eAmbiguousOption = Qnil;
39
- VALUE rbnng_eIncorrectType = Qnil;
40
- VALUE rbnng_eConnectionShutdown = Qnil;
41
- VALUE rbnng_eInternalErrorDetected = Qnil;
3
+ static VALUE eBase;
4
+ static VALUE eInterrupted;
5
+ static VALUE eOutOfMemory;
6
+ static VALUE eInvalidArgument;
7
+ static VALUE eResourceBusy;
8
+ static VALUE eTimedOut;
9
+ static VALUE eConnectionRefused;
10
+ static VALUE eObjectClosed;
11
+ static VALUE eTryAgain;
12
+ static VALUE eNotSupported;
13
+ static VALUE eAddressInUse;
14
+ static VALUE eIncorrectState;
15
+ static VALUE eEntryNotFound;
16
+ static VALUE eProtocolError;
17
+ static VALUE eDestinationUnreachable;
18
+ static VALUE eAddressInvalid;
19
+ static VALUE ePermissionDenied;
20
+ static VALUE eMessageTooLarge;
21
+ static VALUE eConnectionAborted;
22
+ static VALUE eConnectionReset;
23
+ static VALUE eOperationCanceled;
24
+ static VALUE eOutOfFiles;
25
+ static VALUE eOutOfSpace;
26
+ static VALUE eResourceAlreadyExists;
27
+ static VALUE eReadOnlyResource;
28
+ static VALUE eWriteOnlyResource;
29
+ static VALUE eCryptographicError;
30
+ static VALUE ePeerCouldNotBeAuthenticated;
31
+ static VALUE eOptionRequiresArgument;
32
+ static VALUE eAmbiguousOption;
33
+ static VALUE eIncorrectType;
34
+ static VALUE eConnectionShutdown;
35
+ static VALUE eInternalErrorDetected;
42
36
 
43
37
  void
44
- rbnng_exceptions_Init(VALUE nng_module)
38
+ raise_nng_error(int rv)
45
39
  {
46
- VALUE errorModule = rb_define_module_under(nng_module, "Error");
47
- rbnng_eBase = rb_define_class_under(errorModule, "Error", rb_eRuntimeError);
40
+ const char *msg = nng_strerror(rv);
41
+ VALUE cls;
42
+
43
+ switch (rv) {
44
+ case NNG_EINTR: cls = eInterrupted; break;
45
+ case NNG_ENOMEM: cls = eOutOfMemory; break;
46
+ case NNG_EINVAL: cls = eInvalidArgument; break;
47
+ case NNG_EBUSY: cls = eResourceBusy; break;
48
+ case NNG_ETIMEDOUT: cls = eTimedOut; break;
49
+ case NNG_ECONNREFUSED: cls = eConnectionRefused; break;
50
+ case NNG_ECLOSED: cls = eObjectClosed; break;
51
+ case NNG_EAGAIN: cls = eTryAgain; break;
52
+ case NNG_ENOTSUP: cls = eNotSupported; break;
53
+ case NNG_EADDRINUSE: cls = eAddressInUse; break;
54
+ case NNG_ESTATE: cls = eIncorrectState; break;
55
+ case NNG_ENOENT: cls = eEntryNotFound; break;
56
+ case NNG_EPROTO: cls = eProtocolError; break;
57
+ case NNG_EUNREACHABLE: cls = eDestinationUnreachable; break;
58
+ case NNG_EADDRINVAL: cls = eAddressInvalid; break;
59
+ case NNG_EPERM: cls = ePermissionDenied; break;
60
+ case NNG_EMSGSIZE: cls = eMessageTooLarge; break;
61
+ case NNG_ECONNABORTED: cls = eConnectionAborted; break;
62
+ case NNG_ECONNRESET: cls = eConnectionReset; break;
63
+ case NNG_ECANCELED: cls = eOperationCanceled; break;
64
+ case NNG_ENOFILES: cls = eOutOfFiles; break;
65
+ case NNG_ENOSPC: cls = eOutOfSpace; break;
66
+ case NNG_EEXIST: cls = eResourceAlreadyExists; break;
67
+ case NNG_EREADONLY: cls = eReadOnlyResource; break;
68
+ case NNG_EWRITEONLY: cls = eWriteOnlyResource; break;
69
+ case NNG_ECRYPTO: cls = eCryptographicError; break;
70
+ case NNG_EPEERAUTH: cls = ePeerCouldNotBeAuthenticated; break;
71
+ case NNG_ENOARG: cls = eOptionRequiresArgument; break;
72
+ case NNG_EAMBIGUOUS: cls = eAmbiguousOption; break;
73
+ case NNG_EBADTYPE: cls = eIncorrectType; break;
74
+ case NNG_ECONNSHUT: cls = eConnectionShutdown; break;
75
+ case NNG_EINTERNAL: cls = eInternalErrorDetected; break;
76
+ default: cls = eBase; break;
77
+ }
48
78
 
49
- rbnng_eInterrupted =
50
- rb_define_class_under(errorModule, "Interrupted", rbnng_eBase);
51
- rbnng_eOutOfMemory =
52
- rb_define_class_under(errorModule, "OutOfMemory", rbnng_eBase);
53
- rbnng_eInvalidArgument =
54
- rb_define_class_under(errorModule, "InvalidArgument", rbnng_eBase);
55
- rbnng_eResourceBusy =
56
- rb_define_class_under(errorModule, "ResourceBusy", rbnng_eBase);
57
- rbnng_eTimedOut = rb_define_class_under(errorModule, "TimedOut", rbnng_eBase);
58
- rbnng_eConnectionRefused =
59
- rb_define_class_under(errorModule, "ConnectionRefused", rbnng_eBase);
60
- rbnng_eObjectClosed =
61
- rb_define_class_under(errorModule, "ObjectClosed", rbnng_eBase);
62
- rbnng_eTryAgain = rb_define_class_under(errorModule, "TryAgain", rbnng_eBase);
63
- rbnng_eNotSupported =
64
- rb_define_class_under(errorModule, "NotSupported", rbnng_eBase);
65
- rbnng_eAddressInUse =
66
- rb_define_class_under(errorModule, "AddressInUse", rbnng_eBase);
67
- rbnng_eIncorrectState =
68
- rb_define_class_under(errorModule, "IncorrectState", rbnng_eBase);
69
- rbnng_eEntryNotFound =
70
- rb_define_class_under(errorModule, "EntryNotFound", rbnng_eBase);
71
- rbnng_eProtocolError =
72
- rb_define_class_under(errorModule, "ProtocolError", rbnng_eBase);
73
- rbnng_eDestinationUnreachable =
74
- rb_define_class_under(errorModule, "DestinationUnreachable", rbnng_eBase);
75
- rbnng_eAddressInvalid =
76
- rb_define_class_under(errorModule, "AddressInvalid", rbnng_eBase);
77
- rbnng_ePermissionDenied =
78
- rb_define_class_under(errorModule, "PermissionDenied", rbnng_eBase);
79
- rbnng_eMessageTooLarge =
80
- rb_define_class_under(errorModule, "MessageTooLarge", rbnng_eBase);
81
- rbnng_eConnectionReset =
82
- rb_define_class_under(errorModule, "ConnectionReset", rbnng_eBase);
83
- rbnng_eConnectionAborted =
84
- rb_define_class_under(errorModule, "ConnectionAborted", rbnng_eBase);
85
- rbnng_eOperationCanceled =
86
- rb_define_class_under(errorModule, "OperationCanceled", rbnng_eBase);
87
- rbnng_eOutOfFiles =
88
- rb_define_class_under(errorModule, "OutOfFiles", rbnng_eBase);
89
- rbnng_eOutOfSpace =
90
- rb_define_class_under(errorModule, "OutOfSpace", rbnng_eBase);
91
- rbnng_eResourceAlreadyExists =
92
- rb_define_class_under(errorModule, "ResourceAlreadyExists", rbnng_eBase);
93
- rbnng_eReadOnlyResource =
94
- rb_define_class_under(errorModule, "ReadOnlyResource", rbnng_eBase);
95
- rbnng_eWriteOnlyResource =
96
- rb_define_class_under(errorModule, "WriteOnlyResource", rbnng_eBase);
97
- rbnng_eCryptographicError =
98
- rb_define_class_under(errorModule, "CryptographicError", rbnng_eBase);
99
- rbnng_ePeerCouldNotBeAuthenticated = rb_define_class_under(
100
- errorModule, "PeerCouldNotBeAuthenticated", rbnng_eBase);
101
- rbnng_eOptionRequiresArgument =
102
- rb_define_class_under(errorModule, "OptionRequiresArgument", rbnng_eBase);
103
- rbnng_eAmbiguousOption =
104
- rb_define_class_under(errorModule, "AmbiguousOption", rbnng_eBase);
105
- rbnng_eIncorrectType =
106
- rb_define_class_under(errorModule, "IncorrectType", rbnng_eBase);
107
- rbnng_eConnectionShutdown =
108
- rb_define_class_under(errorModule, "ConnectionShutdown", rbnng_eBase);
109
- rbnng_eInternalErrorDetected =
110
- rb_define_class_under(errorModule, "InternalErrorDetected", rbnng_eBase);
79
+ rb_raise(cls, "%s", msg);
111
80
  }
112
81
 
82
+ #define DEF_ERR(var, mod, name) \
83
+ var = rb_define_class_under(mod, name, eBase); \
84
+ rb_gc_register_mark_object(var)
85
+
113
86
  void
114
- raise_error(int nng_errno)
87
+ rbnng_exceptions_init(VALUE nng_module)
115
88
  {
116
- switch (nng_errno) {
117
- case NNG_EINTR:
118
- rb_raise(rbnng_eInterrupted, "");
119
- break;
120
- case NNG_ENOMEM:
121
- rb_raise(rbnng_eOutOfMemory, "");
122
- break;
123
- case NNG_EINVAL:
124
- rb_raise(rbnng_eInvalidArgument, "");
125
- break;
126
- case NNG_EBUSY:
127
- rb_raise(rbnng_eResourceBusy, "");
128
- break;
129
- case NNG_ETIMEDOUT:
130
- rb_raise(rbnng_eTimedOut, "");
131
- break;
132
- case NNG_ECONNREFUSED:
133
- rb_raise(rbnng_eConnectionRefused, "");
134
- break;
135
- case NNG_ECLOSED:
136
- rb_raise(rbnng_eObjectClosed, "");
137
- break;
138
- case NNG_EAGAIN:
139
- rb_raise(rbnng_eTryAgain, "");
140
- break;
141
- case NNG_ENOTSUP:
142
- rb_raise(rbnng_eNotSupported, "");
143
- break;
144
- case NNG_EADDRINUSE:
145
- rb_raise(rbnng_eAddressInUse, "");
146
- break;
147
- case NNG_ESTATE:
148
- rb_raise(rbnng_eIncorrectState, "");
149
- break;
150
- case NNG_ENOENT:
151
- rb_raise(rbnng_eEntryNotFound, "");
152
- break;
153
- case NNG_EPROTO:
154
- rb_raise(rbnng_eProtocolError, "");
155
- break;
156
- case NNG_EUNREACHABLE:
157
- rb_raise(rbnng_eDestinationUnreachable, "");
158
- break;
159
- case NNG_EADDRINVAL:
160
- rb_raise(rbnng_eAddressInvalid, "");
161
- break;
162
- case NNG_EPERM:
163
- rb_raise(rbnng_ePermissionDenied, "");
164
- break;
165
- case NNG_EMSGSIZE:
166
- rb_raise(rbnng_eMessageTooLarge, "");
167
- break;
168
- case NNG_ECONNRESET:
169
- rb_raise(rbnng_eConnectionReset, "");
170
- break;
171
- case NNG_ECONNABORTED:
172
- rb_raise(rbnng_eConnectionAborted, "");
173
- break;
174
- case NNG_ECANCELED:
175
- rb_raise(rbnng_eOperationCanceled, "");
176
- break;
177
- case NNG_ENOFILES:
178
- rb_raise(rbnng_eOutOfFiles, "");
179
- break;
180
- case NNG_ENOSPC:
181
- rb_raise(rbnng_eOutOfSpace, "");
182
- break;
183
- case NNG_EEXIST:
184
- rb_raise(rbnng_eResourceAlreadyExists, "");
185
- break;
186
- case NNG_EREADONLY:
187
- rb_raise(rbnng_eReadOnlyResource, "");
188
- break;
189
- case NNG_EWRITEONLY:
190
- rb_raise(rbnng_eWriteOnlyResource, "");
191
- break;
192
- case NNG_ECRYPTO:
193
- rb_raise(rbnng_eCryptographicError, "");
194
- break;
195
- case NNG_EPEERAUTH:
196
- rb_raise(rbnng_ePeerCouldNotBeAuthenticated, "");
197
- break;
198
- case NNG_ENOARG:
199
- rb_raise(rbnng_eOptionRequiresArgument, "");
200
- break;
201
- case NNG_EAMBIGUOUS:
202
- rb_raise(rbnng_eAmbiguousOption, "");
203
- break;
204
- case NNG_EBADTYPE:
205
- rb_raise(rbnng_eIncorrectType, "");
206
- break;
207
- case NNG_ECONNSHUT:
208
- rb_raise(rbnng_eConnectionShutdown, "");
209
- break;
210
- case NNG_EINTERNAL:
211
- rb_raise(rbnng_eInternalErrorDetected, "");
212
- break;
213
- default:
214
- rb_raise(rbnng_eBase, "errno %d, %s", nng_errno, nng_strerror(nng_errno));
215
- break;
216
- }
89
+ eBase = rb_define_class_under(nng_module, "Error", rb_eRuntimeError);
90
+ rb_gc_register_mark_object(eBase);
91
+
92
+ VALUE m = eBase;
93
+
94
+ DEF_ERR(eInterrupted, m, "Interrupted");
95
+ DEF_ERR(eOutOfMemory, m, "OutOfMemory");
96
+ DEF_ERR(eInvalidArgument, m, "InvalidArgument");
97
+ DEF_ERR(eResourceBusy, m, "ResourceBusy");
98
+ DEF_ERR(eTimedOut, m, "TimedOut");
99
+ DEF_ERR(eConnectionRefused, m, "ConnectionRefused");
100
+ DEF_ERR(eObjectClosed, m, "ObjectClosed");
101
+ DEF_ERR(eTryAgain, m, "TryAgain");
102
+ DEF_ERR(eNotSupported, m, "NotSupported");
103
+ DEF_ERR(eAddressInUse, m, "AddressInUse");
104
+ DEF_ERR(eIncorrectState, m, "IncorrectState");
105
+ DEF_ERR(eEntryNotFound, m, "EntryNotFound");
106
+ DEF_ERR(eProtocolError, m, "ProtocolError");
107
+ DEF_ERR(eDestinationUnreachable, m, "DestinationUnreachable");
108
+ DEF_ERR(eAddressInvalid, m, "AddressInvalid");
109
+ DEF_ERR(ePermissionDenied, m, "PermissionDenied");
110
+ DEF_ERR(eMessageTooLarge, m, "MessageTooLarge");
111
+ DEF_ERR(eConnectionAborted, m, "ConnectionAborted");
112
+ DEF_ERR(eConnectionReset, m, "ConnectionReset");
113
+ DEF_ERR(eOperationCanceled, m, "OperationCanceled");
114
+ DEF_ERR(eOutOfFiles, m, "OutOfFiles");
115
+ DEF_ERR(eOutOfSpace, m, "OutOfSpace");
116
+ DEF_ERR(eResourceAlreadyExists, m, "ResourceAlreadyExists");
117
+ DEF_ERR(eReadOnlyResource, m, "ReadOnlyResource");
118
+ DEF_ERR(eWriteOnlyResource, m, "WriteOnlyResource");
119
+ DEF_ERR(eCryptographicError, m, "CryptographicError");
120
+ DEF_ERR(ePeerCouldNotBeAuthenticated,m, "PeerCouldNotBeAuthenticated");
121
+ DEF_ERR(eOptionRequiresArgument, m, "OptionRequiresArgument");
122
+ DEF_ERR(eAmbiguousOption, m, "AmbiguousOption");
123
+ DEF_ERR(eIncorrectType, m, "IncorrectType");
124
+ DEF_ERR(eConnectionShutdown, m, "ConnectionShutdown");
125
+ DEF_ERR(eInternalErrorDetected, m, "InternalErrorDetected");
217
126
  }
data/ext/rbnng/extconf.rb CHANGED
@@ -1,21 +1,8 @@
1
- #
2
- # Copyright (c) 2021 Adib Saad
3
- #
4
- require 'mkmf'
5
- dir_config('nng')
1
+ require "mkmf"
6
2
 
7
- def header?
8
- have_header('nng/nng.h') ||
9
- find_header('nng/nng.h', '/opt/local/include', '/usr/local/include', '/usr/include')
10
- end
3
+ pkg_config("libnng") || dir_config("nng")
4
+ have_library("nng", "nng_version") || abort("libnng not found")
5
+ have_header("nng/nng.h") || abort("nng/nng.h not found")
6
+ have_header("nng/supplemental/tls/tls.h")
11
7
 
12
- def library?
13
- have_library('nng', 'nng_fini') ||
14
- find_library('nng', 'nng_fini', '/opt/local/lib', '/usr/local/lib', '/usr/lib')
15
- end
16
-
17
- if header? && library?
18
- create_makefile("nng/rbnng")
19
- else
20
- raise "Couldn't find nng library. try setting --with-nng-dir=<path> to tell me where it is."
21
- end
8
+ create_makefile("nng/rbnng")
@@ -0,0 +1,183 @@
1
+ #include "rbnng.h"
2
+
3
+ #define HEADER_ELEMENT_SIZE 4
4
+
5
+ VALUE cMessage = Qnil;
6
+
7
+ /* ── TypedData ──────────────────────────────────────────────────── */
8
+
9
+ static void
10
+ msg_free(void *ptr)
11
+ {
12
+ rbnng_msg_t *m = ptr;
13
+ if (m->msg)
14
+ nng_msg_free(m->msg);
15
+ xfree(m);
16
+ }
17
+
18
+ static size_t
19
+ msg_memsize(const void *ptr)
20
+ {
21
+ return sizeof(rbnng_msg_t);
22
+ }
23
+
24
+ const rb_data_type_t rbnng_msg_type = {
25
+ .wrap_struct_name = "NNG::Message",
26
+ .function = {
27
+ .dmark = NULL,
28
+ .dfree = msg_free,
29
+ .dsize = msg_memsize,
30
+ },
31
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
32
+ };
33
+
34
+ static VALUE
35
+ msg_alloc(VALUE klass)
36
+ {
37
+ rbnng_msg_t *m;
38
+ return TypedData_Make_Struct(klass, rbnng_msg_t, &rbnng_msg_type, m);
39
+ }
40
+
41
+ VALUE
42
+ rbnng_msg_wrap(nng_msg *msg)
43
+ {
44
+ VALUE obj = msg_alloc(cMessage);
45
+ rbnng_msg_t *m;
46
+ TypedData_Get_Struct(obj, rbnng_msg_t, &rbnng_msg_type, m);
47
+ m->msg = msg;
48
+ return obj;
49
+ }
50
+
51
+ static inline rbnng_msg_t *
52
+ msg_get(VALUE self)
53
+ {
54
+ rbnng_msg_t *m;
55
+ TypedData_Get_Struct(self, rbnng_msg_t, &rbnng_msg_type, m);
56
+ return m;
57
+ }
58
+
59
+ static inline nng_msg *
60
+ msg_ptr(VALUE self)
61
+ {
62
+ rbnng_msg_t *m = msg_get(self);
63
+ if (!m->msg)
64
+ rb_raise(rb_eRuntimeError, "message already consumed");
65
+ return m->msg;
66
+ }
67
+
68
+ /* ── Methods ────────────────────────────────────────────────────── */
69
+
70
+ static VALUE
71
+ msg_body(VALUE self)
72
+ {
73
+ nng_msg *p = msg_ptr(self);
74
+ return rb_str_new(nng_msg_body(p), nng_msg_len(p));
75
+ }
76
+
77
+ static VALUE
78
+ msg_body_clear(VALUE self)
79
+ {
80
+ nng_msg_clear(msg_ptr(self));
81
+ return Qnil;
82
+ }
83
+
84
+ static VALUE
85
+ msg_body_append(VALUE self, VALUE data)
86
+ {
87
+ nng_msg *p = msg_ptr(self);
88
+ int rv = nng_msg_append(p, RSTRING_PTR(data), RSTRING_LEN(data));
89
+ if (rv != 0)
90
+ raise_nng_error(rv);
91
+ return Qnil;
92
+ }
93
+
94
+ static VALUE
95
+ msg_header(VALUE self)
96
+ {
97
+ nng_msg *p = msg_ptr(self);
98
+ const char *data = nng_msg_header(p);
99
+ size_t len = nng_msg_header_len(p);
100
+ size_t count = len / HEADER_ELEMENT_SIZE;
101
+
102
+ VALUE ary = rb_ary_new_capa((long)count);
103
+ for (size_t i = 0; i < count; i++)
104
+ rb_ary_push(ary, rb_str_new(data + i * HEADER_ELEMENT_SIZE,
105
+ HEADER_ELEMENT_SIZE));
106
+ return ary;
107
+ }
108
+
109
+ static VALUE
110
+ msg_set_header(VALUE self, VALUE elements)
111
+ {
112
+ nng_msg *p = msg_ptr(self);
113
+ Check_Type(elements, T_ARRAY);
114
+
115
+ long count = RARRAY_LEN(elements);
116
+
117
+ /* Validate all elements first */
118
+ for (long i = 0; i < count; i++) {
119
+ VALUE el = rb_ary_entry(elements, i);
120
+ StringValue(el);
121
+ if (RSTRING_LEN(el) != HEADER_ELEMENT_SIZE)
122
+ rb_raise(rb_eArgError,
123
+ "header element must be exactly %d bytes, got %ld",
124
+ HEADER_ELEMENT_SIZE, RSTRING_LEN(el));
125
+ }
126
+
127
+ /* Clear and write */
128
+ nng_msg_header_clear(p);
129
+ for (long i = 0; i < count; i++) {
130
+ VALUE el = rb_ary_entry(elements, i);
131
+ int rv = nng_msg_header_append(p, RSTRING_PTR(el), RSTRING_LEN(el));
132
+ if (rv != 0)
133
+ raise_nng_error(rv);
134
+ }
135
+
136
+ return elements;
137
+ }
138
+
139
+ static VALUE
140
+ msg_dup(VALUE self)
141
+ {
142
+ nng_msg *p = msg_ptr(self);
143
+ nng_msg *copy;
144
+ int rv = nng_msg_dup(&copy, p);
145
+ if (rv != 0)
146
+ raise_nng_error(rv);
147
+ return rbnng_msg_wrap(copy);
148
+ }
149
+
150
+ static VALUE
151
+ msg_consumed_p(VALUE self)
152
+ {
153
+ rbnng_msg_t *m = msg_get(self);
154
+ return m->msg ? Qfalse : Qtrue;
155
+ }
156
+
157
+ static VALUE
158
+ msg_pipe(VALUE self)
159
+ {
160
+ nng_pipe p = nng_msg_get_pipe(msg_ptr(self));
161
+ if (nng_pipe_id(p) < 0)
162
+ return Qnil;
163
+ return rbnng_pipe_wrap(p);
164
+ }
165
+
166
+ /* ── Init ───────────────────────────────────────────────────────── */
167
+
168
+ void
169
+ rbnng_msg_init(VALUE nng_module)
170
+ {
171
+ cMessage = rb_define_class_under(nng_module, "Message", rb_cObject);
172
+ rb_define_alloc_func(cMessage, msg_alloc);
173
+
174
+ rb_define_method(cMessage, "body", msg_body, 0);
175
+ rb_define_method(cMessage, "to_s", msg_body, 0);
176
+ rb_define_method(cMessage, "body_clear", msg_body_clear, 0);
177
+ rb_define_method(cMessage, "body_append", msg_body_append, 1);
178
+ rb_define_method(cMessage, "header", msg_header, 0);
179
+ rb_define_method(cMessage, "header=", msg_set_header, 1);
180
+ rb_define_method(cMessage, "dup", msg_dup, 0);
181
+ rb_define_method(cMessage, "consumed?", msg_consumed_p, 0);
182
+ rb_define_method(cMessage, "pipe", msg_pipe, 0);
183
+ }
data/ext/rbnng/pipe.c ADDED
@@ -0,0 +1,81 @@
1
+ #include "rbnng.h"
2
+
3
+ VALUE cPipe = Qnil;
4
+
5
+ /* ── TypedData ──────────────────────────────────────────────────── */
6
+
7
+ static size_t
8
+ pipe_memsize(const void *ptr)
9
+ {
10
+ return sizeof(rbnng_pipe_t);
11
+ }
12
+
13
+ const rb_data_type_t rbnng_pipe_type = {
14
+ .wrap_struct_name = "NNG::Pipe",
15
+ .function = {
16
+ .dmark = NULL,
17
+ .dfree = RUBY_DEFAULT_FREE,
18
+ .dsize = pipe_memsize,
19
+ },
20
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
21
+ };
22
+
23
+ VALUE
24
+ rbnng_pipe_wrap(nng_pipe pipe)
25
+ {
26
+ rbnng_pipe_t *p;
27
+ VALUE obj = TypedData_Make_Struct(cPipe, rbnng_pipe_t, &rbnng_pipe_type, p);
28
+ p->pipe = pipe;
29
+ return obj;
30
+ }
31
+
32
+ static inline nng_pipe
33
+ pipe_get(VALUE self)
34
+ {
35
+ rbnng_pipe_t *p;
36
+ TypedData_Get_Struct(self, rbnng_pipe_t, &rbnng_pipe_type, p);
37
+ return p->pipe;
38
+ }
39
+
40
+ /* ── Methods ────────────────────────────────────────────────────── */
41
+
42
+ static VALUE
43
+ pipe_id(VALUE self)
44
+ {
45
+ return INT2NUM(nng_pipe_id(pipe_get(self)));
46
+ }
47
+
48
+ static VALUE
49
+ pipe_tls_verified_p(VALUE self)
50
+ {
51
+ bool val;
52
+ int rv = nng_pipe_get_bool(pipe_get(self), NNG_OPT_TLS_VERIFIED, &val);
53
+ if (rv != 0)
54
+ return Qfalse;
55
+ return val ? Qtrue : Qfalse;
56
+ }
57
+
58
+ static VALUE
59
+ pipe_tls_peer_cn(VALUE self)
60
+ {
61
+ char *val;
62
+ int rv = nng_pipe_get_string(pipe_get(self), NNG_OPT_TLS_PEER_CN, &val);
63
+ if (rv != 0)
64
+ return Qnil;
65
+ VALUE str = rb_str_new_cstr(val);
66
+ nng_strfree(val);
67
+ return str;
68
+ }
69
+
70
+ /* ── Init ───────────────────────────────────────────────────────── */
71
+
72
+ void
73
+ rbnng_pipe_init(VALUE nng_module)
74
+ {
75
+ cPipe = rb_define_class_under(nng_module, "Pipe", rb_cObject);
76
+ rb_undef_alloc_func(cPipe);
77
+
78
+ rb_define_method(cPipe, "id", pipe_id, 0);
79
+ rb_define_method(cPipe, "tls_verified?", pipe_tls_verified_p, 0);
80
+ rb_define_method(cPipe, "tls_peer_cn", pipe_tls_peer_cn, 0);
81
+ }
data/ext/rbnng/rbnng.c CHANGED
@@ -1,38 +1,24 @@
1
- /*
2
- * Copyright (c) 2021 Adib Saad
3
- *
4
- */
5
- #include <nng/nng.h>
6
- #include <ruby.h>
7
-
8
- #include "msg.h"
9
1
  #include "rbnng.h"
10
- #include "socket.h"
11
2
 
12
3
  static VALUE
13
- library_version(VALUE self_)
4
+ library_version(VALUE self)
14
5
  {
15
- return rb_ary_new3(3,
16
- INT2NUM(NNG_MAJOR_VERSION),
17
- INT2NUM(NNG_MINOR_VERSION),
18
- INT2NUM(NNG_PATCH_VERSION));
6
+ return rb_ary_new3(3,
7
+ INT2NUM(NNG_MAJOR_VERSION),
8
+ INT2NUM(NNG_MINOR_VERSION),
9
+ INT2NUM(NNG_PATCH_VERSION));
19
10
  }
20
11
 
21
12
  void
22
- Init_rbnng()
13
+ Init_rbnng(void)
23
14
  {
24
- VALUE nng_module = rb_define_module("NNG");
25
- rb_define_singleton_method(nng_module, "nng_version", library_version, 0);
26
- rbnng_exceptions_Init(nng_module);
27
- rbnng_msg_Init(nng_module);
28
- rbnng_rep0_Init(nng_module);
29
- rbnng_req0_Init(nng_module);
30
- rbnng_pub0_Init(nng_module);
31
- rbnng_sub0_Init(nng_module);
32
- rbnng_pair_Init(nng_module);
33
- rbnng_bus0_Init(nng_module);
34
- rbnng_surveyor0_Init(nng_module);
35
- rbnng_respondent0_Init(nng_module);
36
- rbnng_push0_Init(nng_module);
37
- rbnng_pull0_Init(nng_module);
15
+ VALUE nng = rb_define_module("NNG");
16
+ rb_define_singleton_method(nng, "nng_version", library_version, 0);
17
+
18
+ rbnng_exceptions_init(nng);
19
+ rbnng_msg_init(nng);
20
+ rbnng_pipe_init(nng);
21
+ rbnng_socket_init(nng);
22
+ rbnng_stats_init(nng);
23
+ rbnng_device_init(nng);
38
24
  }