- Fixed a crash when parsing a particular VCard with a blank entry.
authordswitkin <dswitkin@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 29 Sep 2008 18:45:00 +0000 (18:45 +0000)
committerdswitkin <dswitkin@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 29 Sep 2008 18:45:00 +0000 (18:45 +0000)
- Trimmed whitespace around many fields to sanitize the results (this is very useful upstream, for example we hyphenate phone numbers on Android but can't tolerate extra whitespace).
- Fixed a bug with 1D result points when scanning upside down - they needed to be mirrored to draw correctly.

git-svn-id: http://zxing.googlecode.com/svn/trunk@592 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/client/result/AbstractDoCoMoResultParser.java
core/src/com/google/zxing/client/result/AddressBookAUResultParser.java
core/src/com/google/zxing/client/result/AddressBookDoCoMoResultParser.java
core/src/com/google/zxing/client/result/BizcardResultParser.java
core/src/com/google/zxing/client/result/BookmarkDoCoMoResultParser.java
core/src/com/google/zxing/client/result/EmailDoCoMoResultParser.java
core/src/com/google/zxing/client/result/ResultParser.java
core/src/com/google/zxing/client/result/VCardResultParser.java
core/src/com/google/zxing/client/result/VEventResultParser.java
core/src/com/google/zxing/oned/AbstractOneDReader.java
javase/src/com/google/zxing/client/j2se/CommandLineRunner.java

index dd9e314..1c84175 100644 (file)
@@ -28,12 +28,12 @@ package com.google.zxing.client.result;
  */
 abstract class AbstractDoCoMoResultParser extends ResultParser {
 
-  static String[] matchDoCoMoPrefixedField(String prefix, String rawText) {
-    return matchPrefixedField(prefix, rawText, ';');
+  static String[] matchDoCoMoPrefixedField(String prefix, String rawText, boolean trim) {
+    return matchPrefixedField(prefix, rawText, ';', trim);
   }
 
-  static String matchSingleDoCoMoPrefixedField(String prefix, String rawText) {
-    return matchSinglePrefixedField(prefix, rawText, ';');
+  static String matchSingleDoCoMoPrefixedField(String prefix, String rawText, boolean trim) {
+    return matchSinglePrefixedField(prefix, rawText, ';', trim);
   }
 
   static String[] maybeWrap(String value) {
index 7eb8ec8..12eb520 100644 (file)
@@ -36,18 +36,18 @@ final class AddressBookAUResultParser extends ResultParser {
     if (rawText == null || rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
       return null;
     }
-    String[] names = matchMultipleValuePrefix("NAME", 2, rawText);
-    String[] phoneNumbers = matchMultipleValuePrefix("TEL", 3, rawText);
-    String[] emails = matchMultipleValuePrefix("MAIL", 3, rawText);
-    String note = matchSinglePrefixedField("MEMORY:", rawText, '\r');
-    String address = matchSinglePrefixedField("ADD:", rawText, '\r');
+    String[] names = matchMultipleValuePrefix("NAME", 2, rawText, true);
+    String[] phoneNumbers = matchMultipleValuePrefix("TEL", 3, rawText, true);
+    String[] emails = matchMultipleValuePrefix("MAIL", 3, rawText, true);
+    String note = matchSinglePrefixedField("MEMORY:", rawText, '\r', false);
+    String address = matchSinglePrefixedField("ADD:", rawText, '\r', true);
     return new AddressBookParsedResult(names, phoneNumbers, emails, note, address, null, null, null);
   }
 
-  private static String[] matchMultipleValuePrefix(String prefix, int max, String rawText) {
+  private static String[] matchMultipleValuePrefix(String prefix, int max, String rawText, boolean trim) {
     Vector values = null;
     for (int i = 1; i <= max; i++) {
-      String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r');
+      String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
       if (value == null) {
         break;
       }
index 7bf88e6..ca1aba3 100644 (file)
@@ -35,16 +35,16 @@ final class AddressBookDoCoMoResultParser extends AbstractDoCoMoResultParser {
     if (rawText == null || !rawText.startsWith("MECARD:")) {
       return null;
     }
-    String[] rawName = matchDoCoMoPrefixedField("N:", rawText);
+    String[] rawName = matchDoCoMoPrefixedField("N:", rawText, true);
     if (rawName == null) {
       return null;
     }
     String name = parseName(rawName[0]);
-    String[] phoneNumbers = matchDoCoMoPrefixedField("TEL:", rawText);
-    String email = matchSingleDoCoMoPrefixedField("EMAIL:", rawText);
-    String note = matchSingleDoCoMoPrefixedField("NOTE:", rawText);
-    String address = matchSingleDoCoMoPrefixedField("ADR:", rawText);
-    String birthday = matchSingleDoCoMoPrefixedField("BDAY:", rawText);
+    String[] phoneNumbers = matchDoCoMoPrefixedField("TEL:", rawText, true);
+    String email = matchSingleDoCoMoPrefixedField("EMAIL:", rawText, true);
+    String note = matchSingleDoCoMoPrefixedField("NOTE:", rawText, false);
+    String address = matchSingleDoCoMoPrefixedField("ADR:", rawText, true);
+    String birthday = matchSingleDoCoMoPrefixedField("BDAY:", rawText, true);
     if (birthday != null && !isStringOfDigits(birthday, 8)) {
       return null;
     }
index 16809c6..4c36467 100644 (file)
@@ -38,16 +38,16 @@ final class BizcardResultParser extends AbstractDoCoMoResultParser {
     if (rawText == null || !rawText.startsWith("BIZCARD:")) {
       return null;
     }
-    String firstName = matchSingleDoCoMoPrefixedField("N:", rawText);
-    String lastName = matchSingleDoCoMoPrefixedField("X:", rawText);
+    String firstName = matchSingleDoCoMoPrefixedField("N:", rawText, true);
+    String lastName = matchSingleDoCoMoPrefixedField("X:", rawText, true);
     String fullName = buildName(firstName, lastName);
-    String title = matchSingleDoCoMoPrefixedField("T:", rawText);
-    String org = matchSingleDoCoMoPrefixedField("C:", rawText);
-    String address = matchSingleDoCoMoPrefixedField("A:", rawText);
-    String phoneNumber1 = matchSingleDoCoMoPrefixedField("B:", rawText);
-    String phoneNumber2 = matchSingleDoCoMoPrefixedField("M:", rawText);
-    String phoneNumber3 = matchSingleDoCoMoPrefixedField("F:", rawText);
-    String email = matchSingleDoCoMoPrefixedField("E:", rawText);
+    String title = matchSingleDoCoMoPrefixedField("T:", rawText, true);
+    String org = matchSingleDoCoMoPrefixedField("C:", rawText, true);
+    String address = matchSingleDoCoMoPrefixedField("A:", rawText, true);
+    String phoneNumber1 = matchSingleDoCoMoPrefixedField("B:", rawText, true);
+    String phoneNumber2 = matchSingleDoCoMoPrefixedField("M:", rawText, true);
+    String phoneNumber3 = matchSingleDoCoMoPrefixedField("F:", rawText, true);
+    String email = matchSingleDoCoMoPrefixedField("E:", rawText, true);
 
     return new AddressBookParsedResult(maybeWrap(fullName),
                                        buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3),
index e5f4cf2..2a1e1fd 100644 (file)
@@ -31,8 +31,8 @@ final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
     if (rawText == null || !rawText.startsWith("MEBKM:")) {
       return null;
     }
-    String title = matchSingleDoCoMoPrefixedField("TITLE:", rawText);
-    String[] rawUri = matchDoCoMoPrefixedField("URL:", rawText);
+    String title = matchSingleDoCoMoPrefixedField("TITLE:", rawText, true);
+    String[] rawUri = matchDoCoMoPrefixedField("URL:", rawText, true);
     if (rawUri == null) {
       return null;
     }
index bfa10c2..fea5940 100644 (file)
@@ -32,7 +32,7 @@ final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
     if (rawText == null || !rawText.startsWith("MATMSG:")) {
       return null;
     }
-    String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText);
+    String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText, true);
     if (rawTo == null) {
       return null;
     }
@@ -40,8 +40,8 @@ final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
     if (!isBasicallyValidEmailAddress(to)) {
       return null;
     }
-    String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText);
-    String body = matchSingleDoCoMoPrefixedField("BODY:", rawText);
+    String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText, false);
+    String body = matchSingleDoCoMoPrefixedField("BODY:", rawText, false);
     return new EmailAddressParsedResult(to, subject, body, "mailto:" + to);
   }
 
index fdac7c7..4aa5431 100644 (file)
@@ -234,7 +234,7 @@ public abstract class ResultParser {
     }
   }
 
-  static String[] matchPrefixedField(String prefix, String rawText, char endChar) {
+  static String[] matchPrefixedField(String prefix, String rawText, char endChar, boolean trim) {
     Vector matches = null;
     int i = 0;
     int max = rawText.length();
@@ -260,7 +260,11 @@ public abstract class ResultParser {
           if (matches == null) {
             matches = new Vector(3); // lazy init
           }
-          matches.addElement(unescapeBackslash(rawText.substring(start, i)));
+          String element = unescapeBackslash(rawText.substring(start, i));
+          if (trim) {
+            element = element.trim();
+          }
+          matches.addElement(element);
           i++;
           done = true;
         }
@@ -272,8 +276,8 @@ public abstract class ResultParser {
     return toStringArray(matches);
   }
 
-  static String matchSinglePrefixedField(String prefix, String rawText, char endChar) {
-    String[] matches = matchPrefixedField(prefix, rawText, endChar);
+  static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) {
+    String[] matches = matchPrefixedField(prefix, rawText, endChar, trim);
     return matches == null ? null : matches[0];
   }
 
index c0717db..aea9152 100644 (file)
@@ -36,30 +36,30 @@ final class VCardResultParser extends ResultParser {
     if (rawText == null || !rawText.startsWith("BEGIN:VCARD") || !rawText.endsWith("END:VCARD")) {
       return null;
     }
-    String[] names = matchVCardPrefixedField("FN", rawText);
+    String[] names = matchVCardPrefixedField("FN", rawText, true);
     if (names == null) {
       // If no display names found, look for regular name fields and format them
-      names = matchVCardPrefixedField("N", rawText);
+      names = matchVCardPrefixedField("N", rawText, true);
       formatNames(names);
     }
-    String[] phoneNumbers = matchVCardPrefixedField("TEL", rawText);
-    String[] emails = matchVCardPrefixedField("EMAIL", rawText);
-    String note = matchSingleVCardPrefixedField("NOTE", rawText);
-    String address = matchSingleVCardPrefixedField("ADR", rawText);
+    String[] phoneNumbers = matchVCardPrefixedField("TEL", rawText, true);
+    String[] emails = matchVCardPrefixedField("EMAIL", rawText, true);
+    String note = matchSingleVCardPrefixedField("NOTE", rawText, false);
+    String address = matchSingleVCardPrefixedField("ADR", rawText, true);
     address = formatAddress(address);
-    String org = matchSingleVCardPrefixedField("ORG", rawText);
-    String birthday = matchSingleVCardPrefixedField("BDAY", rawText);
+    String org = matchSingleVCardPrefixedField("ORG", rawText, true);
+    String birthday = matchSingleVCardPrefixedField("BDAY", rawText, true);
     if (birthday != null && !isStringOfDigits(birthday, 8)) {
       return null;
     }
-    String title = matchSingleVCardPrefixedField("TITLE", rawText);
+    String title = matchSingleVCardPrefixedField("TITLE", rawText, true);
     return new AddressBookParsedResult(names, phoneNumbers, emails, note, address, org, birthday, title); 
   }
 
-  private static String[] matchVCardPrefixedField(String prefix, String rawText) {
+  private static String[] matchVCardPrefixedField(String prefix, String rawText, boolean trim) {
     Vector matches = null;
     int i = 0;
-    int max = rawText.length();
+    final int max = rawText.length();
     while (i < max) {
       i = rawText.indexOf(prefix, i);
       if (i < 0) {
@@ -79,22 +79,23 @@ final class VCardResultParser extends ResultParser {
       }
       i++; // skip colon
       int start = i; // Found the start of a match here
-      boolean done = false;
-      while (!done) {
-        i = rawText.indexOf((int) '\n', i); // Really, ends in \r\n
-        if (i < 0) {
-          // No terminating end character? uh, done. Set i such that loop terminates and break
-          i = rawText.length();
-          done = true;
-        } else {
-          // found a match
-          if (matches == null) {
-            matches = new Vector(3); // lazy init
-          }
-          matches.addElement(rawText.substring(start, i - 1)); // i - 1 to strip off the \r too
-          i++;
-          done = true;
+      i = rawText.indexOf((int) '\n', i); // Really, ends in \r\n
+      if (i < 0) {
+        // No terminating end character? uh, done. Set i such that loop terminates and break
+        i = max;
+      } else if (i > start) {
+        // found a match
+        if (matches == null) {
+          matches = new Vector(3); // lazy init
+        }
+        String element = rawText.substring(start, i);
+        if (trim) {
+          element = element.trim();
         }
+        matches.addElement(element);
+        i++;
+      } else {
+        i++;
       }
     }
     if (matches == null || matches.isEmpty()) {
@@ -103,8 +104,8 @@ final class VCardResultParser extends ResultParser {
     return toStringArray(matches);
   }
 
-  static String matchSingleVCardPrefixedField(String prefix, String rawText) {
-    String[] values = matchVCardPrefixedField(prefix, rawText);
+  static String matchSingleVCardPrefixedField(String prefix, String rawText, boolean trim) {
+    String[] values = matchVCardPrefixedField(prefix, rawText, trim);
     return values == null ? null : values[0];
   }
 
index 188e2d0..33a53da 100644 (file)
@@ -41,9 +41,9 @@ final class VEventResultParser extends ResultParser {
     }
     rawText = rawText.substring(vEventStart + 14, vEventEnd); // skip over BEGIN:VEVENT\r\n at start
 
-    String summary = VCardResultParser.matchSingleVCardPrefixedField("SUMMARY", rawText);
-    String start = VCardResultParser.matchSingleVCardPrefixedField("DTSTART", rawText);
-    String end = VCardResultParser.matchSingleVCardPrefixedField("DTEND", rawText);
+    String summary = VCardResultParser.matchSingleVCardPrefixedField("SUMMARY", rawText, true);
+    String start = VCardResultParser.matchSingleVCardPrefixedField("DTSTART", rawText, true);
+    String end = VCardResultParser.matchSingleVCardPrefixedField("DTEND", rawText, true);
     try {
       return new CalendarParsedResult(summary, start, end, null, null, null);
     } catch (IllegalArgumentException iae) {
index 0b69b34..b09dd71 100644 (file)
@@ -22,7 +22,9 @@ import com.google.zxing.MonochromeBitmapSource;
 import com.google.zxing.ReaderException;
 import com.google.zxing.Result;
 import com.google.zxing.ResultMetadataType;
+import com.google.zxing.ResultPoint;
 import com.google.zxing.common.BitArray;
+import com.google.zxing.common.GenericResultPoint;
 
 import java.util.Hashtable;
 
@@ -126,6 +128,10 @@ public abstract class AbstractOneDReader implements OneDReader {
           if (attempt == 1) {
             // But it was upside down, so note that
             result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
+            // And remember to flip the result points horizontally.
+            ResultPoint[] points = result.getResultPoints();
+            points[0] = new GenericResultPoint(width - points[0].getX() - 1, points[0].getY());
+            points[1] = new GenericResultPoint(width - points[1].getX() - 1, points[1].getY());
           }
           return result;
         } catch (ReaderException re) {
index 0ac86d8..10fb908 100644 (file)
@@ -97,8 +97,8 @@ public final class CommandLineRunner {
     try {
       MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
       Result result = new MultiFormatReader().decode(source, hints);
-      System.out.println(uri.toString() + ": " + result.getText() + " format: " +
-          result.getBarcodeFormat());
+      System.out.println(uri.toString() + " (format: " + result.getBarcodeFormat() + "):\n" +
+          result.getText());
       return true;
     } catch (ReaderException e) {
       System.out.println(uri.toString() + ": No barcode found");