xref: /illumos-gate/usr/src/lib/libslp/javalib/com/sun/slp/SrvLocHeader.java (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9a70fc3bSMark J. Nelson  * Common Development and Distribution License (the "License").
6*9a70fc3bSMark J. Nelson  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate //  SrvLocHeader.java: Abstract superclass for SLP Headers
287c478bd9Sstevel@tonic-gate //  Author:           James Kempf
297c478bd9Sstevel@tonic-gate //  Created On:       Mon Sep 14 12:47:20 1998
307c478bd9Sstevel@tonic-gate //  Last Modified By: James Kempf
317c478bd9Sstevel@tonic-gate //  Last Modified On: Mon Nov 23 14:32:50 1998
327c478bd9Sstevel@tonic-gate //  Update Count:     55
337c478bd9Sstevel@tonic-gate //
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate package com.sun.slp;
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate import java.util.*;
387c478bd9Sstevel@tonic-gate import java.net.*;
397c478bd9Sstevel@tonic-gate import java.io.*;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /**
427c478bd9Sstevel@tonic-gate  * SrvLocHeader handles different versions of the SLP header. Clients
437c478bd9Sstevel@tonic-gate  * call the instance methods returned by newInstance(). If no version
447c478bd9Sstevel@tonic-gate  * specific subclass exists for the version number, null is returned
457c478bd9Sstevel@tonic-gate  * from newInstance. Parsing of the header and message bodies, and
467c478bd9Sstevel@tonic-gate  * creation of error replies are handled by the version specific
477c478bd9Sstevel@tonic-gate  * subclasses. We also let the SrvLocHeader serve as a SrvLocMsg object
487c478bd9Sstevel@tonic-gate  * to handle the SrvAck, which only has an error code.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * @author James Kempf
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate abstract class SrvLocHeader extends Object implements SrvLocMsg, Cloneable {
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate     // Table of header classes. Keys are the version number.
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate     private static final Hashtable classTable = new Hashtable();
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate     // Offset to XID.
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate     static final int XID_OFFSET = 10;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate     // Common constants and instance variables.
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate     // Number of bytes in the version and function fields.
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate     static int VERSION_FUNCTION_BYTES = 2;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate     // SLP function codes. Even though SAAdvert isn't in all versions,
707c478bd9Sstevel@tonic-gate     //  we include it here.
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate     static final int SrvReq  = 1;
737c478bd9Sstevel@tonic-gate     static final int SrvRply = 2;
747c478bd9Sstevel@tonic-gate     static final int SrvReg = 3;
757c478bd9Sstevel@tonic-gate     static final int SrvDereg = 4;
767c478bd9Sstevel@tonic-gate     static final int SrvAck = 5;
777c478bd9Sstevel@tonic-gate     static final int AttrRqst = 6;
787c478bd9Sstevel@tonic-gate     static final int AttrRply = 7;
797c478bd9Sstevel@tonic-gate     static final int DAAdvert = 8;
807c478bd9Sstevel@tonic-gate     static final int SrvTypeRqst = 9;
817c478bd9Sstevel@tonic-gate     static final int SrvTypeRply = 10;
827c478bd9Sstevel@tonic-gate     static final int SAAdvert = 11;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate     static final String[] functionCodeAbbr = {
857c478bd9Sstevel@tonic-gate 	"0",
867c478bd9Sstevel@tonic-gate 	"SrvReq",
877c478bd9Sstevel@tonic-gate 	"SrvRply",
887c478bd9Sstevel@tonic-gate 	"SrvReg",
897c478bd9Sstevel@tonic-gate 	"SrvDereg",
907c478bd9Sstevel@tonic-gate 	"SrvAck",
917c478bd9Sstevel@tonic-gate 	"AttrRqst",
927c478bd9Sstevel@tonic-gate 	"AttrRply",
937c478bd9Sstevel@tonic-gate 	"DAAdvert",
947c478bd9Sstevel@tonic-gate 	"SrvTypeRqst",
957c478bd9Sstevel@tonic-gate 	"SrvTypeRply",
967c478bd9Sstevel@tonic-gate 	"SAAdvert",
977c478bd9Sstevel@tonic-gate     };
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate     // Sizes of data items.
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate     protected static final int BYTE_SIZE = 1;
1027c478bd9Sstevel@tonic-gate     protected static final int SHORT_SIZE = 2;
1037c478bd9Sstevel@tonic-gate     protected static final int INT24_SIZE = 3;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate     //
1067c478bd9Sstevel@tonic-gate     // Header instance variables.
1077c478bd9Sstevel@tonic-gate     //
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate     // Unprotected for less code.
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate     int    version = 0;			// version number
1127c478bd9Sstevel@tonic-gate     int    functionCode = 0;		// function code
1137c478bd9Sstevel@tonic-gate     int    length = 0;			// packet length
1147c478bd9Sstevel@tonic-gate     short  xid = 0;			// transaction id
1157c478bd9Sstevel@tonic-gate     short  errCode =
1167c478bd9Sstevel@tonic-gate 	ServiceLocationException.OK;	// not applicable to start
1177c478bd9Sstevel@tonic-gate     Locale locale = Defaults.locale;	// language locale
1187c478bd9Sstevel@tonic-gate     Vector previousResponders = null;	// list of previous responders
1197c478bd9Sstevel@tonic-gate     Vector scopes = null;		// list of scopes
1207c478bd9Sstevel@tonic-gate     boolean overflow = false;		// Overflow flag
1217c478bd9Sstevel@tonic-gate     boolean fresh = false;		// Fresh flag
1227c478bd9Sstevel@tonic-gate     boolean mcast = false;		// Mulitcast flag.
1237c478bd9Sstevel@tonic-gate     byte[] payload = new byte[0];	// bytes of outgoing payload,
1247c478bd9Sstevel@tonic-gate     int nbytes = 0;			// number of bytes processed
1257c478bd9Sstevel@tonic-gate     int packetLength = 0;		// length of packet.
1267c478bd9Sstevel@tonic-gate     int iNumReplies = 0;		// number of replies.
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate     protected static short uniqueXID = 0;	// outgoing transaction id.
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate     // Message description.
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate     private String msgType;
1347c478bd9Sstevel@tonic-gate     private String msgDescription;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 
SrvLocHeader()1377c478bd9Sstevel@tonic-gate     SrvLocHeader() {
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	packetLength = SLPConfig.getSLPConfig().getMTU();
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate     }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate     //
1447c478bd9Sstevel@tonic-gate     // SrvLocMsg Implementation.
1457c478bd9Sstevel@tonic-gate     //
1467c478bd9Sstevel@tonic-gate 
getHeader()1477c478bd9Sstevel@tonic-gate     public SrvLocHeader getHeader() {
1487c478bd9Sstevel@tonic-gate 	return this;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate     }
1517c478bd9Sstevel@tonic-gate 
getErrorCode()1527c478bd9Sstevel@tonic-gate     public short getErrorCode() {
1537c478bd9Sstevel@tonic-gate 	return errCode;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate     }
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate     // Return number of replies to this message.
1587c478bd9Sstevel@tonic-gate 
getNumReplies()1597c478bd9Sstevel@tonic-gate     public int getNumReplies() {
1607c478bd9Sstevel@tonic-gate 	return iNumReplies;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate     }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate     //
1657c478bd9Sstevel@tonic-gate     // SrvLocHeader Interface.
1667c478bd9Sstevel@tonic-gate     //
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate     // Register a new header class for version. Serious error, causing
1697c478bd9Sstevel@tonic-gate     //  program termination, if we can't find it.
1707c478bd9Sstevel@tonic-gate 
addHeaderClass(String className, int version)1717c478bd9Sstevel@tonic-gate     static void addHeaderClass(String className, int version) {
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	try {
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	    Class headerClass = Class.forName(className);
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	    classTable.put(new Integer(version), headerClass);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	} catch (ClassNotFoundException ex) {
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	    Assert.slpassert(false,
1827c478bd9Sstevel@tonic-gate 			  "no_class",
1837c478bd9Sstevel@tonic-gate 			  new Object[] {className});
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	}
1867c478bd9Sstevel@tonic-gate     }
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate     // Create a version specific instance. We use a naming convention
1897c478bd9Sstevel@tonic-gate     //  to identify the version specific classes used to create the
1907c478bd9Sstevel@tonic-gate     //  instance.
1917c478bd9Sstevel@tonic-gate 
newInstance(int version)1927c478bd9Sstevel@tonic-gate     static SrvLocHeader newInstance(int version) {
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	try {
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	    // Get header class.
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	    Class hdrClass = (Class)classTable.get(new Integer(version));
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	    if (hdrClass == null) {
2017c478bd9Sstevel@tonic-gate 		return null;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	    }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	    SrvLocHeader hdr = (SrvLocHeader)hdrClass.newInstance();
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	    return hdr;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	} catch (Exception ex) {
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	    SLPConfig.getSLPConfig().writeLog("slh_creation_exception",
2127c478bd9Sstevel@tonic-gate 					      new Object[] {
2137c478bd9Sstevel@tonic-gate 		new Integer(version),
2147c478bd9Sstevel@tonic-gate 		    ex,
2157c478bd9Sstevel@tonic-gate 		    ex.getMessage()});
2167c478bd9Sstevel@tonic-gate 	    return null;
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate     }
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate     // Parse the incoming stream to obtain the header.
2237c478bd9Sstevel@tonic-gate 
parseHeader(int functionCode, DataInputStream dis)2247c478bd9Sstevel@tonic-gate     abstract void parseHeader(int functionCode, DataInputStream dis)
2257c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException, IllegalArgumentException;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate     // Parse the incoming stream to obtain the message.
2287c478bd9Sstevel@tonic-gate 
parseMsg(DataInputStream dis)2297c478bd9Sstevel@tonic-gate     abstract SrvLocMsg parseMsg(DataInputStream dis)
2307c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException, IllegalArgumentException;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate     // Externalize the message.
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate     abstract void
externalize(ByteArrayOutputStream baos, boolean multicast, boolean isTCP)2357c478bd9Sstevel@tonic-gate 	externalize(ByteArrayOutputStream baos,
2367c478bd9Sstevel@tonic-gate 		    boolean multicast,
2377c478bd9Sstevel@tonic-gate 		    boolean isTCP)
2387c478bd9Sstevel@tonic-gate 	throws ServiceLocationException;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate     // Return the appropriately versioned DAAdvert.
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate     abstract SDAAdvert
getDAAdvert(short xid, long timestamp, ServiceURL url, Vector scopes, Vector attrs)2437c478bd9Sstevel@tonic-gate 	getDAAdvert(short xid,
2447c478bd9Sstevel@tonic-gate 		    long timestamp,
2457c478bd9Sstevel@tonic-gate 		    ServiceURL url,
2467c478bd9Sstevel@tonic-gate 		    Vector scopes,
2477c478bd9Sstevel@tonic-gate 		    Vector attrs)
2487c478bd9Sstevel@tonic-gate 	throws ServiceLocationException;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate     //
2517c478bd9Sstevel@tonic-gate     // Methods that some subclasses may reimplement.
2527c478bd9Sstevel@tonic-gate     //
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate     // Parse any options.
2557c478bd9Sstevel@tonic-gate 
parseOptions(DataInputStream dis)2567c478bd9Sstevel@tonic-gate     void parseOptions(DataInputStream dis)
2577c478bd9Sstevel@tonic-gate 	throws ServiceLocationException,
2587c478bd9Sstevel@tonic-gate 	       IOException,
2597c478bd9Sstevel@tonic-gate 	       IllegalArgumentException {
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate     }
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate     // Create an error reply for this message. This reply will be appropriate
2647c478bd9Sstevel@tonic-gate     //  for the server to send back to the client. Default is to do nothing,
2657c478bd9Sstevel@tonic-gate     //  which is the code for the client.
2667c478bd9Sstevel@tonic-gate 
makeErrorReply(Exception ex)2677c478bd9Sstevel@tonic-gate     SrvLocMsg makeErrorReply(Exception ex) {
2687c478bd9Sstevel@tonic-gate 	return null;
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate     }
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate     //
2737c478bd9Sstevel@tonic-gate     //  Common utilities for all versions.
2747c478bd9Sstevel@tonic-gate     //
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate     // Set the packet length to the incoming value.
2777c478bd9Sstevel@tonic-gate 
setPacketLength(int newLength)2787c478bd9Sstevel@tonic-gate     void setPacketLength(int newLength) {
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	if (newLength > 0) {
2817c478bd9Sstevel@tonic-gate 	    packetLength = newLength;
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate     }
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate     // Add an Internet address to the previous responders list.
2877c478bd9Sstevel@tonic-gate 
addPreviousResponder(InetAddress addr)2887c478bd9Sstevel@tonic-gate     void addPreviousResponder(InetAddress addr) {
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	String hostAddr = addr.getHostAddress();
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	Assert.slpassert((previousResponders != null),
2937c478bd9Sstevel@tonic-gate 		      "prev_resp_reply",
2947c478bd9Sstevel@tonic-gate 		      new Object[0]);
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	if (!previousResponders.contains(hostAddr)) {
2977c478bd9Sstevel@tonic-gate 	    previousResponders.addElement(hostAddr);
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate     }
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate     // Get a unique transaction id.
3037c478bd9Sstevel@tonic-gate 
getUniqueXID()3047c478bd9Sstevel@tonic-gate     synchronized static short getUniqueXID() {
3057c478bd9Sstevel@tonic-gate 	if (uniqueXID == 0) {
3067c478bd9Sstevel@tonic-gate 	    Random r = new Random();
3077c478bd9Sstevel@tonic-gate 	    uniqueXID = (short)(r.nextInt() &0xFFFF);
3087c478bd9Sstevel@tonic-gate 	}
3097c478bd9Sstevel@tonic-gate 	uniqueXID++;
3107c478bd9Sstevel@tonic-gate 	return (short)(uniqueXID & 0xFFFF);
3117c478bd9Sstevel@tonic-gate     }
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate     // Parse 2-byte integer, bump byte count.
3147c478bd9Sstevel@tonic-gate 
getInt(DataInputStream dis)3157c478bd9Sstevel@tonic-gate     int getInt(DataInputStream dis)
3167c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException {
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	int ret = getInteger(dis);
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	nbytes += SHORT_SIZE;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	return ret;
3237c478bd9Sstevel@tonic-gate     }
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate     // Parse a 2-byte integer from the input stream.
3277c478bd9Sstevel@tonic-gate 
getInteger(DataInputStream dis)3287c478bd9Sstevel@tonic-gate     static int getInteger(DataInputStream dis)
3297c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException {
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	byte[] b = new byte[2];
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	dis.readFully(b, 0, 2);
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	int x = (int)((char)b[0] & 0xFF);
3367c478bd9Sstevel@tonic-gate 	int y = (int)((char)b[1] & 0xFF);
3377c478bd9Sstevel@tonic-gate 	int z = x << 8;
3387c478bd9Sstevel@tonic-gate 	z += y;
3397c478bd9Sstevel@tonic-gate 	return z;
3407c478bd9Sstevel@tonic-gate     }
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate     // Parse 2-byte integer, bump byte count.
3437c478bd9Sstevel@tonic-gate 
putInt(int z, ByteArrayOutputStream baos)3447c478bd9Sstevel@tonic-gate     void putInt(int z, ByteArrayOutputStream baos) {
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	putInteger(z, baos);
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	nbytes += SHORT_SIZE;
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate     }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate     // Parse a 2-byte integer to the output stream.
3537c478bd9Sstevel@tonic-gate 
putInteger(int z, ByteArrayOutputStream baos)3547c478bd9Sstevel@tonic-gate     static void putInteger(int z, ByteArrayOutputStream baos) {
3557c478bd9Sstevel@tonic-gate 	baos.write((byte) ((0xFF00 & z)>>8));
3567c478bd9Sstevel@tonic-gate 	baos.write((byte) (0xFF & z));
3577c478bd9Sstevel@tonic-gate     }
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate     // Parse a 3-byte integer from the byte input stream.
3617c478bd9Sstevel@tonic-gate 
getInt24(DataInputStream dis)3627c478bd9Sstevel@tonic-gate     protected int getInt24(DataInputStream dis)
3637c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException {
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	byte[] b = new byte[3];
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	dis.readFully(b, 0, 3);
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	int w = (int)((char)b[0] & 0xFF);
3707c478bd9Sstevel@tonic-gate 	int x = (int)((char)b[1] & 0xFF);
3717c478bd9Sstevel@tonic-gate 	int y = (int)((char)b[2] & 0xFF);
3727c478bd9Sstevel@tonic-gate 	int z = w << 16;
3737c478bd9Sstevel@tonic-gate 	z += x << 8;
3747c478bd9Sstevel@tonic-gate 	z += y;
3757c478bd9Sstevel@tonic-gate 	nbytes += 3;
3767c478bd9Sstevel@tonic-gate 	return z;
3777c478bd9Sstevel@tonic-gate     }
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate     // Parse a 3-byte integer to the output stream.
3807c478bd9Sstevel@tonic-gate 
putInt24(int z, ByteArrayOutputStream baos)3817c478bd9Sstevel@tonic-gate     protected void putInt24(int z, ByteArrayOutputStream baos) {
3827c478bd9Sstevel@tonic-gate 	baos.write((byte) ((0xFF0000 & z) >> 16));
3837c478bd9Sstevel@tonic-gate 	baos.write((byte) ((0xFF00 & z)>>8));
3847c478bd9Sstevel@tonic-gate 	baos.write((byte) (0xFF & z));
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	nbytes += 3;
3877c478bd9Sstevel@tonic-gate     }
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate     // Parse string, bump byte count. Use UTF8 encoding.
3917c478bd9Sstevel@tonic-gate 
getString(StringBuffer buf, DataInputStream dis)3927c478bd9Sstevel@tonic-gate     byte[] getString(StringBuffer buf, DataInputStream dis)
3937c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException {
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	byte[] ret = getStringField(buf, dis, Defaults.UTF8);
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 	nbytes += ret.length + SHORT_SIZE;
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 	return ret;
4007c478bd9Sstevel@tonic-gate     }
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate     // Parse a string with an initial length from the input stream.
4037c478bd9Sstevel@tonic-gate     //  Convert it to the proper encoding. Return the raw bytes for
4047c478bd9Sstevel@tonic-gate     //  auth block creation.
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate     static byte[]
getStringField(StringBuffer buf, DataInputStream dis, String encoding)4077c478bd9Sstevel@tonic-gate 	getStringField(StringBuffer buf, DataInputStream dis, String encoding)
4087c478bd9Sstevel@tonic-gate 	throws ServiceLocationException, IOException {
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	// Clear out buffer first.
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	buf.setLength(0);
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	// First get the length.
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	int i, n = 0;
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	n = getInteger(dis);
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	// Now get the bytes.
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	byte[] bytes = new byte[n];
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	dis.readFully(bytes, 0, n);
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 	// Convert to string and return.
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	buf.append(getBytesString(bytes, encoding));
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	return bytes;
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate     }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate     // Parse out string, bump byte count. Use UTF8 encoding.
4357c478bd9Sstevel@tonic-gate 
putString(String string, ByteArrayOutputStream baos)4367c478bd9Sstevel@tonic-gate     byte[] putString(String string, ByteArrayOutputStream baos) {
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	byte[] bytes = putStringField(string, baos, Defaults.UTF8);
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 	nbytes += bytes.length + SHORT_SIZE;
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	return bytes;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate     }
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate     // Put a string with an initial length into the byte stream, converting
4477c478bd9Sstevel@tonic-gate     //  into the proper encoding.
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate     static byte[]
putStringField(String string, ByteArrayOutputStream baos, String encoding)4507c478bd9Sstevel@tonic-gate 	putStringField(String string,
4517c478bd9Sstevel@tonic-gate 		       ByteArrayOutputStream baos,
4527c478bd9Sstevel@tonic-gate 		       String encoding) {
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	byte[] bytes = getStringBytes(string, encoding);
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	// Put out the string's length in the encoding.
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	putInteger(bytes.length, baos);
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	// Now really write out the bytes.
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	baos.write(bytes, 0, bytes.length);
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	return bytes;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate     }
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate     // Convert a Unicode string into encoded bytes.
4697c478bd9Sstevel@tonic-gate 
getStringBytes(String string, String encoding)4707c478bd9Sstevel@tonic-gate     static byte[] getStringBytes(String string, String encoding) {
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	try {
4737c478bd9Sstevel@tonic-gate 	    return string.getBytes(encoding);
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 	} catch (UnsupportedEncodingException ex) {
4767c478bd9Sstevel@tonic-gate 	    return  new byte[0];  // won't happen, hopefully...
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	}
4797c478bd9Sstevel@tonic-gate     }
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate     // Convert bytes into a Unicode string.
4827c478bd9Sstevel@tonic-gate 
getBytesString(byte[] bytes, String encoding)4837c478bd9Sstevel@tonic-gate     static String getBytesString(byte[] bytes, String encoding) {
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 	try {
4867c478bd9Sstevel@tonic-gate 	    return new String(bytes, encoding);
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	} catch (UnsupportedEncodingException ex) {
4897c478bd9Sstevel@tonic-gate 	    return "";  // won't happen, hopefully ...
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	}
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate     }
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate     // Parse a comma separated list of strings from the vector into the
4967c478bd9Sstevel@tonic-gate     //  output stream.
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate     protected byte[]
parseCommaSeparatedListOut(Vector v, ByteArrayOutputStream baos)4997c478bd9Sstevel@tonic-gate 	parseCommaSeparatedListOut(Vector v,
5007c478bd9Sstevel@tonic-gate 				   ByteArrayOutputStream baos) {
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	return putString(vectorToCommaSeparatedList(v), baos);
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate     }
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate     /**
5077c478bd9Sstevel@tonic-gate      * Create a comma separated list of strings out of the vector.
5087c478bd9Sstevel@tonic-gate      *
5097c478bd9Sstevel@tonic-gate      * @param v A Vector of strings.
5107c478bd9Sstevel@tonic-gate      */
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate     static String
vectorToCommaSeparatedList(Vector v)5137c478bd9Sstevel@tonic-gate 	vectorToCommaSeparatedList(Vector v) {
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	// Construct in a string buffer first.
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	int i, n = v.size();
5187c478bd9Sstevel@tonic-gate 	StringBuffer buf = new StringBuffer();
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
5227c478bd9Sstevel@tonic-gate 	    String string = (String)v.elementAt(i);
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 	    // Add comma for previous one if we need it.
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	    if (i != 0) {
5277c478bd9Sstevel@tonic-gate 		buf.append(',');
5287c478bd9Sstevel@tonic-gate 	    }
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	    buf.append(string);
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 	}
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	// Return the bytes.
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 	return buf.toString();
5377c478bd9Sstevel@tonic-gate     }
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate     /**
5407c478bd9Sstevel@tonic-gate      * @parameter The string has the format = STRING *("," STRING)
5417c478bd9Sstevel@tonic-gate      * @parameter A boolean indicating whether parens should be ignored or
5427c478bd9Sstevel@tonic-gate      * 		used for grouping.
5437c478bd9Sstevel@tonic-gate      * @return  A vector (of Strings) based upon the (comma delimited) string.
5447c478bd9Sstevel@tonic-gate      */
parseCommaSeparatedListIn(String s, boolean ignoreParens)5457c478bd9Sstevel@tonic-gate     static Vector parseCommaSeparatedListIn(String s, boolean ignoreParens)
5467c478bd9Sstevel@tonic-gate 	throws ServiceLocationException {
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	if (s == null)
5497c478bd9Sstevel@tonic-gate 	    return new Vector();
5507c478bd9Sstevel@tonic-gate 	if (s.length() == 0)
5517c478bd9Sstevel@tonic-gate 	    return new Vector();
5527c478bd9Sstevel@tonic-gate 	StringTokenizer st = new StringTokenizer(s, ",()", true);
5537c478bd9Sstevel@tonic-gate 	try {
5547c478bd9Sstevel@tonic-gate 	    int level = 0;
5557c478bd9Sstevel@tonic-gate 	    String el = "";
5567c478bd9Sstevel@tonic-gate 	    Vector v = new Vector();
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	    while (st.hasMoreElements()) {
5597c478bd9Sstevel@tonic-gate 		String tok = st.nextToken();
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate 		// It's an open paren, so begin collecting.
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 		if (tok.equals("(")) {
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 		    // Increment the level if not ignoring parens, add to token
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 		    if (!ignoreParens) {
5687c478bd9Sstevel@tonic-gate 			level++;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 		    }
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 		    el += tok;
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 		} else if (tok.equals(")")) {
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 		    // Decrement level if not ignoring parens.
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 		    if (!ignoreParens) {
5797c478bd9Sstevel@tonic-gate 			level--;
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 		    }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 		    el += tok;
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 		} else if (tok.equals(",")) {
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 		    // Add if collecting.
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 		    if (level != 0) {
5907c478bd9Sstevel@tonic-gate 			el += tok;
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 		    } else {
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 			// Check for empty token.
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 			if (el.length() <= 0) {
5977c478bd9Sstevel@tonic-gate 			    throw
5987c478bd9Sstevel@tonic-gate 				new ServiceLocationException(
5997c478bd9Sstevel@tonic-gate 					ServiceLocationException.PARSE_ERROR,
6007c478bd9Sstevel@tonic-gate 					"csl_syntax_error",
6017c478bd9Sstevel@tonic-gate 					new Object[] {s});
6027c478bd9Sstevel@tonic-gate 			}
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 			// If not collecting, then close off the element.
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 			v.addElement(el);
6077c478bd9Sstevel@tonic-gate 			el = "";
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 		    }
6107c478bd9Sstevel@tonic-gate 		} else {
6117c478bd9Sstevel@tonic-gate 		    el += tok;
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate 		}
6147c478bd9Sstevel@tonic-gate 	    }
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 	    // Add last token, but check first for empty token.
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	    if (el.length() <= 0) {
6197c478bd9Sstevel@tonic-gate 		throw
6207c478bd9Sstevel@tonic-gate 		    new ServiceLocationException(
6217c478bd9Sstevel@tonic-gate 				ServiceLocationException.PARSE_ERROR,
6227c478bd9Sstevel@tonic-gate 				"csl_syntax_error",
6237c478bd9Sstevel@tonic-gate 				new Object[] {s});
6247c478bd9Sstevel@tonic-gate 	    }
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 	    v.addElement(el);
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	    // If we're still collecting on close, then there's a syntax error.
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 	    if (level != 0) {
6317c478bd9Sstevel@tonic-gate 		throw
6327c478bd9Sstevel@tonic-gate 		    new ServiceLocationException(
6337c478bd9Sstevel@tonic-gate 				ServiceLocationException.PARSE_ERROR,
6347c478bd9Sstevel@tonic-gate 				"csl_syntax_error",
6357c478bd9Sstevel@tonic-gate 				new Object[] {s});
6367c478bd9Sstevel@tonic-gate 	    }
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 	    return v;
6397c478bd9Sstevel@tonic-gate 	} catch (NoSuchElementException nsee) {
6407c478bd9Sstevel@tonic-gate 	    throw
6417c478bd9Sstevel@tonic-gate 		new ServiceLocationException(
6427c478bd9Sstevel@tonic-gate 				ServiceLocationException.PARSE_ERROR,
6437c478bd9Sstevel@tonic-gate 				"csl_syntax_error",
6447c478bd9Sstevel@tonic-gate 				new Object[] {s});
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	}
6477c478bd9Sstevel@tonic-gate     }
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate     // Allow clients to clone the header.
6507c478bd9Sstevel@tonic-gate 
clone()6517c478bd9Sstevel@tonic-gate     public Object clone()
6527c478bd9Sstevel@tonic-gate 	throws CloneNotSupportedException {
6537c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = (SrvLocHeader)super.clone();
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 	// Reinitialize some stuff. Subclasses must reimplement nbytes
6567c478bd9Sstevel@tonic-gate 	//  header size calculation.
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	hdr.length = 0;
6597c478bd9Sstevel@tonic-gate 	hdr.payload = new byte[0];
6607c478bd9Sstevel@tonic-gate 	hdr.iNumReplies = 0;
6617c478bd9Sstevel@tonic-gate 	// packetlength stays the same, we may be using the same transport.
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	return hdr;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate     }
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate     // Construct a description of the header. Messages add individual
6687c478bd9Sstevel@tonic-gate     //  descriptions to this.
6697c478bd9Sstevel@tonic-gate 
constructDescription(String msgType, String msgDescription)6707c478bd9Sstevel@tonic-gate     protected void constructDescription(String msgType,
6717c478bd9Sstevel@tonic-gate 					String msgDescription) {
6727c478bd9Sstevel@tonic-gate 	this.msgType = msgType;
6737c478bd9Sstevel@tonic-gate 	this.msgDescription = msgDescription;
6747c478bd9Sstevel@tonic-gate     }
6757c478bd9Sstevel@tonic-gate 
getMsgType()6767c478bd9Sstevel@tonic-gate     public String getMsgType() {
6777c478bd9Sstevel@tonic-gate 	if (msgType == null) {
6787c478bd9Sstevel@tonic-gate 	    if (functionCode > 0 && functionCode < functionCodeAbbr.length) {
6797c478bd9Sstevel@tonic-gate 		return functionCodeAbbr[functionCode];
6807c478bd9Sstevel@tonic-gate 	    } else {
6817c478bd9Sstevel@tonic-gate 		return String.valueOf(functionCode);
6827c478bd9Sstevel@tonic-gate 	    }
6837c478bd9Sstevel@tonic-gate 	} else {
6847c478bd9Sstevel@tonic-gate 	    return msgType;
6857c478bd9Sstevel@tonic-gate 	}
6867c478bd9Sstevel@tonic-gate     }
6877c478bd9Sstevel@tonic-gate 
getMsgDescription()6887c478bd9Sstevel@tonic-gate     public String getMsgDescription() {
6897c478bd9Sstevel@tonic-gate 	return (msgDescription == null) ? "" : msgDescription;
6907c478bd9Sstevel@tonic-gate     }
6917c478bd9Sstevel@tonic-gate }
692