|
8 | 8 | #include "xml2_utils.h"
|
9 | 9 |
|
10 | 10 | [[cpp11::register]]
|
11 |
| -extern "C" SEXP url_absolute_(SEXP x_sxp, SEXP base_sxp) { |
12 |
| - R_xlen_t n = Rf_xlength(x_sxp); |
13 |
| - SEXP out = PROTECT(Rf_allocVector(STRSXP, n)); |
| 11 | +cpp11::strings url_absolute_(cpp11::strings x_sxp, cpp11::strings base_sxp) { |
| 12 | + int n = x_sxp.size(); |
| 13 | + cpp11::writable::strings out(n); |
14 | 14 |
|
15 |
| - if (Rf_xlength(base_sxp) > 1) { |
16 |
| - Rf_error("Base URL must be length 1"); |
| 15 | + if (base_sxp.size() > 1) { |
| 16 | + cpp11::stop("Base URL must be length 1"); |
17 | 17 | }
|
18 | 18 |
|
19 |
| - const xmlChar* base_uri = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(base_sxp, 0)); |
| 19 | + const xmlChar* base_uri = (xmlChar*) cpp11::as_cpp<const char*>(base_sxp); |
20 | 20 |
|
21 | 21 | for (int i = 0; i < n; ++i) {
|
22 |
| - const xmlChar* uri = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(x_sxp, i)); |
23 |
| - SET_STRING_ELT(out, i, Xml2String(xmlBuildURI(uri, base_uri)).asRString()); |
| 22 | + const xmlChar* uri = (xmlChar*) Rf_translateCharUTF8(x_sxp[i]); |
| 23 | + out[i] = Xml2String(xmlBuildURI(uri, base_uri)).asRString(); |
24 | 24 | }
|
25 | 25 |
|
26 |
| - UNPROTECT(1); |
27 | 26 | return out;
|
28 | 27 | }
|
29 | 28 |
|
30 | 29 | [[cpp11::register]]
|
31 |
| -extern "C" SEXP url_relative_(SEXP x_sxp, SEXP base_sxp) { |
32 |
| - R_xlen_t n = Rf_xlength(x_sxp); |
33 |
| - SEXP out = PROTECT(Rf_allocVector(STRSXP, n)); |
| 30 | +cpp11::strings url_relative_(cpp11::strings x_sxp, cpp11::strings base_sxp) { |
| 31 | + int n = x_sxp.size(); |
| 32 | + cpp11::writable::strings out(n); |
34 | 33 |
|
35 |
| - if (Rf_xlength(base_sxp) > 1) { |
36 |
| - Rf_error("Base URL must be length 1"); |
| 34 | + if (base_sxp.size() > 1) { |
| 35 | + cpp11::stop("Base URL must be length 1"); |
37 | 36 | }
|
38 | 37 |
|
39 |
| - const xmlChar* base_uri = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(base_sxp, 0)); |
| 38 | + const xmlChar* base_uri = (xmlChar*) cpp11::as_cpp<const char*>(base_sxp); |
40 | 39 |
|
41 | 40 | for (int i = 0; i < n; ++i) {
|
42 |
| - const xmlChar* uri = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(x_sxp, i)); |
43 |
| - SET_STRING_ELT(out, i, Xml2String(xmlBuildRelativeURI(uri, base_uri)).asRString()); |
| 41 | + const xmlChar* uri = (xmlChar*) Rf_translateCharUTF8(x_sxp[i]); |
| 42 | + out[i] = Xml2String(xmlBuildRelativeURI(uri, base_uri)).asRString(); |
44 | 43 | }
|
45 | 44 |
|
46 |
| - UNPROTECT(1); |
47 | 45 | return out;
|
48 | 46 | }
|
49 | 47 |
|
50 | 48 | [[cpp11::register]]
|
51 |
| -extern "C" SEXP url_parse_(SEXP x_sxp) { |
52 |
| - R_xlen_t n = Rf_xlength(x_sxp); |
| 49 | +cpp11::data_frame url_parse_(cpp11::strings x_sxp) { |
| 50 | + int n = x_sxp.size(); |
53 | 51 |
|
54 |
| - SEXP scheme = PROTECT(Rf_allocVector(STRSXP, n)); |
55 |
| - SEXP server = PROTECT(Rf_allocVector(STRSXP, n)); |
56 |
| - SEXP user = PROTECT(Rf_allocVector(STRSXP, n)); |
57 |
| - SEXP path = PROTECT(Rf_allocVector(STRSXP, n)); |
58 |
| - SEXP query = PROTECT(Rf_allocVector(STRSXP, n)); |
59 |
| - SEXP fragment = PROTECT(Rf_allocVector(STRSXP, n)); |
| 52 | + cpp11::writable::strings scheme(n); |
| 53 | + cpp11::writable::strings server(n); |
| 54 | + cpp11::writable::strings user(n); |
| 55 | + cpp11::writable::strings path(n); |
| 56 | + cpp11::writable::strings query(n); |
| 57 | + cpp11::writable::strings fragment(n); |
60 | 58 |
|
61 |
| - SEXP port = PROTECT(Rf_allocVector(INTSXP, n)); |
| 59 | + cpp11::writable::integers port(n); |
62 | 60 |
|
63 | 61 | for (int i = 0; i < n; ++i) {
|
64 |
| - const char* raw = Rf_translateCharUTF8(STRING_ELT(x_sxp, i)); |
| 62 | + const char* raw = Rf_translateCharUTF8(x_sxp[i]); |
65 | 63 | xmlURI* uri = xmlParseURI(raw);
|
66 | 64 | if (uri == NULL) {
|
67 | 65 | continue;
|
68 | 66 | }
|
69 | 67 |
|
70 |
| - SET_STRING_ELT(scheme, i, Rf_mkChar(uri->scheme == NULL ? "" : uri->scheme)); |
71 |
| - SET_STRING_ELT(server, i, Rf_mkChar(uri->server == NULL ? "" : uri->server)); |
72 |
| - INTEGER(port)[i] = uri->port == 0 ? NA_INTEGER : uri->port; |
73 |
| - SET_STRING_ELT(user, i, Rf_mkChar(uri->user == NULL ? "" : uri->user)); |
74 |
| - SET_STRING_ELT(path, i, Rf_mkChar(uri->path == NULL ? "" : uri->path)); |
75 |
| - SET_STRING_ELT(fragment, i, Rf_mkChar(uri->fragment == NULL ? "" : uri->fragment)); |
| 68 | + scheme[i] = uri->scheme == NULL ? "" : uri->scheme; |
| 69 | + server[i] = uri->server == NULL ? "" : uri->server; |
| 70 | + port[i] = uri->port == 0 ? NA_INTEGER : uri->port; |
| 71 | + user[i] = uri->user == NULL ? "" : uri->user; |
| 72 | + path[i] = uri->path == NULL ? "" : uri->path; |
| 73 | + fragment[i] = uri->fragment == NULL ? "" : uri->fragment; |
76 | 74 |
|
77 | 75 | /* * *
|
78 | 76 | * Thu Apr 26 10:36:26 CEST 2007 Daniel Veillard
|
79 | 77 | * svn path=/trunk/; revision=3607
|
80 | 78 | * https://github.com/GNOME/libxml2/commit/a1413b84f7163d57c6251d5f4251186368efd859
|
81 | 79 | */
|
82 | 80 | #if defined(LIBXML_VERSION) && (LIBXML_VERSION >= 20629)
|
83 |
| - SET_STRING_ELT(query, i, Rf_mkChar(uri->query_raw == NULL ? "" : uri->query_raw)); |
| 81 | + query[i] = uri->query_raw == NULL ? "" : uri->query_raw; |
84 | 82 | #else
|
85 |
| - SET_STRING_ELT(query, i, Rf_mkChar(uri->query == NULL ? "" : uri->query)); |
| 83 | + query[i] = uri->query == NULL ? "" : uri->query; |
86 | 84 | #endif
|
87 | 85 |
|
88 | 86 | xmlFreeURI(uri);
|
89 | 87 | }
|
90 | 88 |
|
91 |
| - SEXP out = PROTECT(Rf_allocVector(VECSXP, 7)); |
92 |
| - SET_VECTOR_ELT(out, 0, scheme); |
93 |
| - SET_VECTOR_ELT(out, 1, server); |
94 |
| - SET_VECTOR_ELT(out, 2, port); |
95 |
| - SET_VECTOR_ELT(out, 3, user); |
96 |
| - SET_VECTOR_ELT(out, 4, path); |
97 |
| - SET_VECTOR_ELT(out, 5, query); |
98 |
| - SET_VECTOR_ELT(out, 6, fragment); |
| 89 | + using namespace cpp11::literals; |
99 | 90 |
|
100 |
| - SEXP names = PROTECT(Rf_allocVector(STRSXP, 7)); |
101 |
| - |
102 |
| - SET_STRING_ELT(names, 0, Rf_mkChar("scheme")); |
103 |
| - SET_STRING_ELT(names, 1, Rf_mkChar("server")); |
104 |
| - SET_STRING_ELT(names, 2, Rf_mkChar("port")); |
105 |
| - SET_STRING_ELT(names, 3, Rf_mkChar("user")); |
106 |
| - SET_STRING_ELT(names, 4, Rf_mkChar("path")); |
107 |
| - SET_STRING_ELT(names, 5, Rf_mkChar("query")); |
108 |
| - SET_STRING_ELT(names, 6, Rf_mkChar("fragment")); |
109 |
| - |
110 |
| - Rf_setAttrib(out, R_ClassSymbol, Rf_mkString("data.frame")); |
111 |
| - Rf_setAttrib(out, R_NamesSymbol, names); |
112 |
| - |
113 |
| - SEXP row_names = PROTECT(Rf_allocVector(INTSXP, 2)); |
114 |
| - INTEGER(row_names)[0] = NA_INTEGER; |
115 |
| - INTEGER(row_names)[1] = -n; |
116 |
| - Rf_setAttrib(out, R_RowNamesSymbol, row_names); |
117 |
| - |
118 |
| - UNPROTECT(10); |
| 91 | + cpp11::writable::data_frame out({ |
| 92 | + "scheme"_nm = scheme, |
| 93 | + "server"_nm = server, |
| 94 | + "port"_nm = port, |
| 95 | + "user"_nm = user, |
| 96 | + "path"_nm = path, |
| 97 | + "query"_nm = query, |
| 98 | + "fragment"_nm = fragment, |
| 99 | + }); |
119 | 100 |
|
120 | 101 | return out;
|
121 | 102 | }
|
122 | 103 |
|
123 | 104 | [[cpp11::register]]
|
124 |
| -extern "C" SEXP url_escape_(SEXP x_sxp, SEXP reserved_sxp) { |
125 |
| - R_xlen_t n = Rf_xlength(x_sxp); |
126 |
| - SEXP out = PROTECT(Rf_allocVector(STRSXP, n)); |
| 105 | +cpp11::strings url_escape_(cpp11::strings x_sxp, cpp11::strings reserved_sxp) { |
| 106 | + int n = x_sxp.size(); |
| 107 | + cpp11::writable::strings out(n); |
127 | 108 |
|
128 |
| - if (Rf_xlength(reserved_sxp) != 1) { |
129 |
| - Rf_error("`reserved` must be character vector of length 1"); |
| 109 | + if (reserved_sxp.size() > 1) { |
| 110 | + cpp11::stop("`reserved` must be character vector of length 1"); |
130 | 111 | }
|
131 | 112 |
|
132 |
| - xmlChar* xReserved = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(reserved_sxp, 0)); |
| 113 | + const xmlChar* xReserved = (xmlChar*) cpp11::as_cpp<const char*>(reserved_sxp); |
133 | 114 |
|
134 | 115 | for (int i = 0; i < n; ++i) {
|
135 |
| - const xmlChar* xx = (xmlChar*) Rf_translateCharUTF8(STRING_ELT(x_sxp, i)); |
136 |
| - SET_STRING_ELT(out, i, Xml2String(xmlURIEscapeStr(xx, xReserved)).asRString()); |
| 116 | + const xmlChar* xx = (xmlChar*) Rf_translateCharUTF8(x_sxp[i]); |
| 117 | + out[i] = Xml2String(xmlURIEscapeStr(xx, xReserved)).asRString(); |
137 | 118 | }
|
138 | 119 |
|
139 |
| - UNPROTECT(1); |
140 | 120 | return out;
|
141 | 121 | }
|
142 | 122 |
|
143 | 123 | [[cpp11::register]]
|
144 |
| -extern "C" SEXP url_unescape_(SEXP x_sxp) { |
145 |
| - R_xlen_t n = Rf_xlength(x_sxp); |
146 |
| - SEXP out = PROTECT(Rf_allocVector(STRSXP, n)); |
| 124 | +cpp11::strings url_unescape_(cpp11::strings x_sxp) { |
| 125 | + int n = x_sxp.size(); |
| 126 | + cpp11::writable::strings out(n); |
147 | 127 |
|
148 | 128 | for (int i = 0; i < n; ++i) {
|
149 |
| - const char* xx = Rf_translateCharUTF8(STRING_ELT(x_sxp, i)); |
| 129 | + const char* xx = Rf_translateCharUTF8(x_sxp[i]); |
150 | 130 |
|
151 | 131 | char* unescaped = xmlURIUnescapeString(xx, 0, NULL);
|
152 |
| - SET_STRING_ELT(out, i, (unescaped == NULL) ? NA_STRING : Rf_mkCharCE(unescaped, CE_UTF8)); |
| 132 | + out[i] = (unescaped == NULL) ? cpp11::na<cpp11::r_string>() : cpp11::r_string(unescaped); |
153 | 133 | xmlFree(unescaped);
|
154 | 134 | }
|
155 | 135 |
|
156 |
| - UNPROTECT(1); |
157 | 136 | return out;
|
158 | 137 | }
|
0 commit comments