All Downloads are FREE. Search and download functionalities are using the official Maven repository.

us.levk.rserve.client.protocol.Qap Maven / Gradle / Ivy

/*
 * The MIT License (MIT)
 * Copyright (c) 2017 [email protected]
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package us.levk.rserve.client.protocol;

import static java.nio.ByteBuffer.allocate;
import static java.nio.ByteBuffer.wrap;
import static java.util.stream.Stream.of;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.stream.Stream;

import org.rosuda.REngine.Rserve.protocol.RTalk;

/**
 * QAP1 protocol specifics
 * 
 * @author levk
 */
public interface Qap {

  /**
   * String type
   */
  static final int DT_STRING = RTalk.DT_STRING;
  /**
   * Flag for objects larger than 0xffffff
   */
  static final int DT_LARGE = RTalk.DT_LARGE;
  /**
   * SEXP type
   */
  static final int DT_SEXP = RTalk.DT_SEXP;

  /**
   * Assign command code
   */
  static final int CMD_assignSEXP = RTalk.CMD_assignSEXP;
  /**
   * Evaluate command code
   */
  static final int CMD_eval = RTalk.CMD_eval;
  /**
   * Evaluate without result command code
   */
  static final int CMD_voidEval = RTalk.CMD_voidEval;

  /**
   * @param c
   *          code
   * @param s
   *          size
   * @return header
   */
  static ByteBuffer header (int c, int s) {
    boolean l = s > 0xfffff0;
    byte[] b = new byte[l ? 8 : 4];
    int o = 0;
    b[o] = (byte) ((c & 255) | ((s > 0xfffff0) ? DT_LARGE : 0));
    o++;
    b[o] = (byte) (s & 255);
    o++;
    b[o] = (byte) ((s & 0xff00) >> 8);
    o++;
    b[o] = (byte) ((s & 0xff0000) >> 16);
    o++;
    if (l) {
      b[o] = (byte) ((s & 0xff000000) >> 24);
      o++;
      b[o] = 0;
      o++;
      b[o] = 0;
      o++;
      b[o] = 0;
      o++;
    }
    return wrap (b);
  }

  /**
   * @param s
   *          string
   * @return stream of encoded buffers
   */
  static Stream  string (String s) {
    int l = s.length () + 1;
    int p = 4 - (l & 3);
    return of (header (DT_STRING, l + p), wrap (s.getBytes ()), allocate (p + 1));
  }

  /**
   * @param c
   *          content
   * @return stream of encoded buffers
   */
  static Stream  sexp (byte[] c) {
    return of (header (DT_SEXP, c.length), wrap (c));
  }

  /**
   * @param i
   *          input
   * @return packet content (or null if no content)
   * @throws IOException
   *           on read or bad packet
   */
  static ByteBuffer packet (ByteBuffer i) throws IOException {
    int r = i.getInt ();
    if ((r & 0xf) == 1) {
      int s = i.getInt ();
      int h = i.position () + 8;
      i.position (h);
      if (s > 0) i.position (h + ((i.get () & DT_LARGE) > 0 ? 8 : 4));
      return i;
    } else throw new IOException ("Error response packet with error code " + ((r >> 24) & 127));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy