/*
*
* Hamsam - Instant Messaging API
*
* Copyright (C) 2003 Mike Miller <mikemil@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package hamsam.protocol.aim.flap;
import java.io.IOException;
import java.net.SocketException;
import hamsam.exception.IllegalArgumentException;
import hamsam.exception.IllegalStateException;
import hamsam.net.Connection;
import hamsam.protocol.aim.util.ByteUtils;
/**
* @author mike
*/
public class FlapHeader {
public static final int FLAP_HDR_LENGTH = 6;
private byte channelId;
private int sequenceNumber;
private int dataLength;
/**
* Constructor
* @param byte[] byte array used to create FlapHeader
*/
public FlapHeader(byte[] bytes) throws IllegalArgumentException {
super();
if (bytes == null || bytes.length < FLAP_HDR_LENGTH) {
throw new IllegalArgumentException("FlapHeader constructor bytes parm length must be " + FLAP_HDR_LENGTH);
}
// check for preamble byte value
if (bytes[0] != FlapConstants.FLAP_PREAMBLE) {
throw new IllegalArgumentException("FlagHeader first byte=" + Integer.toHexString(bytes[0]) + " and not 0x2A");
}
channelId = bytes[1];
//set the sequence number and data length from the bytes
sequenceNumber = ByteUtils.getUShort(bytes, 2);
dataLength = ByteUtils.getUShort(bytes, 4);
}
/**
* Constructor
* @param channel channel number
* @param seqNum sequence number
*/
public FlapHeader(byte channel, int seqNum) {
channelId = channel;
sequenceNumber = seqNum;
}
/**
* Get the channel id for the flap header
* @return channel id of the flap header
*/
public byte getChannelId() {
return channelId;
}
/**
* Gets the data length found in the flap header
* @return data length found in the flap header
*/
public int getDataLength() {
return dataLength;
}
/**
* Sets the data length within the flap header
* @param length value to set the data length to
*/
public void setDataLength(int length) {
dataLength = length;
}
/**
* Get the sequence number from the flap header
* @return sequence number from the flap header
*/
public int getSequenceNumber() {
return sequenceNumber;
}
/**
* Gets a byte array of the flap header
* @return byte array representing the flap header
*/
public byte[] getBytes() {
byte[] bytes = new byte[FLAP_HDR_LENGTH];
bytes[0] = FlapConstants.FLAP_PREAMBLE;
bytes[1] = channelId;
bytes[2] = (byte) ((sequenceNumber >> 8) & 0xff);
bytes[3] = (byte) (sequenceNumber & 0xff);
bytes[4] = (byte) ((dataLength >> 8) & 0xff);
bytes[5] = (byte) (dataLength & 0xff);
return bytes;
}
/**
* Gets string representation of the flap header
* @return string representation of the flap header
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer sb = new StringBuffer(30);
sb.append("FlapHeader :").append("\t").append("preamble=").append("0x2A\t");
sb.append("channelid=").append(channelId).append("\t").append("sequenceNumber=");
sb.append(sequenceNumber).append("\tdataLength=").append(dataLength);
return sb.toString();
}
/**
* Reads a flap header from the network
* @param conn Connection used to read the flap header
* @return FlapHeader object
* @throws IOException when error encountered reading from the connection
* @throws IllegalStateException when invalid data read for the flap header,
* for example, if the premable is not 0x2a.
*/
public static FlapHeader getHeader(Connection conn) throws IOException, IllegalStateException {
byte[] hdr = new byte[FlapHeader.FLAP_HDR_LENGTH];
int pos = 0;
//try {
while (pos < hdr.length) {
final int count = conn.read(hdr, pos, hdr.length - pos);
// check the count to make sure we didn't hit EOF or lose connection
if (count == -1) {
return null;
}
pos += count;
}
//} catch (SocketException e) {
// e.printStackTrace();
// return null;
//}
FlapHeader flapHeader = null;
try {
flapHeader = new FlapHeader(hdr);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return flapHeader;
}
}