/*=====================================================================*/
/*    .../prgm/project/bigloo/runtime/Jlib/input_pipe_port.java        */
/*    -------------------------------------------------------------    */
/*    Author      :  Manuel Serrano                                    */
/*    Creation    :  Sat Dec  9 11:49:41 2000                          */
/*    Last change :  Fri May  2 16:19:27 2003 (serrano)                */
/*    Copyright   :  2000-03 Manuel Serrano                            */
/*    -------------------------------------------------------------    */
/*    Bigloo JVM input pipe ports.                                     */
/*=====================================================================*/
package bigloo;

import java.lang.*;
import java.io.*;

/*---------------------------------------------------------------------*/
/*    input_pipe_port ...                                              */
/*---------------------------------------------------------------------*/
public class input_pipe_port extends input_port
{
  public InputStream in;

  /*--- public constructors ---------------------------------------------*/
  public input_pipe_port( final InputStream  in,
                          final byte[]       c )
  {
    super( new String( c ), (int)bigloo.foreign.default_io_bufsiz );
    this.in= in;
  }

  public input_pipe_port( final byte[]  cmd,
                          final int     len )
  {
    super( new String( cmd ), len );

    final String        scmd= new String( cmd, 2, cmd.length-2 );

    try
    {
      final Process     process= Runtime.getRuntime().exec( scmd );

      in= process.getInputStream();
    }
    catch (final IOException _)
    {
      foreign.fail( "open-input-file",
                    "Can't execute command",
                    scmd.getBytes() );
    }
  }

  public input_pipe_port( final String  cmd,
                          final int     len )
  {
    super( cmd, len );

    try
    {
      final Process     process= Runtime.getRuntime().exec( cmd );

      in= process.getInputStream();
    }
    catch (final IOException _)
    {
      foreign.fail( "open-input-file",
                    "Can't execute command",
                    cmd.getBytes() );
    }
  }

  /*--- public methods --------------------------------------------------*/
  public void close()
    throws IOException
  {
    eof= true;
    other_eof= true;
    in.close();
  }

  public boolean rgc_charready()
  {
    try
    {
      return (   ((forward+1) < abufsiz)
              || (0 < in.available()));
    }
    catch (Exception _)
    {
      return false;
    }
  }

  public boolean rgc_fill_buffer()
    throws IOException
  {
    final int           bufsize= this.bufsiz;
    int                 abufsize= this.abufsiz;
    final int           matchstart= this.matchstart;
    final byte[]        buffer= this.buffer;

    if (0 < matchstart)
    {
      // we shift the buffer left and we fill the buffer */
      final int         movesize= abufsize-matchstart;

      for ( int i= 0 ; i < movesize ; ++i )
        buffer[i]= buffer[matchstart+i];

      abufsize-= matchstart;
      this.matchstart= 0;
      this.matchstop-= matchstart;
      this.forward-= matchstart;
      this.lastchar= buffer[matchstart-1];

      return rgc_size_fill_file_buffer( abufsize, bufsize-abufsize );
    }

    if (abufsize < bufsize)
      return rgc_size_fill_file_buffer( abufsize, bufsize-abufsize );

    // we current token is too large for the buffer */
    // we have to enlarge it.                       */
    rgc_double_buffer();

    return rgc_fill_buffer();
  }

  final boolean rgc_size_fill_file_buffer( int        abufsize,
                                           final int  size )
    throws IOException
  {
    final int           nbread= in.read( buffer, abufsize-1, size );

    if (nbread == -1)
      eof= true;
    else
      abufsize+= nbread;

    this.abufsiz= abufsize;

    if (0 < abufsize)
    {
      buffer[abufsize-1]= (byte)0;
      return true;
    }

    return false;
  }

  public void write( final output_port  p )
  {
    p.write( "#<input_pipe_port:" + name + ">" );
  }

  /*--- static methods --------------------------------------------------*/
  static boolean pipe_name_p( final byte[]  name )
  {
    return (   (name[ 0 ] == (byte)'|')
            && (name[ 1 ] == (byte)' ') );
  }
}
