Example #1
0
  /**
   * Read the python preamble off of stderr. It ends when the prompy '>>> ' is detected.
   *
   * @return the preamble read from stderr
   */
  private String readPreamble(int timeoutMs) {
    String rv = null;
    StringBuilder sb = new StringBuilder();
    long timeout = System.currentTimeMillis() + timeoutMs;

    try {
      char[] prompt = {'>', '>', '>', ' '};
      int index = 0;

      while (true) {
        // sleep until there's input
        while (!stderr.ready()) {
          Thread.yield();

          if (timeoutMs >= 0 && System.currentTimeMillis() >= timeout)
            error("Timeout (" + timeoutMs + " ms) reached while reading python preamble.");
        }

        int readInt = stderr.read();

        if (readInt == -1) // end of stream
        error("End of output stream was reached while looking for python prompt.");

        char c = (char) readInt;

        sb.append(c);

        if (c == prompt[index]) {
          ++index;

          if (index == prompt.length) {
            // exit only if there are no more bytes to be read
            if (!stderr.ready()) break;
            else index = 0;
          }
        } else index = 0;
      }

      // trim off the prompt
      int len = sb.length();
      sb.delete(len - prompt.length, len);

      // remove \n and \r if they're at the end of the string
      trimSuffix(sb, '\n');
      trimSuffix(sb, '\r');

      rv = sb.toString();
    } catch (IOException e) {
      error("Error while reading python preamble.", e);
    }

    return rv;
  }
Example #2
0
  /**
   * Read stdout until the prompt '>>> ' is given on stderr
   *
   * @param quitOnStderr should we raise an exception if stderr output is detected other than the
   *     prompt?
   * @return output the received stdout / stderr strings
   */
  private String readUntilPrompt() {
    String rv = null;
    StringBuilder sbStdout = new StringBuilder();
    StringBuilder sbStderr = new StringBuilder();
    long timeout = System.currentTimeMillis() + timeoutMs;

    try {
      char[] prompt = {'>', '>', '>', ' '};
      int index = 0;
      boolean done = false;

      while (!done) {
        // sleep until there's input
        while (!stdout.ready() && !stderr.ready()) {
          Thread.yield();

          if (timeoutMs >= 0 && System.currentTimeMillis() >= timeout) {
            String out = "";
            String err = "";

            if (sbStdout.length() > 0) out = "\nStdout was: '" + sbStdout.toString() + "'";

            if (sbStderr.length() > 0) err = "\nStderr was: '" + sbStderr.toString() + "'";

            error("Timeout (" + timeoutMs + " ms) reached during python interaction." + out + err);
          }
        }

        // read stdout until blocked
        while (stdout.ready()) {
          int readInt = stdout.read();

          if (readInt == -1) // end of stream
          error("End of output stream was reached while reading python response.");

          sbStdout.append((char) readInt);
        }

        // read stderr until blocked
        while (stderr.ready()) {
          int readInt = stderr.read();

          if (readInt == -1) // end of stream
          error("End of output stream was reached while looking for python prompt.");

          char c = (char) readInt;
          sbStderr.append(c);

          if (c == prompt[index]) {
            ++index;

            if (index == prompt.length) {
              // exit only if there are no more bytes to be read
              if (!stderr.ready()) {
                done = true;
                break;
              } else index = 0;
            }
          } else index = 0;
        }
      }

      // read any remaining stdout characters
      sbStdout.append(readUntilBlocked(stdout));

      // trim off the prompt
      sbStderr.delete(sbStderr.length() - prompt.length, sbStderr.length());

      // trim off \n if it's at the end
      trimSuffix(sbStdout, '\n');
      trimSuffix(sbStdout, '\r');

      // if anything was printed to stderr, it's an error
      if (sbStderr.length() > 0)
        error(
            "Python produced output on stderr:\n'"
                + sbStderr.toString()
                + "'"
                + (sbStdout.length() > 0 ? "\n\nstdout was:\n" + sbStdout.toString() : ""));

      rv = sbStdout.toString();
    } catch (IOException e) {
      error("Error while reading python output", e);
    }

    return rv;
  }