/*
* Copyright (C) 1996, 1997 By Radu Sion
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Radu Sion (radus@cs.pub.ro)
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* (radus@cs.pub.ro, http://www.dsp.pub.ro/radu.html)
*
*/
import Message;
import MessageConstants;
import util;
/**
* A class used in parsing a Message.
* Written: Radu Sion
* Version: 0.41
* Source: MessageParser.java
* @see Message
* @see MessageCreator
* @see MessageConstants
*/
public class
MessageParser
extends Object
{
/**
* Tests the validity of the Message.
* Should be used before any other call to a method of this class.
* The CRC is tested , also the whole header.
* @return Returns true if valid, false otherwise
* @param message The Message to test for validity
*/
public static boolean
isValid(Message message)
{
if (message == null) return false;
if (message.length() < MessageConstants.MIN_LENGTH) return false;
char message_id = message.charAt(MessageConstants.ID_INDEX);
return (
(message_id == MessageConstants.CTS_ID) ||
(message_id == MessageConstants.RESET_ID) ||
(message_id == MessageConstants.DATA_STRING_ID) ||
(message_id == MessageConstants.DATA_BYTES_ID) ||
(message_id == MessageConstants.DNF_ID) ||
(message_id == MessageConstants.DOWN_ID) ||
(message_id == MessageConstants.INVRQ_ID) ||
(message_id == MessageConstants.OK_ID) ||
(message_id == MessageConstants.CHGRP_ID) ||
(message_id == MessageConstants.NOP_ID)
);
}
/**
* Tries to get a human readable description of the Message.
* @return A description String
* @param message The Message to describe
*/
public static String
getDescription(Message message)
{
return "Method MessageParser.getDescription() not implemented yet";
}
/**
* Gets the sender number of the Message sender.
* @param message The Message to use
*/
public static int
getSender(Message message)
{
return message.getInt(MessageConstants.SENDER_ID_INDEX);
}
/**
* Gets the destination number of the Message destination.
* @param message The Message to use
*/
public static int
getDestination(Message message)
{
return message.getInt(MessageConstants.DESTINATION_ID_INDEX);
}
/**
* Gets the sender group number of the Message sender.
* @param message The Message to use
*/
public static int
getSenderGroup(Message message)
{
return message.getInt(MessageConstants.SENDER_GROUP_ID_INDEX);
}
/**
* Gets the destination group number of the Message destination.
* @param message The Message to use
*/
public static int
getDestinationGroup(Message message)
{
return message.getInt(MessageConstants.DESTINATION_GROUP_ID_INDEX);
}
/**
* Tests if it's a INVRQ (Invalid Request) Message.
* The INVRQ is generated by the server only.
* @param message The Message to use
* @return Returns true if INVRQ, false otherwise
*/
public static boolean
isINVRQ(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.INVRQ_ID)
return true;
return false;
}
/**
* Tests if it's a OK Message.
* The OK is generated also by the server as a confirmation of a fullfiled request.
* @param message The Message to use
* @return Returns true if OK, false otherwise
*/
public static boolean
isOK(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.OK_ID)
return true;
return false;
}
/**
* Test if it's a CHGRP (Change Group) Message.
* The CHGRP is generated by a client only when it wishes to change it's group
* @param message The Message to use
* @return It returns the wanted new group if ok, MessageConstants.INVALID otherwise
*/
public static int
isCHGRP(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.CHGRP_ID)
return message.getInt(MessageConstants.DATA_BEGIN_INDEX);
return MessageConstants.INVALID;
}
/**
* Tests if it's a DOWN (client is down) Message.
* The DOWN is generated by the server when a client is down, in order to notify other clients.
* Not implemented yet. [SUBJECT TO CHANGE !!!]
* @param message The Message to use
* @return It returns the client number that went down if ok, MessageConstants.INVALID otherwise
*/
public static int
isDOWN(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DOWN_ID)
return message.getInt(MessageConstants.DATA_BEGIN_INDEX);
return MessageConstants.INVALID;
}
/**
* Tests if it's a NOP (No Operation == ignore) Message.
* @param message The Message to use
* @return Returns true if it's NOP, false otherwise
*/
public static boolean
isNOP(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.NOP_ID)
return true;
return false;
}
/**
* Tests if it's a CTS (Request to send) Message.
* CTS is server-generated when the client is free to send Messages again.
* @param message The Message to use
* @return Returns true if it's CTS, false otherwise
*/
public static boolean
isCTS(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.CTS_ID)
return true;
return false;
}
/**
* Tests if it's a DNF (Destination not found) Message.
* DFN is some INVRQ and should be obsoleted by it.
* @param message The Message to use
* @return Returns the destination client number if it's DNF, MessageConstants.INVALID otherwise
*/
public static int
isDNF(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DNF_ID)
return message.getInt(MessageConstants.DATA_BEGIN_INDEX);
return MessageConstants.INVALID;
}
/**
* Tests if it's a RESET Message.
* RESET is server generated. On receiving it, the client should efectively reset.
* @param message The Message to test
* @return Returns true if it's RESET, false otherwise
*/
public static boolean
isRESET(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.RESET_ID)
return true;
return false;
}
/**
* Tests if it's a DataXXXXX Message.
* @param message The Message to test
* @return True if it a data message, false otherwise
*/
public static boolean
isData(Message message)
{
if ((message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DATA_STRING_ID) ||
(message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DATA_BYTES_ID))
return true;
return false;
}
/**
* Tests if it's a DataString Message.
* @param message The Message to test
* @return The sender number if it's DataString, MessageConstants.INVALID otherwise
*/
public static int
isDataString(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DATA_STRING_ID)
return message.getInt(MessageConstants.SENDER_ID_INDEX);
return MessageConstants.INVALID;
}
/**
* Tests if it's a DataBytes Message.
* @param message The Message to test
* @return The sender number if it's DataBytes, MessageConstants.INVALID otherwise
*/
public static int
isDataBytes(Message message)
{
if (message.charAt(MessageConstants.ID_INDEX) == MessageConstants.DATA_BYTES_ID)
return message.getInt(MessageConstants.SENDER_ID_INDEX);
return MessageConstants.INVALID;
}
/**
* Gets the byte array if it's a DataBytes or DataString Message.
* @param message The Message to use
* @return Returns a byte array if it's DataBytes, null otherwise
*/
public static byte[]
getDataBytes(Message message)
{
if ((isDataBytes(message) == MessageConstants.INVALID) &&
(isDataString(message) == MessageConstants.INVALID))
return null;
byte dd[] = message.getBytes();
return util.bytescut(MessageConstants.DATA_BEGIN_INDEX,dd.length-1,dd);
}
/**
* Gets the String if it's a DataString or DataBytes Message.
* @param message The Message to use
* @return Returns a String if it's DataString, null otherwise
*/
public static String
getDataString(Message message)
{
if ((isDataString(message) == MessageConstants.INVALID) &&
(isDataBytes(message) == MessageConstants.INVALID))
return null;
byte dd[] = message.getBytes();
return new String(dd,0,MessageConstants.DATA_BEGIN_INDEX,dd.length - MessageConstants.DATA_BEGIN_INDEX);
}
/**
* Gets a character from the data area of the Message
* Treating the Message as a Data
* Message (DataBytes, DataString)
* (no checkings are done to ensure that it's really a Data Message)
* @param message The Message to use
* @param index Index in the data area of the Message
* @return Returns a character from the data area of the Message
*/
public static char
getDataChar(Message message, int index)
{
return message.charAt(index+MessageConstants.DATA_BEGIN_INDEX);
}
/**
* Gets a byte from the data area of the Message
* Treating the Message as a Data
* Message (DataBytes, DataString etc) !!!
* (no checkings are done to ensure that it's really a Data Message)
* @param message The Message to use
* @param index Index in the data area of the Message
* @return Returns a byte from the data area of the Message
*/
public static byte
getDataByte(Message message, int index)
{
return message.byteAt(index+MessageConstants.DATA_BEGIN_INDEX);
}
}
/*eoc*/