Added mms:, mmsto: support and tests, plus basic tests for vCard format
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 27 Jun 2008 18:14:19 +0000 (18:14 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 27 Jun 2008 18:14:19 +0000 (18:14 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@488 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/client/result/ResultParser.java
core/src/com/google/zxing/client/result/SMSMMSResultParser.java [new file with mode: 0644]
core/src/com/google/zxing/client/result/SMSTOResultParser.java [deleted file]
core/src/com/google/zxing/client/result/VCardResultParser.java
core/test/src/com/google/zxing/client/result/ParsedReaderResultTestCase.java

index 2f88fff..c7d0295 100644 (file)
@@ -53,9 +53,7 @@ public abstract class ResultParser {
       return result;
     } else if ((result = TelResultParser.parse(theResult)) != null) {
       return result;
-    } else if ((result = SMSResultParser.parse(theResult)) != null) {
-      return result;
-    } else if ((result = SMSTOResultParser.parse(theResult)) != null) {
+    } else if ((result = SMSMMSResultParser.parse(theResult)) != null) {
       return result;
     } else if ((result = GeoResultParser.parse(theResult)) != null) {
       return result;
@@ -183,6 +181,9 @@ public abstract class ResultParser {
   }
 
   protected static boolean isStringOfDigits(String value, int length) {
+    if (value == null) {
+      return false;
+    }
     int stringLength = value.length();
     if (length != stringLength) {
       return false;
diff --git a/core/src/com/google/zxing/client/result/SMSMMSResultParser.java b/core/src/com/google/zxing/client/result/SMSMMSResultParser.java
new file mode 100644 (file)
index 0000000..83d1e2b
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.result;
+
+import com.google.zxing.Result;
+
+import java.util.Hashtable;
+
+/**
+ * <p>Parses an "sms:" URI result, which specifies a number to SMS and optional
+ * "via" number. See <a href="http://gbiv.com/protocols/uri/drafts/draft-antti-gsm-sms-url-04.txt">
+ * the IETF draft</a> on this.</p>
+ *
+ * <p>This actually also parses URIs starting with "mms:", "smsto:", "mmsto:", "SMSTO:", and
+ * "MMSTO:", and treats them all the same way, and effectively converts them to an "sms:" URI
+ * for purposes of forwarding to the platform.</p>
+ *
+ * @author srowen@google.com (Sean Owen)
+ */
+public final class SMSMMSResultParser extends ResultParser {
+
+  private SMSMMSResultParser() {
+  }
+
+  public static SMSParsedResult parse(Result result) {
+    String rawText = result.getText();
+    if (rawText == null) {
+      return null;
+    }
+    int prefixLength;
+    if (rawText.startsWith("sms:") || rawText.startsWith("mms:")) {
+      prefixLength = 4;
+    } else if (rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
+               rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:")) {
+      prefixLength = 6;
+    } else {
+      return null;
+    }
+    // Drop sms, query portion
+    int queryStart = rawText.indexOf('?', prefixLength);
+    String smsURIWithoutQuery;
+    if (queryStart < 0) {
+      smsURIWithoutQuery = rawText.substring(prefixLength);
+    } else {
+      smsURIWithoutQuery = rawText.substring(prefixLength, queryStart);
+    }
+    int numberEnd = smsURIWithoutQuery.indexOf(';');
+    String number;
+    String via;
+    if (numberEnd < 0) {
+      number = smsURIWithoutQuery;
+      via = null;
+    } else {
+      number = smsURIWithoutQuery.substring(0, numberEnd);
+      String maybeVia = smsURIWithoutQuery.substring(numberEnd + 1);
+      if (maybeVia.startsWith("via=")) {
+        via = maybeVia.substring(4);
+      } else {
+        via = null;
+      }
+    }
+    Hashtable nameValuePairs = parseNameValuePairs(rawText);
+    String subject = null;
+    String body = null;
+    if (nameValuePairs != null) {
+      subject = (String) nameValuePairs.get("subject");
+      body = (String) nameValuePairs.get("body");
+    }
+    return new SMSParsedResult("sms:" + number, number, via, subject, body, null);
+  }
+
+}
\ No newline at end of file
diff --git a/core/src/com/google/zxing/client/result/SMSTOResultParser.java b/core/src/com/google/zxing/client/result/SMSTOResultParser.java
deleted file mode 100644 (file)
index 5730a8a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.zxing.client.result;
-
-import com.google.zxing.Result;
-
-/**
- * Parses an "SMSTO:" result, which specifies a number to SMS.
- *
- * @author srowen@google.com (Sean Owen)
- */
-public final class SMSTOResultParser extends ResultParser {
-
-  private SMSTOResultParser() {
-  }
-
-  public static SMSParsedResult parse(Result result) {
-    String rawText = result.getText();
-    if (rawText == null || !rawText.startsWith("SMSTO:")) {
-      return null;
-    }
-    String number = rawText.substring(6);
-    return new SMSParsedResult("sms:" + number, number, null, null, null, null);
-  }
-
-}
\ No newline at end of file
index 7d5677b..834db4c 100644 (file)
@@ -49,7 +49,7 @@ public final class VCardResultParser extends ResultParser {
     address = formatAddress(address);
     String org = matchSingleVCardPrefixedField("ORG", rawText);
     String birthday = matchSingleVCardPrefixedField("BDAY", rawText);
-    if (!isStringOfDigits(birthday, 8)) {
+    if (birthday != null && !isStringOfDigits(birthday, 8)) {
       return null;
     }
     String title = matchSingleVCardPrefixedField("TITLE", rawText);
@@ -109,6 +109,9 @@ public final class VCardResultParser extends ResultParser {
   }
 
   private static String formatAddress(String address) {
+    if (address == null) {
+      return null;
+    }
     int length = address.length();
     StringBuffer newAddress = new StringBuffer(length);
     for (int j = 0; j < length; j++) {
@@ -129,25 +132,27 @@ public final class VCardResultParser extends ResultParser {
    * @param names name values to format, in place
    */
   private static void formatNames(String[] names) {
-    for (int i = 0; i < names.length; i++) {
-      String name = names[i];
-      String[] components = new String[5];
-      int start = 0;
-      int end;
-      int componentIndex = 0;
-      while ((end = name.indexOf(';', start)) > 0) {
-        components[componentIndex] = name.substring(start, end);
-        componentIndex++;
-        start = end + 1;
+    if (names != null) {
+      for (int i = 0; i < names.length; i++) {
+        String name = names[i];
+        String[] components = new String[5];
+        int start = 0;
+        int end;
+        int componentIndex = 0;
+        while ((end = name.indexOf(';', start)) > 0) {
+          components[componentIndex] = name.substring(start, end);
+          componentIndex++;
+          start = end + 1;
+        }
+        components[componentIndex] = name.substring(start);
+        StringBuffer newName = new StringBuffer();
+        maybeAppendComponent(components, 3, newName);
+        maybeAppendComponent(components, 1, newName);
+        maybeAppendComponent(components, 2, newName);
+        maybeAppendComponent(components, 0, newName);
+        maybeAppendComponent(components, 4, newName);
+        names[i] = newName.toString().trim();
       }
-      components[componentIndex] = name.substring(start);      
-      StringBuffer newName = new StringBuffer();
-      maybeAppendComponent(components, 3, newName);
-      maybeAppendComponent(components, 1, newName);
-      maybeAppendComponent(components, 2, newName);
-      maybeAppendComponent(components, 0, newName);
-      maybeAppendComponent(components, 4, newName);
-      names[i] = newName.toString().trim();
     }
   }
 
index 0766015..8e06a1f 100644 (file)
@@ -106,19 +106,43 @@ public final class ParsedReaderResultTestCase extends TestCase {
     doTestResult("telephone", ParsedResultType.TEXT);
   }
 
+  public void testVCard() {
+    doTestResult("BEGIN:VCARD\r\nEND:VCARD", ParsedResultType.ADDRESSBOOK);
+    doTestResult("BEGIN:VCARD\r\nN:Owen;Sean\r\nEND:VCARD", ParsedResultType.ADDRESSBOOK);
+    doTestResult("BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD", ParsedResultType.ADDRESSBOOK);
+    doTestResult("BEGIN:VCARD\r\nADR;HOME:123 Main St\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD", ParsedResultType.ADDRESSBOOK);    
+    doTestResult("BEGIN:VCARD", ParsedResultType.URI);
+  }
+
+  public void testSMS() {
+    doTestResult("sms:+15551212", ParsedResultType.SMS);
+    doTestResult("SMSTO:+15551212", ParsedResultType.SMS);
+    doTestResult("smsto:+15551212", ParsedResultType.SMS);
+    doTestResult("sms:+15551212;via=999333", ParsedResultType.SMS);
+    doTestResult("sms:+15551212?subject=foo&body=bar", ParsedResultType.SMS);
+  }
+
+  public void testMMS() {
+    doTestResult("mms:+15551212", ParsedResultType.SMS);
+    doTestResult("MMSTO:+15551212", ParsedResultType.SMS);
+    doTestResult("mmsto:+15551212", ParsedResultType.SMS);
+    doTestResult("mms:+15551212;via=999333", ParsedResultType.SMS);
+    doTestResult("mms:+15551212?subject=foo&body=bar", ParsedResultType.SMS);
+  }
+
   /*
   public void testNDEFText() {
     doTestResult(new byte[] {(byte)0xD1,(byte)0x01,(byte)0x05,(byte)0x54,
                              (byte)0x02,(byte)0x65,(byte)0x6E,(byte)0x68,
                              (byte)0x69},
-                 ParsedResultType.NDEF_TEXT);
+                 ParsedResultType.TEXT);
   }
 
   public void testNDEFURI() {
     doTestResult(new byte[] {(byte)0xD1,(byte)0x01,(byte)0x08,(byte)0x55,
                              (byte)0x01,(byte)0x6E,(byte)0x66,(byte)0x63,
                              (byte)0x2E,(byte)0x63,(byte)0x6F,(byte)0x6D},
-                 ParsedResultType.NDEF_URI);
+                 ParsedResultType.URI);
   }
 
   public void testNDEFSmartPoster() {