in src/RLoader.cpp [197:276]
Status RPIServiceImpl::loaderGetVariables(ServerContext* context, const GetVariablesRequest* request, VariablesResponse* response) {
executeOnMainThread([&] {
ShieldSEXP obj = dereference(request->obj());
R_xlen_t reqStart = request->start();
R_xlen_t reqEnd = request->end();
if (reqEnd == -1) reqEnd = std::numeric_limits<R_xlen_t>::max();
if (obj.type() == ENVSXP) {
response->set_isenv(true);
if (request->onlyfunctions() && request->nofunctions()) return;
ShieldSEXP ls = RI->ls(named("envir", obj), named("all.names", !request->nohidden()));
if (ls.type() != STRSXP) return;
R_xlen_t length = ls.length();
if (request->onlyfunctions() || request->nofunctions()) {
R_xlen_t j = 0;
for (R_xlen_t i = 0; i < length; ++i) {
ShieldSEXP x = obj.getVar(stringEltNative(ls, i), false);
bool isFunc = x.type() == CLOSXP || x.type() == BUILTINSXP || x.type() == SPECIALSXP;
if (isFunc == request->onlyfunctions()) {
if (reqStart <= j && j < reqEnd) {
VariablesResponse::Variable *var = response->add_vars();
std::string name = stringEltUTF8(ls, i);
trim(name);
var->set_name(name);
getValueInfo(x, var->mutable_value());
}
++j;
}
}
response->set_totalcount(j);
} else {
response->set_totalcount(ls.length());
for (int i = std::max<R_xlen_t>(0, reqStart); i < std::min(length, reqEnd); ++i) {
VariablesResponse::Variable *var = response->add_vars();
std::string name = stringEltUTF8(ls, i);
trim(name);
var->set_name(name);
getValueInfo(obj.getVar(stringEltNative(ls, i), false), var->mutable_value());
}
}
return;
}
response->set_isenv(false);
if (obj.type() == LISTSXP || obj.type() == DOTSXP) {
SEXP x = obj;
response->set_totalcount(obj.length());
int i = 0;
while (x != R_NilValue && i < reqEnd) {
if (i >= reqStart) {
VariablesResponse::Variable* var = response->add_vars();
if (TAG(x) != R_NilValue) {
std::string name = asStringUTF8(PRINTNAME(TAG(x)));
trim(name);
var->set_name(name);
}
getValueInfo(CAR(x), var->mutable_value());
}
x = CDR(x);
++i;
}
return;
}
if (obj.type() != VECSXP && obj.type() != INTSXP && obj.type() != REALSXP && obj.type() != STRSXP &&
obj.type() != RAWSXP && obj.type() != CPLXSXP && obj.type() != LGLSXP && obj.type() != EXPRSXP) {
return;
}
R_xlen_t length = obj.length();
response->set_totalcount(length);
ShieldSEXP unclassed = Rf_inherits(obj, "factor") ? (SEXP)obj : RI->unclass(obj);
ShieldSEXP filtered = RI->subscript(unclassed, RI->colon(reqStart + 1, std::min(length, reqEnd)));
ShieldSEXP names = Rf_getAttrib(filtered, R_NamesSymbol);
for (int i = 0; i < filtered.length(); ++i) {
VariablesResponse::Variable* var = response->add_vars();
std::string name = stringEltUTF8(names, i);
trim(name);
var->set_name(name);
getValueInfo(RI->doubleSubscript(filtered, i + 1), var->mutable_value());
}
}, context, true);
return Status::OK;
}