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

decodes.decoder.ScanOperation 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$
*
*  $State$
*
*  $Log$
*  Revision 1.6  2010/09/13 19:30:36  mmaloney
*  Scan should always jump to the specified label if the scan fails, even if the scan ran out of data.
*
*  Revision 1.5  2009/09/30 13:52:15  shweta
*  *** empty log message ***
*
*  Revision 1.4  2009/09/29 21:16:11  shweta
*  MOdified code  to scan pseudo binary characters.
*
*  Revision 1.3  2009/03/24 18:38:40  mjmaloney
*  Fix debug message
*
*  Revision 1.2  2008/11/20 18:49:25  mjmaloney
*  merge from usgs mods
*
*  Revision 1.1  2008/11/15 01:03:50  mmaloney
*  Moved from separate trees to common parent
*
*  Revision 1.11  2008/08/21 18:38:34  sedreyer
*  In displays, replaced references to the absolute byte position within a file
*  to a line number and character offset from the beginning of line.
*
*  Revision 1.10  2008/03/25 18:39:53  satin
*  Corrected the statements that set the "case sensitive" flag.
*  (The comparison on the property variable should  have been a string
*  comparison. )
*
*  Revision 1.9  2008/02/11 14:33:27  mmaloney
*  Removed misleading comment.
*
*  Revision 1.8  2008/02/07 15:42:41  satin
*  Added code to make format labels case-sensitive if the DECODES
*  property "decodesFormatLabelMode" equals "case-sensitive".
*
*  Revision 1.7  2007/12/11 01:05:18  mmaloney
*  javadoc cleanup
*
*  Revision 1.6  2004/08/31 16:31:22  mjmaloney
*  javadoc
*
*  Revision 1.5  2004/04/08 19:50:09  satin
*  Added code to generate an EndOfData exception when a skipline
*  operation goes past the end of data.
*
*  Revision 1.4  2003/02/01 19:05:18  mjmaloney
*  Improved debug messages on field ops.
*
*  Revision 1.3  2002/09/30 18:54:34  mjmaloney
*  SQL dev.
*
*  Revision 1.2  2001/05/21 13:38:50  mike
*  dev
*
*  Revision 1.1  2001/05/06 23:04:02  mike
*  dev
*
*
*/
package decodes.decoder;

import ilex.util.ArgumentTokenizer;
import ilex.util.Logger;

import decodes.db.DecodesScript;
import decodes.db.FormatStatement;
import decodes.util.DecodesSettings;

/**
DecodesScanCommand is a DecodesOperation that scans data for a pattern.
*/
public class ScanOperation extends DecodesOperation 
{
	private int numChars;
	private FormatStatement newFormat;
	private char scanFor;
	private String scanString;
	private char scanChar;

	private static final char SCAN_FOR_SIGN = 's';
	private static final char SCAN_FOR_NUMBER = 'n';
	private static final char SCAN_FOR_STRING = '\'';
	private static final char SCAN_FOR_CHAR = 'c';
	private static final char SCAN_FOR_LETTER = 'a';
	private static final char SCAN_FOR_PSEUDOBINAY = 'p';
	// Format Label mode
	private boolean labelIsCaseSensitive = false;

	public char getType() { return 's'; }

	/**
	  Constructor.
	  @param  args complete string inside the parens
	  @param  ds the DecodesScript that this operation belongs to
	  @throws ScriptFormatException if syntax error detected in arguments
	*/
	public ScanOperation(String args, DecodesScript ds)
		throws ScriptFormatException
	{
		super(1);  // By definition, only 1 repetition.

		DecodesSettings settings = DecodesSettings.instance();
		if ( settings.decodesFormatLabelMode.equals("case-sensitive" ) )
			labelIsCaseSensitive = true;	
		numChars = 1;
		scanString = null;
		scanChar = (char)0;

		ArgumentTokenizer tokenizer = new ArgumentTokenizer(args, !labelIsCaseSensitive);

		String nstr = tokenizer.getNextToken();
		if (nstr == null)
			throw new ScriptFormatException("Scan operation with no 'n'");
		try { numChars = Integer.parseInt(nstr); }
		catch(NumberFormatException e)
		{
			throw new ScriptFormatException(
				"Exception integer number-of-chars in scan operation.");
		}

		String what = tokenizer.getNextToken();
		if (what == null)
			throw new ScriptFormatException("No target in scan operation");
		boolean quoted = tokenizer.wasQuoted();

		String label = tokenizer.getNextToken();
		if (label == null)
			throw new ScriptFormatException("No label in check operation");
		newFormat = ds.getFormatStatement(label);
		if (newFormat == null)
			throw new ScriptFormatException("No such format statement '"
				 + label + "'");

		if (quoted)
		{
			if (what.length() == 1)
			{
				scanFor = SCAN_FOR_CHAR;
				scanChar = what.charAt(0);
			}
			else
			{
				scanFor = SCAN_FOR_STRING;
				scanString = what;
			}
		}
		else if (what.toLowerCase().charAt(0) == 's')
		{
			scanFor = SCAN_FOR_SIGN;
		}
		else if (what.toLowerCase().charAt(0) == 'n')
		{
			scanFor = SCAN_FOR_NUMBER;
		}
		else if (what.toLowerCase().charAt(0) == 'a')
		{
			scanFor = SCAN_FOR_LETTER;
		}
		else if (what.toLowerCase().charAt(0) == 'p')
		{
			scanFor = SCAN_FOR_PSEUDOBINAY;
		}
		else
			throw new ScriptFormatException("Illegal target in scan operation");
	}


	/**
	  Executes this operation using the context provided.
	  @param dd holds the raw data and context.
	  @param msg store decoded values here.
	  @throws DecoderException or subclass if error detected.
	*/
	public void execute(DataOperations dd, DecodedMessage msg) 
		throws DecoderException
	{
		boolean found = false;
		int n;

		for(n=0; !found  && n < repetitions; n++ ) 
	    	switch(scanFor) 
			{
			case SCAN_FOR_NUMBER:
				found = dd.scanNum(numChars);
				break;

			case SCAN_FOR_STRING:
				Logger.instance().log(Logger.E_DEBUG3, "Scanning "
					+ numChars + " bytes for '" + scanString + "' on line " 
					+ dd.getCurrentLine() + " at position "
					+ dd.getRelBytePos());
				found = dd.scanString(numChars, scanString);
				break;

			case SCAN_FOR_CHAR:
				Logger.instance().log(Logger.E_DEBUG3, "Scanning "
					+ numChars + " bytes for '" + scanChar + "' on line " 
					+ dd.getCurrentLine() + " at position "
					+ dd.getRelBytePos());
				found=dd.scanChar(numChars, (byte)scanChar);
				break;

			case SCAN_FOR_SIGN:
				found=dd.scanSign(numChars);
				break;

			case SCAN_FOR_LETTER:
				found=dd.scanAlpha(numChars);
				break;
				
			case SCAN_FOR_PSEUDOBINAY:				
				Logger.instance().log(Logger.E_DEBUG3, "Scanning data for pseudobinary characters");						
				found=dd.scanPseudoBinary(numChars);				
				break;
	    	}
		if (!found)
		{
// MJM - We don't want to do the following test. I might put:
// try_limits    s(100,'LIMITS=',try_data)
// try_data      0p, .... do something else.
// meaning that I want to scan entire message for the string 'LIMITS='.
// If it fails, I want to go to try_data which calls 0p to re-process the msg in
// a different way.
//			if (!dd.moreChars())
//				throw new EndOfDataException(
//					"End of data during scan operation");
	        throw new SwitchFormatException(newFormat);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy