mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Refactored to avoid use of exceptions in parsing, at the suggestion of Jeff Griffin (thanks). These "exceptional cases" are frequent and are expensive; a static parse() / private constructor approach proves no more complex, and a smidge more efficient.
git-svn-id: https://zxing.googlecode.com/svn/trunk@239 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
905b1f7676
commit
36a5e32021
|
@ -19,9 +19,12 @@ package com.google.zxing.client.result;
|
|||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* See
|
||||
* <p>See
|
||||
* <a href="http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html">
|
||||
* DoCoMo's documentation</a> about the result types represented by subclasses of this class.
|
||||
* DoCoMo's documentation</a> about the result types represented by subclasses of this class.</p>
|
||||
*
|
||||
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
* on exception-based mechanisms during parsing.</p>
|
||||
*
|
||||
* @author srowen@google.com (Sean Owen)
|
||||
*/
|
||||
|
@ -66,7 +69,7 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (matches == null) {
|
||||
if (matches == null || matches.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int size = matches.size();
|
||||
|
@ -82,14 +85,6 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
|
|||
return matches == null ? null : matches[0];
|
||||
}
|
||||
|
||||
static String[] matchRequiredPrefixedField(String prefix, String rawText) {
|
||||
String[] result = matchPrefixedField(prefix, rawText);
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException("Did not match prefix " + prefix);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String unescape(String escaped) {
|
||||
if (escaped != null) {
|
||||
int backslash = escaped.indexOf((int) '\\');
|
||||
|
|
|
@ -34,16 +34,29 @@ public final class AddressBookDoCoMoResult extends AbstractDoCoMoResult {
|
|||
private final String note;
|
||||
private final String address;
|
||||
|
||||
public AddressBookDoCoMoResult(String rawText) {
|
||||
private AddressBookDoCoMoResult(String name, String[] phoneNumbers, String email, String note, String address) {
|
||||
super(ParsedReaderResultType.ADDRESSBOOK);
|
||||
this.name = name;
|
||||
this.phoneNumbers = phoneNumbers;
|
||||
this.email = email;
|
||||
this.note = note;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public static AddressBookDoCoMoResult parse(String rawText) {
|
||||
if (!rawText.startsWith("MECARD:")) {
|
||||
throw new IllegalArgumentException("Does not begin with MECARD");
|
||||
return null;
|
||||
}
|
||||
name = parseName(matchRequiredPrefixedField("N:", rawText)[0]);
|
||||
phoneNumbers = matchPrefixedField("TEL:", rawText);
|
||||
email = matchSinglePrefixedField("EMAIL:", rawText);
|
||||
note = matchSinglePrefixedField("NOTE:", rawText);
|
||||
address = matchSinglePrefixedField("ADR:", rawText);
|
||||
String[] rawName = matchPrefixedField("N:", rawText);
|
||||
if (rawName == null) {
|
||||
return null;
|
||||
}
|
||||
String name = parseName(rawName[0]);
|
||||
String[] phoneNumbers = matchPrefixedField("TEL:", rawText);
|
||||
String email = matchSinglePrefixedField("EMAIL:", rawText);
|
||||
String note = matchSinglePrefixedField("NOTE:", rawText);
|
||||
String address = matchSinglePrefixedField("ADR:", rawText);
|
||||
return new AddressBookDoCoMoResult(name, phoneNumbers, email, note, address);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
|
@ -24,17 +24,26 @@ public final class BookmarkDoCoMoResult extends AbstractDoCoMoResult {
|
|||
private final String title;
|
||||
private final String uri;
|
||||
|
||||
public BookmarkDoCoMoResult(String rawText) {
|
||||
private BookmarkDoCoMoResult(String title, String uri) {
|
||||
super(ParsedReaderResultType.BOOKMARK);
|
||||
this.title = title;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public static BookmarkDoCoMoResult parse(String rawText) {
|
||||
if (!rawText.startsWith("MEBKM:")) {
|
||||
throw new IllegalArgumentException("Does not begin with MEBKM");
|
||||
return null;
|
||||
}
|
||||
title = matchSinglePrefixedField("TITLE:", rawText);
|
||||
String uriString = matchRequiredPrefixedField("URL:", rawText)[0];
|
||||
if (!URIParsedResult.isBasicallyValidURI(uriString)) {
|
||||
throw new IllegalArgumentException("Invalid URI: " + uriString);
|
||||
String title = matchSinglePrefixedField("TITLE:", rawText);
|
||||
String[] rawUri = matchPrefixedField("URL:", rawText);
|
||||
if (rawUri == null) {
|
||||
return null;
|
||||
}
|
||||
uri = uriString;
|
||||
String uri = rawUri[0];
|
||||
if (!URIParsedResult.isBasicallyValidURI(uri)) {
|
||||
return null;
|
||||
}
|
||||
return new BookmarkDoCoMoResult(title, uri);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
|
|
|
@ -26,17 +26,23 @@ public final class EmailAddressResult extends AbstractDoCoMoResult {
|
|||
|
||||
private final String emailAddress;
|
||||
|
||||
public EmailAddressResult(String rawText) {
|
||||
private EmailAddressResult(String emailAddress) {
|
||||
super(ParsedReaderResultType.EMAIL_ADDRESS);
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public static EmailAddressResult parse(String rawText) {
|
||||
String emailAddress;
|
||||
if (rawText.startsWith("mailto:")) {
|
||||
// If it starts with mailto:, assume it is definitely trying to be an email address
|
||||
emailAddress = rawText.substring(7);
|
||||
} else {
|
||||
if (!EmailDoCoMoResult.isBasicallyValidEmailAddress(rawText)) {
|
||||
throw new IllegalArgumentException("Invalid email address: " + rawText);
|
||||
return null;
|
||||
}
|
||||
emailAddress = rawText;
|
||||
}
|
||||
return new EmailAddressResult(emailAddress);
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
|
|
|
@ -29,17 +29,28 @@ public final class EmailDoCoMoResult extends AbstractDoCoMoResult {
|
|||
private final String subject;
|
||||
private final String body;
|
||||
|
||||
public EmailDoCoMoResult(String rawText) {
|
||||
private EmailDoCoMoResult(String to, String subject, String body) {
|
||||
super(ParsedReaderResultType.EMAIL);
|
||||
this.to = to;
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static EmailDoCoMoResult parse(String rawText) {
|
||||
if (!rawText.startsWith("MATMSG:")) {
|
||||
throw new IllegalArgumentException("Does not begin with MATMSG");
|
||||
return null;
|
||||
}
|
||||
to = matchRequiredPrefixedField("TO:", rawText)[0];
|
||||
String[] rawTo = matchPrefixedField("TO:", rawText);
|
||||
if (rawTo == null) {
|
||||
return null;
|
||||
}
|
||||
String to = rawTo[0];
|
||||
if (!isBasicallyValidEmailAddress(to)) {
|
||||
throw new IllegalArgumentException("Invalid email address: " + to);
|
||||
return null;
|
||||
}
|
||||
subject = matchSinglePrefixedField("SUB:", rawText);
|
||||
body = matchSinglePrefixedField("BODY:", rawText);
|
||||
String subject = matchSinglePrefixedField("SUB:", rawText);
|
||||
String body = matchSinglePrefixedField("BODY:", rawText);
|
||||
return new EmailDoCoMoResult(to, subject, body);
|
||||
}
|
||||
|
||||
public String getTo() {
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
package com.google.zxing.client.result;
|
||||
|
||||
/**
|
||||
* <p>Abstract class representing the result of decoding a barcode, as more than
|
||||
* a String -- as some type of structured data. This might be a subclass which represents
|
||||
* a URL, or an e-mail address. {@link #parseReaderResult(String)} will turn a raw
|
||||
* decoded string into the most appropriate type of structured representation.</p>
|
||||
*
|
||||
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
* on exception-based mechanisms during parsing.</p>
|
||||
*
|
||||
* @author srowen@google.com (Sean Owen)
|
||||
*/
|
||||
public abstract class ParsedReaderResult {
|
||||
|
@ -37,42 +45,23 @@ public abstract class ParsedReaderResult {
|
|||
// This is a bit messy, but given limited options in MIDP / CLDC, this may well be the simplest
|
||||
// way to go about this. For example, we have no reflection available, really.
|
||||
// Order is important here.
|
||||
try {
|
||||
return new BookmarkDoCoMoResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
ParsedReaderResult result;
|
||||
if ((result = BookmarkDoCoMoResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = AddressBookDoCoMoResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = EmailDoCoMoResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = EmailAddressResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = URLTOResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = URIParsedResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
} else if ((result = UPCParsedResult.parse(rawText)) != null) {
|
||||
return result;
|
||||
}
|
||||
try {
|
||||
return new AddressBookDoCoMoResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
try {
|
||||
return new EmailDoCoMoResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
try {
|
||||
return new EmailAddressResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
try {
|
||||
return new URLTOResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
try {
|
||||
return new URIParsedResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
try {
|
||||
return new UPCParsedResult(rawText);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// continue
|
||||
}
|
||||
return new TextParsedResult(rawText);
|
||||
return TextParsedResult.parse(rawText);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -23,9 +23,13 @@ public final class TextParsedResult extends ParsedReaderResult {
|
|||
|
||||
private final String text;
|
||||
|
||||
public TextParsedResult(String rawText) {
|
||||
private TextParsedResult(String text) {
|
||||
super(ParsedReaderResultType.TEXT);
|
||||
text = rawText;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static TextParsedResult parse(String rawText) {
|
||||
return new TextParsedResult(rawText);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
|
|
|
@ -23,19 +23,24 @@ public final class UPCParsedResult extends ParsedReaderResult {
|
|||
|
||||
private final String upc;
|
||||
|
||||
public UPCParsedResult(String rawText) {
|
||||
private UPCParsedResult(String upc) {
|
||||
super(ParsedReaderResultType.UPC);
|
||||
this.upc = upc;
|
||||
}
|
||||
|
||||
public static UPCParsedResult parse(String rawText) {
|
||||
int length = rawText.length();
|
||||
if (length != 12 && length != 13) {
|
||||
throw new IllegalArgumentException("Wrong number of digits for UPC");
|
||||
return null;
|
||||
}
|
||||
for (int x = 0; x < length; x++) {
|
||||
char c = rawText.charAt(x);
|
||||
if (c < '0' || c > '9') {
|
||||
throw new IllegalArgumentException("Invalid character found in UPC");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
upc = rawText;
|
||||
// Not actually checking the checkusm again here
|
||||
return new UPCParsedResult(rawText);
|
||||
}
|
||||
|
||||
public String getUPC() {
|
||||
|
|
|
@ -23,13 +23,17 @@ public final class URIParsedResult extends ParsedReaderResult {
|
|||
|
||||
private final String uri;
|
||||
|
||||
public URIParsedResult(String rawText) {
|
||||
private URIParsedResult(String uri) {
|
||||
super(ParsedReaderResultType.URI);
|
||||
if (!isBasicallyValidURI(rawText)) {
|
||||
throw new IllegalArgumentException("Invalid URI: " + rawText);
|
||||
}
|
||||
uri = massagePossibleURI(rawText);
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public static URIParsedResult parse(String rawText) {
|
||||
if (!isBasicallyValidURI(rawText)) {
|
||||
return null;
|
||||
}
|
||||
String uri = massagePossibleURI(rawText);
|
||||
return new URIParsedResult(uri);
|
||||
}
|
||||
|
||||
public String getURI() {
|
||||
|
|
|
@ -28,14 +28,23 @@ public final class URLTOResult extends ParsedReaderResult {
|
|||
private final String title;
|
||||
private final String uri;
|
||||
|
||||
public URLTOResult(String rawText) {
|
||||
private URLTOResult(String title, String uri) {
|
||||
super(ParsedReaderResultType.URLTO);
|
||||
this.title = title;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public static URLTOResult parse(String rawText) {
|
||||
if (!rawText.startsWith("URLTO:")) {
|
||||
throw new IllegalArgumentException("Does not begin with URLTO");
|
||||
return null;
|
||||
}
|
||||
int titleEnd = rawText.indexOf(':', 6);
|
||||
title = rawText.substring(6, titleEnd);
|
||||
uri = rawText.substring(titleEnd + 1);
|
||||
if (titleEnd < 0) {
|
||||
return null;
|
||||
}
|
||||
String title = rawText.substring(6, titleEnd);
|
||||
String uri = rawText.substring(titleEnd + 1);
|
||||
return new URLTOResult(title, uri);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
|
|
Loading…
Reference in a new issue