Logo Search packages:      
Sourcecode: rserve version File versions  Download package

static int org::rosuda::JRclient::REXP::parseREXP ( REXP  x,
byte[]  buf,
int  o 
) [inline, static]

parses byte buffer for binary representation of xpressions - read one xpression slot (descends recursively for aggregated xpressions such as lists, vectors etc.)

Parameters:
x xpression object to store the parsed xpression in
buf buffer containing the binary representation
o offset in the buffer to start at
Returns:
position just behind the parsed xpression. Can be use for successive calls to parseREXP if more than one expression is stored in the binary array.

Definition at line 119 of file REXP.java.

References attr, org::rosuda::JRclient::RList::body, cont, org::rosuda::JRclient::RList::head, REXP(), org::rosuda::JRclient::RList::tag, toString(), Xt, XT_ARRAY_BOOL, XT_ARRAY_BOOL_UA, XT_ARRAY_DOUBLE, XT_ARRAY_INT, XT_BOOL, XT_CLOS, XT_DOUBLE, XT_FACTOR, XT_INT, XT_LANG, XT_LIST, XT_NULL, XT_STR, XT_SYM, XT_UNKNOWN, and XT_VECTOR.

                                                           {
      int xl=Rtalk.getLen(buf,o);
      boolean hasAtt=((buf[o]&128)!=0);
        boolean isLong=((buf[o]&64)!=0);
      int xt=(int)(buf[o]&63);
        //System.out.println("parseREXP: type="+xt+", len="+xl+", hasAtt="+hasAtt+", isLong="+isLong);
        if (isLong) o+=4;
        o+=4;
      int eox=o+xl;
      
      x.Xt=xt; x.attr=null;
      if (hasAtt) o=parseREXP(x.attr=new REXP(),buf,o);
      if (xt==XT_NULL) {
          x.cont=null; return o;
      };
      if (xt==XT_DOUBLE) {
          long lr=Rtalk.getLong(buf,o);
          x.cont=new Double(Double.longBitsToDouble(lr));
          o+=8;
          if (o!=eox) {
            System.out.println("Warning: double SEXP size mismatch\n");
            o=eox;
          };
          return o;
      }
      if (xt==XT_ARRAY_DOUBLE) {
          int as=(eox-o)/8,i=0;
          double[] d=new double[as];
          while (o<eox) {
            d[i]=Double.longBitsToDouble(Rtalk.getLong(buf,o));
            o+=8;
            i++;
          };
          if (o!=eox) {
            System.out.println("Warning: double array SEXP size mismatch\n");
            o=eox;
          };
          x.cont=d;
          return o;
      };
      if (xt==XT_BOOL) {
          x.cont=new RBool(buf[o]); o++;
          if (o!=eox) {
                if (eox!=o+3) // o+3 could happen if the result was aligned (1 byte data + 3 bytes padding)
                    System.out.println("Warning: bool SEXP size mismatch\n");
            o=eox;
          };
          return o;
      };
      if (xt==XT_ARRAY_BOOL_UA) {
          int as=(eox-o), i=0;
            x.Xt=XT_ARRAY_BOOL; // XT_ARRAY_BOOL_UA is only old transport type for XT_ARRAY_BOOL
          RBool[] d=new RBool[as];
          while(o<eox) {
            d[i]=new RBool(buf[o]);
            i++; o++;
          };
          x.cont=d;
          return o;
      };
        if (xt==XT_ARRAY_BOOL) {
            int as=Rtalk.getInt(buf,o);
            o+=4;
            int i=0;
            RBool[] d=new RBool[as];
            while(o<eox && i<as) {
                d[i]=new RBool(buf[o]);
                i++; o++;
            }
          // skip the padding
          while ((i&3)!=0) { i++; o++; };
            x.cont=d;
            return o;
        };
        if (xt==XT_INT) {
          x.cont=new Integer(Rtalk.getInt(buf,o));
          o+=4;
          if (o!=eox) {
            System.out.println("Warning: int SEXP size mismatch\n");
            o=eox;
          };
          return o;
      }
      if (xt==XT_ARRAY_INT) {
          int as=(eox-o)/4,i=0;
          int[] d=new int[as];
          while (o<eox) {
            d[i]=Rtalk.getInt(buf,o);
            o+=4;
            i++;
          };
          if (o!=eox) {
            System.out.println("Warning: int array SEXP size mismatch\n");
            o=eox;
          };
          x.cont=d;
          // hack for lists - special lists attached to int are factors
          if (x.attr!=null && x.attr.Xt==XT_LIST && x.attr.cont!=null &&
            ((RList)x.attr.cont).head!=null &&
            ((RList)x.attr.cont).body!=null &&
            ((RList)x.attr.cont).head.cont!=null &&
            ((RList)x.attr.cont).body.cont!=null &&
            ((RList)x.attr.cont).head.Xt==XT_VECTOR &&
            ((RList)x.attr.cont).body.Xt==XT_LIST &&
            ((RList)((RList)x.attr.cont).body.cont).head!=null &&
            ((RList)((RList)x.attr.cont).body.cont).head.Xt==XT_STR &&
            ((String)((RList)((RList)x.attr.cont).body.cont).head.cont).compareTo("factor")==0) {
            RFactor f=new RFactor(d,(Vector)((RList)x.attr.cont).head.cont);
            x.cont=f;
            x.Xt=XT_FACTOR;
            x.attr=null;
          };
          return o;
      };
      if (xt==XT_VECTOR) {
          Vector v=new Vector();
          while(o<eox) {
            REXP xx=new REXP();
            o=parseREXP(xx,buf,o);
            v.addElement(xx);
          };
          if (o!=eox) {
            System.out.println("Warning: int vector SEXP size mismatch\n");
            o=eox;
          };
          x.cont=v;
          // fixup for lists since they're stored as attributes of vectors
          if (x.attr!=null && x.attr.Xt==XT_LIST && x.attr.cont!=null) {
            RList l=new RList();
            l.head=((RList)x.attr.cont).head;
            l.body=new REXP(XT_VECTOR,v);
            x.cont=l;
            x.Xt=XT_LIST; x.attr=x.attr.attr;
            // one more hack: we're de-vectorizing strings if alone
            // so we should invert that in case of list heads
            if (l.head.Xt==XT_STR) {
                Vector sv=new Vector();
                sv.addElement(l.head);
                l.head=new REXP(XT_VECTOR,sv,l.head.attr);
                l.head.attr=null;
            };
          };
          return o;
      };
      if (xt==XT_STR) {
          int i=o;
          while (buf[i]!=0 && i<eox) i++;
          try {
            x.cont=new String(buf,o,i-o,Rconnection.transferCharset);
          } catch(Exception e) {
            System.out.println("unable to convert string\n");
            x.cont=null;
          };
          o=eox;
          return o;
      };
      if (xt==XT_LIST || xt==XT_LANG) {
          RList rl=new RList();
          rl.head=new REXP();
          rl.body=new REXP();
          rl.tag=null;
          o=parseREXP(rl.head,buf,o); // CAR
          o=parseREXP(rl.body,buf,o); // CDR
          if (o!=eox) {
            // if there is more data then it's presumably the TAG entry
            rl.tag=new REXP();
            o=parseREXP(rl.tag,buf,o);
            if (o!=eox) {
                System.out.println("Warning: list SEXP size mismatch\n");
                o=eox;
            }
          };
          x.cont=rl;
          return o;
      };

      if (xt==XT_SYM) {
          REXP sym=new REXP();
          o=parseREXP(sym,buf,o); // PRINTNAME that's all we will use
          String s=null;
          if (sym.Xt==XT_STR) s=(String)sym.cont; else s=sym.toString();
          x.cont=s; // content of a symbol is its printname string (so far)
          o=eox;
          return o;
      }

      if (xt==XT_CLOS) {
          REXP form=new REXP();
          REXP body=new REXP();
          o=parseREXP(form,buf,o);
          o=parseREXP(body,buf,o);
          if (o!=eox) {
            System.out.println("Warning: closure SEXP size mismatch\n");
            o=eox;
          }
            /* curently closures are not coded into their own objects, basically due to lack of demand. */
          x.cont=body;
          return o;
      }

      if (xt==XT_UNKNOWN) {
          x.cont=new Integer(Rtalk.getInt(buf,o));
          o=eox;
          return o;
      }

      x.cont=null;
      o=eox;
      System.out.println("unhandled type: "+xt);
      return o;
    }


Generated by  Doxygen 1.6.0   Back to index