package org.rosuda.JRI;
// JRclient library - client interface to Rserve, see http://www.rosuda.org/Rserve/
// Copyright (C) 2004 Simon Urbanek
// --- for licensing information see LICENSE file in the original JRclient distribution ---
import java.util.*;
/** implementation of R-lists
This is rather preliminary and may change in future since it's not really proper.
The point is that the parser tries to interpret lists to be of the form entry=value,
where entry is stored in the "head" part, and value is stored in the "body" part.
Then using {@link #at(String)} it is possible to fetch "body" for a specific "head".
The terminology used is partly from hash fields - "keys" are the elements in "head"
and values are in "body" (see {@link #keys}).
On the other hand, R uses lists to store complex internal structures, which are not parsed according to the structure - in that case "head" and "body" have to be evaluated separately according to their meaning in that context. @version $Id: RList.java 2720 2007-03-15 17:35:42Z urbanek $ */ public class RList extends Object { /** xpressions containing head, body and tag. The terminology is a bit misleading (for historical reasons) - head corresponds to CAR, body to CDR and finally tag is TAG. */ public REXP head, body, tag; /** cached keys (from TAG) */ String[] keys = null; /** cached values(from CAR) */ REXP[] values = null; /** flag denoting whether we need to re-fetch the cached values.
true
if the conversion was successful */
boolean updateVec() {
if (!dirtyCache) return true;
// we do NOT run it recursively, because in most cases only once instance is asked
RList cur = this;
int l = 0;
while (cur!=null) {
l++;
REXP bd = cur.getBody();
cur = (bd==null)?null:bd.asList();
}
keys=new String[l];
values=new REXP[l];
cur = this;
l=0;
while (cur != null) {
REXP x = cur.getTag();
if (x!=null) keys[l]=x.asSymbolName();
values[l] = cur.getHead();
REXP bd = cur.getBody();
cur = (bd==null)?null:bd.asList();
l++;
}
dirtyCache=false;
return true;
}
/** get xpression given a key
@param v key
@return xpression which corresponds to the given key or
null
if list is not standartized or key not found */
public REXP at(String v) {
if (!updateVec() || keys==null || values==null) return null;
int i=0;
while (inull
if list is not standartized */
public String[] keys() {
return (!updateVec())?null:this.keys;
}
}