/*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program 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
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package javax.microedition.io;
/**
* Implements path normalization for comm protocol.
*/
class CommOptParameterParser implements PathNormalizer {
/** Bit flag: 1 stop bits. */
private final static int serSettingsFlagStopBits1 = 1 << 0;
/** Bit flag: 2 stop bits. */
private final static int serSettingsFlagStopBits2 = 1 << 1;
/** Bit flag: parity none. */
private final static int serSettingsFlagParityNoneM = 1 << 2;
/** Bit flag: parity on. */
private final static int serSettingsFlagParityOddM = 1 << 3;
/** Bit flag: parity even. */
private final static int serSettingsFlagParityEvenM = 1 << 4;
/** Bit flag: RTS rcv flow control. */
private final static int serSettingsFlagRTSAutoM = 1 << 5;
private final static int serSettingsFlagRTSAutoOffM = 1 << 6;
/** Bit flag: CTS xmit flow control. */
private final static int serSettingsFlagCTSAutoM = 1 << 7;
private final static int serSettingsFlagCTSAutoOffM = 1 << 8;
/** Bit flag: 7 bits/char. */
private final static int serSettingsFlagBitsPerChar7 = 1 << 9;
/** Bit flag: 8 bits/char. */
private final static int serSettingsFlagBitsPerChar8 = 1 << 10;
/** Bit flag: blocking */
private final static int serSettingsFlagBlockingOn = 1 << 11;
private final static int serSettingsFlagBlockingOff = 1 << 12;
/** Port name */
public String port;
/** Bit per char. */
public int bbc = serSettingsFlagBitsPerChar7 |
serSettingsFlagBitsPerChar8;
/** Stop bits. */
public int stop = serSettingsFlagStopBits1 |
serSettingsFlagStopBits2;
/** Parity. */
public int parity = serSettingsFlagParityNoneM |
serSettingsFlagParityOddM |
serSettingsFlagParityEvenM;
/** RTS. */
public int rts = serSettingsFlagRTSAutoM |
serSettingsFlagRTSAutoOffM;
/** CTS. */
public int cts = serSettingsFlagCTSAutoM |
serSettingsFlagCTSAutoOffM;
/** Blocking. */
public int blocking = serSettingsFlagBlockingOn |
serSettingsFlagBlockingOff;
/** Baud rate. */
public int baud = -1;
public String normalize(String path) {
if (path == null || "".equals(path)) {
throw new IllegalArgumentException("Expected scheme-specific part");
}
int p = 0;
int len = path.length();
for (p = 0; p < len && isAlphaNum(path.charAt(p)); p++) {}
// Asterisk can be used to indicate a wildcard match
// in the port identifier field
if (p < len && path.charAt(p) == '*') {
if (p != len - 1) {
throw new IllegalArgumentException(
"Asterisk can appear only at the end: " + path);
}
p++;
}
if (p == 0) {
throw new IllegalArgumentException("Expected port identifier: " + path);
}
port = path.substring(0, p);
while (p < len) {
if (path.charAt(p) != ';') {
throw new IllegalArgumentException(
"Expected semi-colon delimiter: " + path);
}
p++;
int q = path.indexOf('=', p);
if (q == -1) {
throw new IllegalArgumentException(
"Malformed optional parameters: " + path);
}
String name = path.substring(p, q);
q++;
int r = path.indexOf(';', q);
if (r == -1) {
r = len;
}
String value = path.substring(q, r);
if ("baudrate".equals(name)) {
try {
baud = Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"Invalid baudrate value: " + path);
}
if (baud <= 0) {
throw new IllegalArgumentException(
"Invalid baudrate value: " + path);
}
} else if ("bitsperchar".equals(name)) {
if ("7".equals(value)) {
bbc = serSettingsFlagBitsPerChar7;
} else if ("8".equals(value)) {
bbc = serSettingsFlagBitsPerChar8;
} else {
throw new IllegalArgumentException(
"Invalid bitsperchar value: " + path);
}
} else if ("stopbits".equals(name)) {
if ("1".equals(value)) {
stop = serSettingsFlagStopBits1;
} else if ("2".equals(value)) {
stop = serSettingsFlagStopBits2;
} else {
throw new IllegalArgumentException(
"Invalid stopbits value: " + path);
}
} else if ("parity".equals(name)) {
if ("odd".equals(value)) {
parity = serSettingsFlagParityOddM;
} else if ("even".equals(value)) {
parity = serSettingsFlagParityEvenM;
} else if ("none".equals(value)) {
parity = serSettingsFlagParityNoneM;
} else {
throw new IllegalArgumentException(
"Invalid parity value: " + path);
}
} else if ("blocking".equals(name)) {
if ("on".equals(value)) {
blocking = serSettingsFlagBlockingOn;
} else if ("off".equals(value)) {
blocking = serSettingsFlagBlockingOff;
} else {
throw new IllegalArgumentException(
"Invalid blocking value: " + path);
}
} else if ("autocts".equals(name)) {
if ("on".equals(value)) {
cts = serSettingsFlagCTSAutoM;
} else if ("off".equals(value)) {
cts = serSettingsFlagCTSAutoOffM;
} else {
throw new IllegalArgumentException("Invalid autocts value: " + path);
}
} else if ("autorts".equals(name)) {
if ("on".equals(value)) {
rts = serSettingsFlagRTSAutoM;
} else if ("off".equals(value)) {
rts = serSettingsFlagRTSAutoOffM;
} else {
throw new IllegalArgumentException("Invalid autorts value: " + path);
}
} else {
throw new IllegalArgumentException("Unknown parameter used: " + path);
}
p = r;
}
{
String normalizedPath = port;
if (baud > 0) {
normalizedPath += ";baudrate=" + baud;
}
switch (bbc) {
case serSettingsFlagBitsPerChar7:
normalizedPath += ";bitsperchar=7"; break;
case serSettingsFlagBitsPerChar8:
normalizedPath += ";bitsperchar=8"; break;
}
switch (stop) {
case serSettingsFlagStopBits1:
normalizedPath += ";stopbits=1"; break;
case serSettingsFlagStopBits2:
normalizedPath += ";stopbits=2"; break;
}
switch (parity) {
case serSettingsFlagParityNoneM:
normalizedPath += ";parity=none"; break;
case serSettingsFlagParityOddM:
normalizedPath += ";parity=odd"; break;
case serSettingsFlagParityEvenM:
normalizedPath += ";parity=even"; break;
}
switch (blocking) {
case serSettingsFlagBlockingOn:
normalizedPath += ";blocking=on"; break;
case serSettingsFlagBlockingOff:
normalizedPath += ";blocking=off"; break;
}
switch (cts) {
case serSettingsFlagCTSAutoM:
normalizedPath += ";autocts=on"; break;
case serSettingsFlagCTSAutoOffM:
normalizedPath += ";autocts=off"; break;
}
switch (rts) {
case serSettingsFlagRTSAutoM:
normalizedPath += ";autorts=on"; break;
case serSettingsFlagRTSAutoOffM:
normalizedPath += ";autorts=off"; break;
}
return normalizedPath;
}
}
private static boolean isAlphaNum(char c) {
return Character.isDigit(c) || ('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z');
}
}