Skip to content

Commit 120c517

Browse files
committed
more robust code
1 parent c270c7f commit 120c517

File tree

8 files changed

+52
-50
lines changed

8 files changed

+52
-50
lines changed

.github/workflows/test-coverage.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
33
on:
44
push:
5-
branches: [main, master]
5+
branches: [main]
66
pull_request:
7-
branches: [main, master]
7+
branches: [main]
88

99
name: test-coverage
1010

R/sendrecv.R

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ recv.nanoSocket <- function(con,
222222

223223
mode <- match.arg2(mode, c("serial", "character", "complex", "double",
224224
"integer", "logical", "numeric", "raw"))
225-
keep.raw <- missing(keep.raw) || isTRUE(keep.raw)
226225
.Call(rnng_recv, con, mode, block, keep.raw)
227226

228227
}
@@ -241,7 +240,6 @@ recv.nanoContext <- function(con,
241240
mode <- match.arg2(mode, c("serial", "character", "complex", "double",
242241
"integer", "logical", "numeric", "raw"))
243242
if (missing(block) || isTRUE(block)) block <- -2L
244-
keep.raw <- missing(keep.raw) || isTRUE(keep.raw)
245243
.Call(rnng_ctx_recv, con, mode, block, keep.raw)
246244

247245
}
@@ -261,7 +259,6 @@ recv.nanoStream <- function(con,
261259
mode <- match.arg2(mode, c("character", "complex", "double", "integer",
262260
"logical", "numeric", "raw")) + 1L
263261
if (missing(block) || isTRUE(block)) block <- -2L
264-
keep.raw <- missing(keep.raw) || isTRUE(keep.raw)
265262
.Call(rnng_stream_recv, con, mode, block, keep.raw, n)
266263

267264
}

README.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,9 @@ In this respect, it may be used as a performant and lightweight method for makin
437437

438438
```{r stream}
439439
440-
s <- stream(dial = "wss://socketsbay.com/wss/v2/2/demo/", textframes = TRUE)
440+
s <- stream(dial = "wss://demo.piesocket.com/v3/channel_1", textframes = TRUE)
441441
s
442-
s |> send("hello world")
442+
s |> recv(keep.raw = FALSE)
443443
444444
```
445445

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ aio
379379
#> < recvAio >
380380
#> - $data for message data
381381
aio$data |> str()
382-
#> num [1:100000000] -0.597 -0.351 -0.984 1.93 1.393 ...
382+
#> num [1:100000000] -0.0183 0.9349 -0.8196 0.0607 -0.1335 ...
383383
```
384384

385385
As `call_aio()` is blocking and will wait for completion, an alternative
@@ -516,11 +516,11 @@ ncurl("http://httpbin.org/headers")
516516
#> [1] 7b 0a 20 20 22 68 65 61 64 65 72 73 22 3a 20 7b 0a 20 20 20 20 22 48 6f 73
517517
#> [26] 74 22 3a 20 22 68 74 74 70 62 69 6e 2e 6f 72 67 22 2c 20 0a 20 20 20 20 22
518518
#> [51] 58 2d 41 6d 7a 6e 2d 54 72 61 63 65 2d 49 64 22 3a 20 22 52 6f 6f 74 3d 31
519-
#> [76] 2d 36 32 36 35 31 34 37 38 2d 31 38 64 62 65 31 36 38 34 32 62 63 62 36 62
520-
#> [101] 63 33 30 36 61 37 61 63 33 22 0a 20 20 7d 0a 7d 0a
519+
#> [76] 2d 36 32 36 35 39 30 34 32 2d 34 38 34 35 64 63 30 36 36 32 66 30 63 38 66
520+
#> [101] 30 32 31 33 63 35 63 63 32 22 0a 20 20 7d 0a 7d 0a
521521
#>
522522
#> $data
523-
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62651478-18dbe16842bcb6bc306a7ac3\"\n }\n}\n"
523+
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62659042-4845dc0662f0c8f0213c5cc2\"\n }\n}\n"
524524
```
525525

526526
For advanced use, supports additional HTTP methods such as POST or PUT.
@@ -535,7 +535,7 @@ res
535535
#> - $raw for raw message
536536

537537
call_aio(res)$data
538-
#> [1] "{\n \"args\": {}, \n \"data\": \"{\\\"key\\\": \\\"value\\\"}\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Authorization\": \"Bearer APIKEY\", \n \"Content-Length\": \"16\", \n \"Content-Type\": \"application/json\", \n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62651478-224f907c244b4b5053cfdac3\"\n }, \n \"json\": {\n \"key\": \"value\"\n }, \n \"origin\": \"78.145.225.121\", \n \"url\": \"http://httpbin.org/post\"\n}\n"
538+
#> [1] "{\n \"args\": {}, \n \"data\": \"{\\\"key\\\": \\\"value\\\"}\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Authorization\": \"Bearer APIKEY\", \n \"Content-Length\": \"16\", \n \"Content-Type\": \"application/json\", \n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62659042-7ab689205d5bd45b62c030da\"\n }, \n \"json\": {\n \"key\": \"value\"\n }, \n \"origin\": \"78.145.225.121\", \n \"url\": \"http://httpbin.org/post\"\n}\n"
539539
```
540540

541541
In this respect, it may be used as a performant and lightweight method
@@ -550,14 +550,14 @@ communicating with raw sockets. This may be used for connecting to
550550
arbitrary non-NNG endpoints.
551551

552552
``` r
553-
s <- stream(dial = "wss://socketsbay.com/wss/v2/2/demo/", textframes = TRUE)
553+
s <- stream(dial = "wss://demo.piesocket.com/v3/channel_1", textframes = TRUE)
554554
s
555555
#> < nanoStream >
556556
#> - type: dialer
557-
#> - url: wss://socketsbay.com/wss/v2/2/demo/
557+
#> - url: wss://demo.piesocket.com/v3/channel_1
558558
#> - textframes: TRUE
559-
s |> send("hello world")
560-
#> [1] 68 65 6c 6c 6f 20 77 6f 72 6c 64 00
559+
s |> recv(keep.raw = FALSE)
560+
#> [1] "{\"error\":\"Missing apiKey\"}"
561561
```
562562

563563
The stream interface can be used to communicate with websocket servers.

src/aio.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ SEXP rnng_aio_get_msg(SEXP aio, SEXP mode, SEXP keep) {
181181
return mk_error(res);
182182

183183
const int mod = *INTEGER(mode), kpr = *LOGICAL(keep);
184-
unsigned char *buf = nng_msg_body(raio->data);
184+
unsigned char *buf = (unsigned char *) nng_msg_body(raio->data);
185185
size_t sz = nng_msg_len(raio->data);
186186

187187
return nano_decode(buf, sz, mod, kpr);
@@ -210,7 +210,7 @@ SEXP rnng_aio_stream_in(SEXP aio, SEXP mode, SEXP keep) {
210210

211211
const int mod = *INTEGER(mode), kpr = *LOGICAL(keep);
212212
nng_iov *iov = (nng_iov *) iaio->data;
213-
unsigned char *buf = iov->iov_buf;
213+
unsigned char *buf = (unsigned char *) iov->iov_buf;
214214
size_t sz = nng_aio_count(iaio->aio);
215215

216216
return nano_decode(buf, sz, mod, kpr);
@@ -390,7 +390,7 @@ SEXP rnng_stream_recv_aio(SEXP stream, SEXP bytes, SEXP timeout) {
390390

391391
nng_stream *sp = (nng_stream *) R_ExternalPtrAddr(stream);
392392
const nng_duration dur = (nng_duration) Rf_asInteger(timeout);
393-
const size_t xlen = Rf_asInteger(bytes);
393+
const size_t xlen = (size_t) Rf_asInteger(bytes);
394394
nano_aio *iaio = R_Calloc(1, nano_aio);
395395
nng_iov *iov = R_Calloc(1, nng_iov);
396396
int xc;
@@ -399,7 +399,7 @@ SEXP rnng_stream_recv_aio(SEXP stream, SEXP bytes, SEXP timeout) {
399399
iaio->type = IOV_RECVAIO;
400400
iaio->data = iov;
401401
iov->iov_len = xlen;
402-
iov->iov_buf = R_Calloc(xlen, unsigned char);
402+
iov->iov_buf = (unsigned char *) R_Calloc(xlen, unsigned char);
403403

404404
xc = nng_aio_alloc(&iaio->aio, iaio_complete, iaio);
405405
if (xc) {
@@ -416,7 +416,7 @@ SEXP rnng_stream_recv_aio(SEXP stream, SEXP bytes, SEXP timeout) {
416416
R_Free(iaio);
417417
return mk_error(xc);
418418
}
419-
xc = nng_aio_set_iov(iaio->aio, 1, iaio->data);
419+
xc = nng_aio_set_iov(iaio->aio, 1u, iov);
420420
if (xc) {
421421
nng_mtx_free(iaio->mtx);
422422
nng_aio_free(iaio->aio);
@@ -579,7 +579,7 @@ SEXP rnng_stream_send_aio(SEXP stream, SEXP data, SEXP timeout) {
579579
R_Free(iaio);
580580
return Rf_ScalarInteger(xc);
581581
}
582-
xc = nng_aio_set_iov(iaio->aio, 1, iaio->data);
582+
xc = nng_aio_set_iov(iaio->aio, 1u, iov);
583583
if (xc) {
584584
nng_mtx_free(iaio->mtx);
585585
nng_aio_free(iaio->aio);
@@ -690,7 +690,7 @@ SEXP rnng_ncurl_aio(SEXP http, SEXP method, SEXP headers, SEXP data) {
690690
}
691691
if (data != R_NilValue) {
692692
unsigned char *dp = RAW(data);
693-
const R_xlen_t dlen = Rf_xlength(data) - 1;
693+
const size_t dlen = (size_t) Rf_xlength(data) - 1;
694694
xc = nng_http_req_set_data(handle->req, dp, dlen);
695695
if (xc) {
696696
nng_http_req_free(handle->req);
@@ -801,16 +801,13 @@ SEXP rnng_aio_http(SEXP aio) {
801801

802802
void *dat;
803803
size_t sz;
804-
unsigned char *rp;
805804
SEXP vec;
806805

807806
nng_http_res_get_data(handle->res, &dat, &sz);
808807

809-
PROTECT(vec = Rf_allocVector(RAWSXP, sz));
810-
rp = RAW(vec);
811-
memcpy(rp, dat, sz);
808+
vec = Rf_allocVector(RAWSXP, sz);
809+
memcpy(RAW(vec), (unsigned char *) dat, sz);
812810

813-
UNPROTECT(1);
814811
return vec;
815812

816813
}

src/core.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ SEXP mk_error(const int xc) {
2020
SEXP nano_encode(SEXP object) {
2121

2222
R_xlen_t xlen = Rf_xlength(object);
23+
unsigned char *buf;
2324
size_t sz;
2425
SEXP out;
2526

2627
if (!Rf_isVectorAtomic(object))
2728
error_return("'data' is not an atomic vector type");
2829
if (TYPEOF(object) == STRSXP) {
2930
const char *s;
30-
unsigned char *buf;
3131
size_t np, outlen = 0;
3232
R_xlen_t i;
3333
for (i = 0; i < xlen; i++)
@@ -43,24 +43,28 @@ SEXP nano_encode(SEXP object) {
4343
} else {
4444
switch (TYPEOF(object)) {
4545
case REALSXP:
46+
buf = (unsigned char *) REAL(object);
4647
sz = xlen * sizeof(double);
4748
out = Rf_allocVector(RAWSXP, sz);
48-
memcpy(RAW(out), REAL(object), sz);
49+
memcpy(RAW(out), buf, sz);
4950
break;
5051
case INTSXP:
52+
buf = (unsigned char *) INTEGER(object);
5153
sz = xlen * sizeof(int);
5254
out = Rf_allocVector(RAWSXP, sz);
53-
memcpy(RAW(out), INTEGER(object), sz);
55+
memcpy(RAW(out), buf, sz);
5456
break;
5557
case LGLSXP:
58+
buf = (unsigned char *) LOGICAL(object);
5659
sz = xlen * sizeof(int);
5760
out = Rf_allocVector(RAWSXP, sz);
58-
memcpy(RAW(out), LOGICAL(object), sz);
61+
memcpy(RAW(out), buf, sz);
5962
break;
6063
case CPLXSXP:
64+
buf = (unsigned char *) COMPLEX(object);
6165
sz = xlen * (sizeof(double) + sizeof(double));
6266
out = Rf_allocVector(RAWSXP, sz);
63-
memcpy(RAW(out), COMPLEX(object), sz);
67+
memcpy(RAW(out), buf, sz);
6468
break;
6569
case RAWSXP:
6670
out = object;
@@ -78,7 +82,7 @@ SEXP rawOneString(unsigned char *bytes, R_xlen_t nbytes, R_xlen_t *np) {
7882

7983
unsigned char *p;
8084
R_xlen_t i;
81-
char *buf;
85+
char *cbuf;
8286
SEXP res;
8387

8488
for (i = *np, p = bytes + (*np); i < nbytes; p++, i++)
@@ -89,11 +93,11 @@ SEXP rawOneString(unsigned char *bytes, R_xlen_t nbytes, R_xlen_t *np) {
8993
*np = i + 1;
9094
res = Rf_mkChar((char *) p);
9195
} else {
92-
buf = R_chk_calloc(nbytes - (*np) + 1, 1);
93-
memcpy(buf, bytes + (*np), nbytes - (*np));
96+
cbuf = R_chk_calloc(nbytes - (*np) + 1, 1);
97+
memcpy(cbuf, bytes + (*np), nbytes - (*np));
9498
*np = nbytes;
95-
res = Rf_mkChar(buf);
96-
R_Free(buf);
99+
res = Rf_mkChar(cbuf);
100+
R_Free(cbuf);
97101
}
98102

99103
return res;
@@ -646,7 +650,9 @@ SEXP rnng_recv(SEXP socket, SEXP mode, SEXP block, SEXP keep) {
646650
return mk_error(xc);
647651
}
648652
nng_msg *msgp = nng_aio_get_msg(aiop);
649-
res = nano_decode(nng_msg_body(msgp), nng_msg_len(msgp), mod, kpr);
653+
buf = (unsigned char *) nng_msg_body(msgp);
654+
sz = nng_msg_len(msgp);
655+
res = nano_decode(buf, sz, mod, kpr);
650656
nng_msg_free(msgp);
651657
nng_aio_free(aiop);
652658
}
@@ -701,6 +707,8 @@ SEXP rnng_ctx_recv(SEXP context, SEXP mode, SEXP timeout, SEXP keep) {
701707
const nng_duration dur = (nng_duration) Rf_asInteger(timeout);
702708
const int mod = *INTEGER(mode), kpr = *LOGICAL(keep);
703709
int xc;
710+
unsigned char *buf;
711+
size_t sz;
704712
SEXP res;
705713

706714
xc = nng_aio_alloc(&aiop, NULL, NULL);
@@ -717,7 +725,9 @@ SEXP rnng_ctx_recv(SEXP context, SEXP mode, SEXP timeout, SEXP keep) {
717725
}
718726

719727
nng_msg *msgp = nng_aio_get_msg(aiop);
720-
res = nano_decode(nng_msg_body(msgp), nng_msg_len(msgp), mod, kpr);
728+
buf = (unsigned char *) nng_msg_body(msgp);
729+
sz = nng_msg_len(msgp);
730+
res = nano_decode(buf, sz, mod, kpr);
721731
nng_msg_free(msgp);
722732
nng_aio_free(aiop);
723733

@@ -783,7 +793,7 @@ SEXP rnng_stream_recv(SEXP stream, SEXP mode, SEXP timeout, SEXP keep, SEXP byte
783793
SEXP res;
784794

785795
iov.iov_len = xlen;
786-
iov.iov_buf = R_Calloc(xlen, unsigned char);
796+
iov.iov_buf = (unsigned char *) R_Calloc(xlen, unsigned char);
787797

788798
xc = nng_aio_alloc(&aiop, NULL, NULL);
789799
if (xc) {

src/utils.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ SEXP rnng_ncurl(SEXP http, SEXP method, SEXP headers, SEXP data) {
154154
}
155155
if (data != R_NilValue) {
156156
unsigned char *dp = RAW(data);
157-
const R_xlen_t dlen = XLENGTH(data) - 1;
157+
const size_t dlen = (size_t) Rf_xlength(data) - 1;
158158
xc = nng_http_req_set_data(req, dp, dlen);
159159
if (xc) {
160160
nng_http_req_free(req);
@@ -234,22 +234,19 @@ SEXP rnng_ncurl(SEXP http, SEXP method, SEXP headers, SEXP data) {
234234

235235
void *dat;
236236
size_t sz;
237-
unsigned char *rp;
238237
SEXP vec;
239238

240239
nng_http_res_get_data(res, &dat, &sz);
241240

242-
PROTECT(vec = Rf_allocVector(RAWSXP, sz));
243-
rp = RAW(vec);
244-
memcpy(rp, dat, sz);
241+
vec = Rf_allocVector(RAWSXP, sz);
242+
memcpy(RAW(vec), (unsigned char *) dat, sz);
245243
if (cfg != NULL)
246244
nng_tls_config_free(cfg);
247245
nng_http_res_free(res);
248246
nng_http_req_free(req);
249247
nng_http_client_free(client);
250248
nng_url_free(url);
251249

252-
UNPROTECT(1);
253250
return vec;
254251

255252
}
@@ -543,11 +540,11 @@ SEXP rnng_messenger(SEXP url) {
543540
R_Free(sock);
544541
return mk_error(xc);
545542
}
546-
dlp = R_Calloc(1, nng_listener);
543+
dlp = (nng_listener *) R_Calloc(1, nng_listener);
547544
xc = nng_listen(*sock, up, dlp, 0);
548545
if (xc == 10 || xc == 15) {
549546
R_Free(dlp);
550-
dlp = R_Calloc(1, nng_dialer);
547+
dlp = (nng_dialer *) R_Calloc(1, nng_dialer);
551548
xc = nng_dial(*sock, up, dlp, 2u);
552549
if (xc) {
553550
R_Free(dlp);

tests/tests.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ nanotest(is.integer(ctx$id))
8787
nanotest(ctx$state == "opened")
8888
nanotest(ctx$protocol == "req")
8989
nanotest(setopt(ctx, "ms", "send-timeout", 1000) == 0L)
90-
nanotestwn(send_aio(ctx, data.frame(), timeout = 500))
90+
csaio <- send_aio(ctx, data.frame(), timeout = 500)
91+
nanotestn(call_aio(csaio)$result)
9192
nanotestwn(recv_aio(ctx1, timeout = 500, keep.raw = FALSE))
9293
nanotestwn(send(ctx, "context test", mode ="raw", block = 300, echo = FALSE))
9394
nanotestwn(recv(ctx1, mode = "character", block = 300))

0 commit comments

Comments
 (0)