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;
|
import java.util.Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See
|
* <p>See
|
||||||
* <a href="http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html">
|
* <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)
|
* @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;
|
return null;
|
||||||
}
|
}
|
||||||
int size = matches.size();
|
int size = matches.size();
|
||||||
|
@ -82,14 +85,6 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
|
||||||
return matches == null ? null : matches[0];
|
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) {
|
private static String unescape(String escaped) {
|
||||||
if (escaped != null) {
|
if (escaped != null) {
|
||||||
int backslash = escaped.indexOf((int) '\\');
|
int backslash = escaped.indexOf((int) '\\');
|
||||||
|
|
|
@ -34,16 +34,29 @@ public final class AddressBookDoCoMoResult extends AbstractDoCoMoResult {
|
||||||
private final String note;
|
private final String note;
|
||||||
private final String address;
|
private final String address;
|
||||||
|
|
||||||
public AddressBookDoCoMoResult(String rawText) {
|
private AddressBookDoCoMoResult(String name, String[] phoneNumbers, String email, String note, String address) {
|
||||||
super(ParsedReaderResultType.ADDRESSBOOK);
|
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:")) {
|
if (!rawText.startsWith("MECARD:")) {
|
||||||
throw new IllegalArgumentException("Does not begin with MECARD");
|
return null;
|
||||||
}
|
}
|
||||||
name = parseName(matchRequiredPrefixedField("N:", rawText)[0]);
|
String[] rawName = matchPrefixedField("N:", rawText);
|
||||||
phoneNumbers = matchPrefixedField("TEL:", rawText);
|
if (rawName == null) {
|
||||||
email = matchSinglePrefixedField("EMAIL:", rawText);
|
return null;
|
||||||
note = matchSinglePrefixedField("NOTE:", rawText);
|
}
|
||||||
address = matchSinglePrefixedField("ADR:", rawText);
|
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() {
|
public String getName() {
|
||||||
|
|
|
@ -24,17 +24,26 @@ public final class BookmarkDoCoMoResult extends AbstractDoCoMoResult {
|
||||||
private final String title;
|
private final String title;
|
||||||
private final String uri;
|
private final String uri;
|
||||||
|
|
||||||
public BookmarkDoCoMoResult(String rawText) {
|
private BookmarkDoCoMoResult(String title, String uri) {
|
||||||
super(ParsedReaderResultType.BOOKMARK);
|
super(ParsedReaderResultType.BOOKMARK);
|
||||||
|
this.title = title;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BookmarkDoCoMoResult parse(String rawText) {
|
||||||
if (!rawText.startsWith("MEBKM:")) {
|
if (!rawText.startsWith("MEBKM:")) {
|
||||||
throw new IllegalArgumentException("Does not begin with MEBKM");
|
return null;
|
||||||
}
|
}
|
||||||
title = matchSinglePrefixedField("TITLE:", rawText);
|
String title = matchSinglePrefixedField("TITLE:", rawText);
|
||||||
String uriString = matchRequiredPrefixedField("URL:", rawText)[0];
|
String[] rawUri = matchPrefixedField("URL:", rawText);
|
||||||
if (!URIParsedResult.isBasicallyValidURI(uriString)) {
|
if (rawUri == null) {
|
||||||
throw new IllegalArgumentException("Invalid URI: " + uriString);
|
return null;
|
||||||
}
|
}
|
||||||
uri = uriString;
|
String uri = rawUri[0];
|
||||||
|
if (!URIParsedResult.isBasicallyValidURI(uri)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BookmarkDoCoMoResult(title, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
|
|
|
@ -26,17 +26,23 @@ public final class EmailAddressResult extends AbstractDoCoMoResult {
|
||||||
|
|
||||||
private final String emailAddress;
|
private final String emailAddress;
|
||||||
|
|
||||||
public EmailAddressResult(String rawText) {
|
private EmailAddressResult(String emailAddress) {
|
||||||
super(ParsedReaderResultType.EMAIL_ADDRESS);
|
super(ParsedReaderResultType.EMAIL_ADDRESS);
|
||||||
|
this.emailAddress = emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EmailAddressResult parse(String rawText) {
|
||||||
|
String emailAddress;
|
||||||
if (rawText.startsWith("mailto:")) {
|
if (rawText.startsWith("mailto:")) {
|
||||||
// If it starts with mailto:, assume it is definitely trying to be an email address
|
// If it starts with mailto:, assume it is definitely trying to be an email address
|
||||||
emailAddress = rawText.substring(7);
|
emailAddress = rawText.substring(7);
|
||||||
} else {
|
} else {
|
||||||
if (!EmailDoCoMoResult.isBasicallyValidEmailAddress(rawText)) {
|
if (!EmailDoCoMoResult.isBasicallyValidEmailAddress(rawText)) {
|
||||||
throw new IllegalArgumentException("Invalid email address: " + rawText);
|
return null;
|
||||||
}
|
}
|
||||||
emailAddress = rawText;
|
emailAddress = rawText;
|
||||||
}
|
}
|
||||||
|
return new EmailAddressResult(emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmailAddress() {
|
public String getEmailAddress() {
|
||||||
|
|
|
@ -29,17 +29,28 @@ public final class EmailDoCoMoResult extends AbstractDoCoMoResult {
|
||||||
private final String subject;
|
private final String subject;
|
||||||
private final String body;
|
private final String body;
|
||||||
|
|
||||||
public EmailDoCoMoResult(String rawText) {
|
private EmailDoCoMoResult(String to, String subject, String body) {
|
||||||
super(ParsedReaderResultType.EMAIL);
|
super(ParsedReaderResultType.EMAIL);
|
||||||
|
this.to = to;
|
||||||
|
this.subject = subject;
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EmailDoCoMoResult parse(String rawText) {
|
||||||
if (!rawText.startsWith("MATMSG:")) {
|
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)) {
|
if (!isBasicallyValidEmailAddress(to)) {
|
||||||
throw new IllegalArgumentException("Invalid email address: " + to);
|
return null;
|
||||||
}
|
}
|
||||||
subject = matchSinglePrefixedField("SUB:", rawText);
|
String subject = matchSinglePrefixedField("SUB:", rawText);
|
||||||
body = matchSinglePrefixedField("BODY:", rawText);
|
String body = matchSinglePrefixedField("BODY:", rawText);
|
||||||
|
return new EmailDoCoMoResult(to, subject, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTo() {
|
public String getTo() {
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
package com.google.zxing.client.result;
|
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)
|
* @author srowen@google.com (Sean Owen)
|
||||||
*/
|
*/
|
||||||
public abstract class ParsedReaderResult {
|
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
|
// 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.
|
// way to go about this. For example, we have no reflection available, really.
|
||||||
// Order is important here.
|
// Order is important here.
|
||||||
try {
|
ParsedReaderResult result;
|
||||||
return new BookmarkDoCoMoResult(rawText);
|
if ((result = BookmarkDoCoMoResult.parse(rawText)) != null) {
|
||||||
} catch (IllegalArgumentException iae) {
|
return result;
|
||||||
// continue
|
} 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 TextParsedResult.parse(rawText);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -23,9 +23,13 @@ public final class TextParsedResult extends ParsedReaderResult {
|
||||||
|
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
public TextParsedResult(String rawText) {
|
private TextParsedResult(String text) {
|
||||||
super(ParsedReaderResultType.TEXT);
|
super(ParsedReaderResultType.TEXT);
|
||||||
text = rawText;
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TextParsedResult parse(String rawText) {
|
||||||
|
return new TextParsedResult(rawText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
|
|
|
@ -23,19 +23,24 @@ public final class UPCParsedResult extends ParsedReaderResult {
|
||||||
|
|
||||||
private final String upc;
|
private final String upc;
|
||||||
|
|
||||||
public UPCParsedResult(String rawText) {
|
private UPCParsedResult(String upc) {
|
||||||
super(ParsedReaderResultType.UPC);
|
super(ParsedReaderResultType.UPC);
|
||||||
|
this.upc = upc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UPCParsedResult parse(String rawText) {
|
||||||
int length = rawText.length();
|
int length = rawText.length();
|
||||||
if (length != 12 && length != 13) {
|
if (length != 12 && length != 13) {
|
||||||
throw new IllegalArgumentException("Wrong number of digits for UPC");
|
return null;
|
||||||
}
|
}
|
||||||
for (int x = 0; x < length; x++) {
|
for (int x = 0; x < length; x++) {
|
||||||
char c = rawText.charAt(x);
|
char c = rawText.charAt(x);
|
||||||
if (c < '0' || c > '9') {
|
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() {
|
public String getUPC() {
|
||||||
|
|
|
@ -23,13 +23,17 @@ public final class URIParsedResult extends ParsedReaderResult {
|
||||||
|
|
||||||
private final String uri;
|
private final String uri;
|
||||||
|
|
||||||
public URIParsedResult(String rawText) {
|
private URIParsedResult(String uri) {
|
||||||
super(ParsedReaderResultType.URI);
|
super(ParsedReaderResultType.URI);
|
||||||
if (!isBasicallyValidURI(rawText)) {
|
this.uri = uri;
|
||||||
throw new IllegalArgumentException("Invalid URI: " + rawText);
|
}
|
||||||
}
|
|
||||||
uri = massagePossibleURI(rawText);
|
|
||||||
|
|
||||||
|
public static URIParsedResult parse(String rawText) {
|
||||||
|
if (!isBasicallyValidURI(rawText)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String uri = massagePossibleURI(rawText);
|
||||||
|
return new URIParsedResult(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getURI() {
|
public String getURI() {
|
||||||
|
|
|
@ -28,14 +28,23 @@ public final class URLTOResult extends ParsedReaderResult {
|
||||||
private final String title;
|
private final String title;
|
||||||
private final String uri;
|
private final String uri;
|
||||||
|
|
||||||
public URLTOResult(String rawText) {
|
private URLTOResult(String title, String uri) {
|
||||||
super(ParsedReaderResultType.URLTO);
|
super(ParsedReaderResultType.URLTO);
|
||||||
|
this.title = title;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URLTOResult parse(String rawText) {
|
||||||
if (!rawText.startsWith("URLTO:")) {
|
if (!rawText.startsWith("URLTO:")) {
|
||||||
throw new IllegalArgumentException("Does not begin with URLTO");
|
return null;
|
||||||
}
|
}
|
||||||
int titleEnd = rawText.indexOf(':', 6);
|
int titleEnd = rawText.indexOf(':', 6);
|
||||||
title = rawText.substring(6, titleEnd);
|
if (titleEnd < 0) {
|
||||||
uri = rawText.substring(titleEnd + 1);
|
return null;
|
||||||
|
}
|
||||||
|
String title = rawText.substring(6, titleEnd);
|
||||||
|
String uri = rawText.substring(titleEnd + 1);
|
||||||
|
return new URLTOResult(title, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
|
|
Loading…
Reference in a new issue