dfa5da084cdc3a608ba7dbac28cd8ba4266c3f39
[zxing.git] / core / src / com / google / zxing / client / result / SMSMMSResultParser.java
1 /*
2  * Copyright 2008 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.result;
18
19 import com.google.zxing.Result;
20
21 import java.util.Hashtable;
22
23 /**
24  * <p>Parses an "sms:" URI result, which specifies a number to SMS and optional
25  * "via" number. See <a href="http://gbiv.com/protocols/uri/drafts/draft-antti-gsm-sms-url-04.txt">
26  * the IETF draft</a> on this.</p>
27  *
28  * <p>This actually also parses URIs starting with "mms:", "smsto:", "mmsto:", "SMSTO:", and
29  * "MMSTO:", and treats them all the same way, and effectively converts them to an "sms:" URI
30  * for purposes of forwarding to the platform.</p>
31  *
32  * @author Sean Owen
33  */
34 final class SMSMMSResultParser extends ResultParser {
35
36   private SMSMMSResultParser() {
37   }
38
39   public static SMSParsedResult parse(Result result) {
40     String rawText = result.getText();
41     if (rawText == null) {
42       return null;
43     }
44     int prefixLength;
45     if (rawText.startsWith("sms:") || rawText.startsWith("SMS:") ||
46         rawText.startsWith("mms:") || rawText.startsWith("MMS:")) {
47       prefixLength = 4;
48     } else if (rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
49                rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:")) {
50       prefixLength = 6;
51     } else {
52       return null;
53     }
54
55     // Check up front if this is a URI syntax string with query arguments
56     Hashtable nameValuePairs = parseNameValuePairs(rawText);
57     String subject = null;
58     String body = null;
59     boolean querySyntax = false;
60     if (nameValuePairs != null && nameValuePairs.size() > 0) {
61       subject = (String) nameValuePairs.get("subject");
62       body = (String) nameValuePairs.get("body");
63       querySyntax = true;
64     }
65
66     // Drop sms, query portion
67     int queryStart = rawText.indexOf('?', prefixLength);
68     String smsURIWithoutQuery;
69     // If it's not query syntax, the question mark is part of the subject or message
70     if (queryStart < 0 || !querySyntax) {
71       smsURIWithoutQuery = rawText.substring(prefixLength);
72     } else {
73       smsURIWithoutQuery = rawText.substring(prefixLength, queryStart);
74     }
75     int numberEnd = smsURIWithoutQuery.indexOf(';');
76     String number;
77     String via;
78     if (numberEnd < 0) {
79       number = smsURIWithoutQuery;
80       via = null;
81     } else {
82       number = smsURIWithoutQuery.substring(0, numberEnd);
83       String maybeVia = smsURIWithoutQuery.substring(numberEnd + 1);
84       if (maybeVia.startsWith("via=")) {
85         via = maybeVia.substring(4);
86       } else {
87         via = null;
88       }
89     }
90
91     // Thanks to dominik.wild for suggesting this enhancement to support
92     // smsto:number:body URIs
93     if (body == null) {
94       int bodyStart = number.indexOf(':');
95       if (bodyStart >= 0) {
96         body = number.substring(bodyStart + 1);
97         number = number.substring(0, bodyStart);
98       }
99     }
100     return new SMSParsedResult("sms:" + number, number, via, subject, body, null);
101   }
102
103 }