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

decodes.polling.StreamReader Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/*
 * $Id$
 * 
 * This software was written by Cove Software, LLC ("COVE") under contract
 * to Alberta Environment and Sustainable Resource Development (Alberta ESRD).
 * No warranty is provided or implied other than specific contractual terms 
 * between COVE and Alberta ESRD.
 *
 * Copyright 2014 Alberta Environment and Sustainable Resource Development.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package decodes.polling;

import ilex.util.ArrayUtil;
import ilex.util.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Used by Protocol to continually read the InputStream coming from
 * the remote station. It provides methods for searching the stream for a
 * match-string. It keeps track of characters already searched. It saves
 * the entire stream for subsequent logging. It can 'capture' a portion of
 * the stream for inclusion in a DCP Message.
 */
public class StreamReader
	extends Thread
{
	private String module = "StreamReader";
	private InputStream in = null;
	private ByteArrayOutputStream captured = new ByteArrayOutputStream();
	private boolean capture = false;
	private PollSessionLogger psLog = null;
	public static final int MAX_BUF_SIZE = 99900;
	private byte[] sessionBuf = new byte[MAX_BUF_SIZE];
	private int sessionIdx = 0;
	private int processIdx = 0;
	private boolean _shutdown = false;
	private StreamReaderOwner owner = null;
	
	public StreamReader(InputStream in, StreamReaderOwner owner)
	{
		this.in = in;
		this.owner = owner;
		if (owner != null)
			module = module + "(" + owner.getModule() + ")";
	}
	
	@Override
	public void run()
	{
		Logger.instance().debug1(module + " starting.");
		try
		{
			int c=-1;
			while(!_shutdown)
			{
				if (in.available() > 0)
				{
					c = in.read();
					if (c == -1)
					{
						Logger.instance().debug1(module + " input stream closed.");
						_shutdown = true;
					}
					else
					{
						if (sessionIdx >= sessionBuf.length)
						{
							Logger.instance().info(module + "Message too long. Size=" 
								+ sessionIdx + ", truncating message at this point.");
							_shutdown = true;
							break;
						}
						sessionBuf[sessionIdx++] = (byte)c;
						if (capture)
							captured.write(c);
						if (psLog != null)
							psLog.received((char)c);
					}
				}
				else
				{
					try { sleep(100L); } catch(InterruptedException ex) {}
				}
			}
		}
		catch (IOException ex)
		{
			Logger.instance().debug1(module + " " + ex);
			if (owner != null)
				owner.inputError(ex);
			_shutdown = true;
		}
		catch(Exception ex)
		{
			String msg = module + " Unexpected exception: " + ex;
			Logger.instance().warning(msg);
			System.err.println(msg);
			ex.printStackTrace(System.err);
			if (owner != null)
				owner.inputError(ex);
			_shutdown = true;

		}
		Logger.instance().debug1(module + " exiting.");
	}
	
	public void shutdown()
	{
		Logger.instance().debug3(module + " shutdown() called.");
		_shutdown = true;
		// Note: mustn't close the InputStream, Multiple StreamReaders
		// may be used at various phases of a session on the same ioPort.
		// try { in.close(); } catch(IOException ex) {}
	}
	
//	private synchronized void growBuffer()
//	{
//		byte newbuf[] = new byte[sessionBuf.length + 8192];
//		for(int i=0; i 0)
			processIdx = patternMatcher[0].getProcessIdx();
		return false; // sec timed out without match
	}
		
	/**
	 * Start or stop capturing data for subsequent inclusion in DCP message
	 * @param capture true to turn capture on, false to turn it off.
	 */
	public void setCapture(boolean capture)
	{
		this.capture = capture;
		this.processIdx = sessionIdx;
		Logger.instance().debug3(module + " capture=" + capture + ", processIdx=" + processIdx);
	}
	
	/**
	 * Discard any captured data and set processIdx such that only data received after
	 * this point will be processed by the wait and check methods.
	 */
	public void flushBacklog()
	{
		Logger.instance().debug3(module + " flushing backlog at sessionIdx=" + sessionIdx);
		this.processIdx = sessionIdx;
		captured.reset();
	}
	
	/**
	 * @return a byte array containing all data received when capture was ON.
	 */
	public byte[] getCapturedData()
	{
		return captured.toByteArray();
	}
	
//	/**
//	 * @return a byte array containing all data received during entire session.
//	 */
//	public byte[] getEntireSession()
//	{
//		byte [] ret = new byte[sessionIdx];
//		for(int i = 0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy