001: /*
002: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
003: * Reserved. Use is subject to license terms.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025: package gov.nist.core;
026:
027: import gov.nist.siplite.parser.Lexer;
028:
029: /**
030: * Parser for host names.
031: *
032: * @version JAIN-SIP-1.1
033: *
034: *
035: * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
036: *
037: */
038:
039: public class HostNameParser extends ParserCore {
040:
041: /**
042: * The lexer is initialized with the buffer.
043: * @param lexer class to use for parsing
044: */
045: public HostNameParser(LexerCore lexer) {
046: this .lexer = lexer;
047: lexer.selectLexer("charLexer");
048: }
049:
050: /**
051: * Gets the domain name.
052: * @return the domain label
053: * @exception ParseException if an error occurs parsing
054: */
055: protected String domainLabel() throws ParseException {
056: StringBuffer retval = new StringBuffer();
057: char la;
058: if (debug)
059: dbg_enter("domainLabel");
060: try {
061: while (lexer.hasMoreChars()) {
062: la = lexer.lookAhead(0);
063: if (LexerCore.isAlpha(la)) {
064: lexer.consume(1);
065: retval.append(la);
066: } else if (LexerCore.isDigit(la)) {
067: lexer.consume(1);
068: retval.append(la);
069: } else if (la == '-') {
070: lexer.consume(1);
071: retval.append(la);
072: } else
073: break;
074: }
075: // Debug.println("returning " + retval.toString());
076: if (retval.length() == 0) {
077: throw new ParseException("Error parsing domain label "
078: + lexer.getBuffer(), lexer.getPtr());
079: }
080: return retval.toString();
081: } finally {
082: if (debug)
083: dbg_leave("domainLabel");
084: }
085: }
086:
087: /**
088: * Gets the IPV6 reference.
089: * @return the IPV6 address
090: */
091: protected String ipv6Reference() throws ParseException {
092: StringBuffer retval = new StringBuffer();
093: if (debug)
094: dbg_enter("domainLabel");
095: try {
096: while (lexer.hasMoreChars()) {
097: char la = lexer.lookAhead(0);
098: if (LexerCore.isHexDigit(la)) {
099: lexer.consume(1);
100: retval.append(la);
101: } else if (la == '.' || la == ':' || la == '[') {
102: lexer.consume(1);
103: retval.append(la);
104: } else if (la == ']') {
105: lexer.consume(1);
106: retval.append(la);
107: return retval.toString();
108: } else
109: break;
110: }
111:
112: throw new ParseException(lexer.getBuffer()
113: + ": Illegal Host name ", lexer.getPtr());
114: } finally {
115: if (debug)
116: dbg_leave("domainLabel");
117: }
118: }
119:
120: /**
121: * Gets the host name.
122: * @return the host name
123: * @exception ParseException if an error occurs parsing
124: */
125: public String hostName() throws ParseException {
126: if (debug)
127: dbg_enter("host");
128: try {
129: StringBuffer hname = new StringBuffer();
130: // IPv6 referene
131: if (lexer.lookAhead(0) == '[') {
132: hname.append(ipv6Reference());
133: }
134: // IPv4 address or hostname
135: else {
136: String nextTok = domainLabel();
137: hname.append(nextTok);
138: while (lexer.hasMoreChars()) {
139: // Reached the end of the buffer.
140: if (lexer.lookAhead(0) == '.') {
141: lexer.consume(1);
142: nextTok = domainLabel();
143: hname.append(".");
144: hname.append(nextTok);
145: } else
146: break;
147: }
148: }
149:
150: return hname.toString();
151: } finally {
152: if (debug)
153: dbg_leave("host");
154: }
155: }
156:
157: /**
158: * Gets the host name and port number.
159: * @return the host name and port number encoded string
160: * @exception ParseException if an error occurs parsing
161: */
162: public HostPort hostPort() throws ParseException {
163: if (debug)
164: dbg_enter("hostPort");
165: try {
166: int m = lexer.markInputPosition();
167: String hostName = this .hostName();
168: Host host = new Host();
169: HostPort hp = new HostPort();
170: boolean parsePort = false;
171: if (StringTokenizer.isDigitString(hostName)) { // maybe server URI
172: lexer.rewindInputPosition(m); // try to port parsing
173: parsePort = true;
174: } else { // save hostname
175: host.setHostname(hostName);
176: }
177: hp.setHost(host);
178:
179: // For some headers (for ex., Via) there may be spaces
180: // between the host name and the port number.
181: lexer.SPorHT();
182:
183: // Has a port?
184: if (!parsePort && lexer.hasMoreChars()
185: && lexer.lookAhead(0) == ':') {
186: lexer.consume(1);
187: lexer.SPorHT();
188: parsePort = true;
189: }
190: if (parsePort) {
191: parsePort(lexer, hp);
192: }
193:
194: return hp;
195: } finally {
196: if (debug)
197: dbg_leave("hostPort");
198: }
199:
200: }
201:
202: /**
203: * Port parsing method.
204: * All port symbols must be digital. Port length must be >0.
205: * Resulting port value stores in input HostPort instance.
206: * @param lexer class to use for parsing
207: * @param hp HostPort instance for accepting port value
208: * @exception ParseException if an error occurs parsing
209: * @exception NumberFormatException if any number format error
210: * @exception IllegalArgumentException if any other format error
211: */
212: public static void parsePort(LexerCore lexer, HostPort hp)
213: throws ParseException {
214: try {
215: String port = lexer.number();
216: if (port.length() == 0) { // nondigit port symbols
217: throw new ParseException("Port format error", lexer
218: .getPtr());
219: } else {
220: hp.setPort(Integer.parseInt(port));
221: }
222: } catch (NumberFormatException nfe) {
223: throw new ParseException(lexer.getBuffer()
224: + " :Error parsing port ", lexer.getPtr());
225: } catch (IllegalArgumentException iae) {
226: // setPort can throw IAE
227: throw new ParseException(iae.getMessage(), lexer.getPtr());
228: }
229: }
230:
231: }
|