Skip to content

Commit ae3a6ec

Browse files
committed
Convert xml2_path.cpp
1 parent 60ae697 commit ae3a6ec

File tree

2 files changed

+25
-31
lines changed

2 files changed

+25
-31
lines changed

src/cpp11.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,10 @@ extern "C" SEXP _xml2_url_unescape_(SEXP x_sxp) {
440440
END_CPP11
441441
}
442442
// xml2_xpath.cpp
443-
cpp11::sexp xpath_search(SEXP node_sxp, SEXP doc_sxp, SEXP xpath_sxp, SEXP nsMap_sxp, SEXP num_results_sxp);
443+
cpp11::sexp xpath_search(cpp11::sexp node_sxp, cpp11::sexp doc_sxp, cpp11::sexp xpath_sxp, cpp11::strings nsMap_sxp, cpp11::doubles num_results_sxp);
444444
extern "C" SEXP _xml2_xpath_search(SEXP node_sxp, SEXP doc_sxp, SEXP xpath_sxp, SEXP nsMap_sxp, SEXP num_results_sxp) {
445445
BEGIN_CPP11
446-
return cpp11::as_sexp(xpath_search(cpp11::as_cpp<cpp11::decay_t<SEXP>>(node_sxp), cpp11::as_cpp<cpp11::decay_t<SEXP>>(doc_sxp), cpp11::as_cpp<cpp11::decay_t<SEXP>>(xpath_sxp), cpp11::as_cpp<cpp11::decay_t<SEXP>>(nsMap_sxp), cpp11::as_cpp<cpp11::decay_t<SEXP>>(num_results_sxp)));
446+
return cpp11::as_sexp(xpath_search(cpp11::as_cpp<cpp11::decay_t<cpp11::sexp>>(node_sxp), cpp11::as_cpp<cpp11::decay_t<cpp11::sexp>>(doc_sxp), cpp11::as_cpp<cpp11::decay_t<cpp11::sexp>>(xpath_sxp), cpp11::as_cpp<cpp11::decay_t<cpp11::strings>>(nsMap_sxp), cpp11::as_cpp<cpp11::decay_t<cpp11::doubles>>(num_results_sxp)));
447447
END_CPP11
448448
}
449449

src/xml2_xpath.cpp

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,24 @@ class XmlSeeker {
2323
context_->node = node;
2424
}
2525

26-
void registerNamespace(SEXP nsMap) {
27-
R_xlen_t n = Rf_xlength(nsMap);
26+
void registerNamespace(cpp11::strings nsMap) {
27+
R_xlen_t n = nsMap.size();
2828
if (n == 0) {
2929
return;
3030
}
3131

32-
SEXP prefix = Rf_getAttrib(nsMap, R_NamesSymbol);
32+
cpp11::strings prefix = nsMap.names();
3333

3434
for (int i = 0; i < n; ++i) {
35-
xmlChar* prefixI = (xmlChar*) CHAR(STRING_ELT(prefix, i));
36-
xmlChar* urlI = (xmlChar*) CHAR(STRING_ELT(nsMap, i));
35+
xmlChar* prefixI = (xmlChar*) CHAR(prefix[i]);
36+
xmlChar* urlI = (xmlChar*) CHAR(nsMap[i]);
3737

3838
if (xmlXPathRegisterNs(context_, prefixI, urlI) != 0)
39-
Rf_error("Failed to register namespace (%s <-> %s)", prefixI, urlI);
39+
cpp11::stop("Failed to register namespace (%s <-> %s)", prefixI, urlI);
4040
}
4141
}
4242

43-
SEXP search(const char* xpath, int num_results) {
43+
cpp11::sexp search(const char* xpath, int num_results) {
4444
result_ = xmlXPathEval((const xmlChar*)xpath, context_);
4545
if (result_ == NULL) {
4646
SEXP ret = PROTECT(Rf_allocVector(VECSXP, 0));
@@ -61,34 +61,29 @@ class XmlSeeker {
6161
}
6262
int n = std::min(result_->nodesetval->nodeNr, num_results);
6363

64-
SEXP out = PROTECT(Rf_allocVector(VECSXP, n));
64+
cpp11::writable::list out(n);
6565

66-
SEXP names = PROTECT(Rf_allocVector(STRSXP, 2));
67-
SET_STRING_ELT(names, 0, Rf_mkChar("node"));
68-
SET_STRING_ELT(names, 1, Rf_mkChar("doc"));
66+
cpp11::strings names({"node", "doc"});
6967

7068
for (int i = 0; i < n; i++) {
71-
SEXP ret = PROTECT(Rf_allocVector(VECSXP, 2));
69+
cpp11::writable::list ret({
70+
XPtrNode(nodes->nodeTab[i]),
71+
doc_
72+
});
7273

73-
SET_VECTOR_ELT(ret, 0, XPtrNode(nodes->nodeTab[i]));
74-
SET_VECTOR_ELT(ret, 1, doc_);
74+
ret.names() = names;
75+
ret.attr("class") = "xml_node";
7576

76-
Rf_setAttrib(ret, R_NamesSymbol, names);
77-
Rf_setAttrib(ret, R_ClassSymbol, Rf_mkString("xml_node"));
78-
79-
SET_VECTOR_ELT(out, i, ret);
80-
81-
UNPROTECT(1);
77+
out[i] = ret;
8278
}
8379

84-
UNPROTECT(2);
8580
return out;
8681
}
87-
case XPATH_NUMBER: { return Rf_ScalarReal(result_->floatval); }
88-
case XPATH_BOOLEAN: { return Rf_ScalarLogical(result_->boolval); }
89-
case XPATH_STRING: { return Rf_ScalarString(Rf_mkCharCE((char *) result_->stringval, CE_UTF8)); }
82+
case XPATH_NUMBER: { return cpp11::doubles({result_->floatval}); }
83+
case XPATH_BOOLEAN: { return cpp11::logicals({result_->boolval}); }
84+
case XPATH_STRING: { return cpp11::as_sexp((const char*) result_->stringval); }
9085
default:
91-
Rf_error("XPath result type: %d not supported", result_->type);
86+
cpp11::stop("XPath result type: %d not supported", result_->type);
9287
}
9388

9489
return R_NilValue;
@@ -105,16 +100,15 @@ class XmlSeeker {
105100
};
106101

107102
[[cpp11::register]]
108-
cpp11::sexp xpath_search(SEXP node_sxp, SEXP doc_sxp, SEXP xpath_sxp, SEXP nsMap_sxp, SEXP num_results_sxp) {
109-
103+
cpp11::sexp xpath_search(cpp11::sexp node_sxp, cpp11::sexp doc_sxp, cpp11::sexp xpath_sxp, cpp11::strings nsMap_sxp, cpp11::doubles num_results_sxp) {
110104
XPtrNode node(node_sxp);
111105
XPtrDoc doc(doc_sxp);
112106
if (TYPEOF(xpath_sxp) != STRSXP) {
113107
Rf_error("XPath must be a string, received %s", Rf_type2char(TYPEOF(xpath_sxp)));
114108
}
115-
const char* xpath = CHAR(STRING_ELT(xpath_sxp, 0));
109+
const char* xpath = CHAR(cpp11::strings(xpath_sxp)[0]);
116110

117-
double num_results = REAL(num_results_sxp)[0];
111+
double num_results = num_results_sxp[0];
118112

119113
if (num_results == R_PosInf) {
120114
num_results = INT_MAX;

0 commit comments

Comments
 (0)