mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-05-04 06:51:28 +08:00
项目结构调整
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> <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.</p>
|
||||
///
|
||||
/// <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
/// on exception-based mechanisms during parsing.</p>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
abstract class AbstractDoCoMoResultParser : ResultParser
|
||||
{
|
||||
internal static String[] matchDoCoMoPrefixedField(String prefix, String rawText)
|
||||
{
|
||||
return matchPrefixedField(prefix, rawText, ';', true);
|
||||
}
|
||||
|
||||
internal static String matchSingleDoCoMoPrefixedField(String prefix, String rawText, bool trim)
|
||||
{
|
||||
return matchSinglePrefixedField(prefix, rawText, ';', trim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Implements KDDI AU's address book format. See
|
||||
/// <a href="http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html">
|
||||
/// http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.
|
||||
/// (Thanks to Yuzo for translating!)
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class AddressBookAUResultParser : ResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
var rawText = result.Text;
|
||||
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
|
||||
if (rawText == null || rawText.IndexOf("MEMORY") < 0 || rawText.IndexOf("\r\n") < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.
|
||||
// Therefore we treat them specially instead of as an array of names.
|
||||
var name = matchSinglePrefixedField("NAME1:", rawText, '\r', true);
|
||||
var pronunciation = matchSinglePrefixedField("NAME2:", rawText, '\r', true);
|
||||
|
||||
var phoneNumbers = matchMultipleValuePrefix("TEL", rawText);
|
||||
var emails = matchMultipleValuePrefix("MAIL", rawText);
|
||||
var note = matchSinglePrefixedField("MEMORY:", rawText, '\r', false);
|
||||
var address = matchSinglePrefixedField("ADD:", rawText, '\r', true);
|
||||
var addresses = address == null ? null : new[] { address };
|
||||
return new AddressBookParsedResult(maybeWrap(name),
|
||||
null,
|
||||
pronunciation,
|
||||
phoneNumbers,
|
||||
null,
|
||||
emails,
|
||||
null,
|
||||
null,
|
||||
note,
|
||||
addresses,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
private static String[] matchMultipleValuePrefix(String prefix, String rawText)
|
||||
{
|
||||
IList<string> values = null;
|
||||
// For now, always 3, and always trim
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
var value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', true);
|
||||
if (value == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (values == null)
|
||||
{
|
||||
values = new List<string>();
|
||||
}
|
||||
values.Add(value);
|
||||
}
|
||||
if (values == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return SupportClass.toStringArray(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Implements the "MECARD" address book entry format.
|
||||
///
|
||||
/// Supported keys: N, SOUND, TEL, EMAIL, NOTE, ADR, BDAY, URL, plus ORG
|
||||
/// Unsupported keys: TEL-AV, NICKNAME
|
||||
///
|
||||
/// Except for TEL, multiple values for keys are also not supported;
|
||||
/// the first one found takes precedence.
|
||||
///
|
||||
/// Our understanding of the MECARD format is based on this document:
|
||||
///
|
||||
/// http://www.mobicode.org.tw/files/OMIA%20Mobile%20Bar%20Code%20Standard%20v3.2.1.doc
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class AddressBookDoCoMoResultParser : AbstractDoCoMoResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null || !rawText.StartsWith("MECARD:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String[] rawName = matchDoCoMoPrefixedField("N:", rawText);
|
||||
if (rawName == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String name = parseName(rawName[0]);
|
||||
String pronunciation = matchSingleDoCoMoPrefixedField("SOUND:", rawText, true);
|
||||
String[] phoneNumbers = matchDoCoMoPrefixedField("TEL:", rawText);
|
||||
String[] emails = matchDoCoMoPrefixedField("EMAIL:", rawText);
|
||||
String note = matchSingleDoCoMoPrefixedField("NOTE:", rawText, false);
|
||||
String[] addresses = matchDoCoMoPrefixedField("ADR:", rawText);
|
||||
String birthday = matchSingleDoCoMoPrefixedField("BDAY:", rawText, true);
|
||||
if (!isStringOfDigits(birthday, 8))
|
||||
{
|
||||
// No reason to throw out the whole card because the birthday is formatted wrong.
|
||||
birthday = null;
|
||||
}
|
||||
String[] urls = matchDoCoMoPrefixedField("URL:", rawText);
|
||||
|
||||
// Although ORG may not be strictly legal in MECARD, it does exist in VCARD and we might as well
|
||||
// honor it when found in the wild.
|
||||
String org = matchSingleDoCoMoPrefixedField("ORG:", rawText, true);
|
||||
|
||||
return new AddressBookParsedResult(maybeWrap(name),
|
||||
null,
|
||||
pronunciation,
|
||||
phoneNumbers,
|
||||
null,
|
||||
emails,
|
||||
null,
|
||||
null,
|
||||
note,
|
||||
addresses,
|
||||
null,
|
||||
org,
|
||||
birthday,
|
||||
null,
|
||||
urls,
|
||||
null);
|
||||
}
|
||||
|
||||
private static String parseName(String name)
|
||||
{
|
||||
int comma = name.IndexOf(',');
|
||||
if (comma >= 0)
|
||||
{
|
||||
// Format may be last,first; switch it around
|
||||
return name.Substring(comma + 1) + ' ' + name.Substring(0, comma);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes contact information, like that in an address book entry.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class AddressBookParsedResult : ParsedResult
|
||||
{
|
||||
private readonly String[] names;
|
||||
private readonly String[] nicknames;
|
||||
private readonly String pronunciation;
|
||||
private readonly String[] phoneNumbers;
|
||||
private readonly String[] phoneTypes;
|
||||
private readonly String[] emails;
|
||||
private readonly String[] emailTypes;
|
||||
private readonly String instantMessenger;
|
||||
private readonly String note;
|
||||
private readonly String[] addresses;
|
||||
private readonly String[] addressTypes;
|
||||
private readonly String org;
|
||||
private readonly String birthday;
|
||||
private readonly String title;
|
||||
private readonly String[] urls;
|
||||
private readonly String[] geo;
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="names"></param>
|
||||
/// <param name="phoneNumbers"></param>
|
||||
/// <param name="phoneTypes"></param>
|
||||
/// <param name="emails"></param>
|
||||
/// <param name="emailTypes"></param>
|
||||
/// <param name="addresses"></param>
|
||||
/// <param name="addressTypes"></param>
|
||||
public AddressBookParsedResult(String[] names,
|
||||
String[] phoneNumbers,
|
||||
String[] phoneTypes,
|
||||
String[] emails,
|
||||
String[] emailTypes,
|
||||
String[] addresses,
|
||||
String[] addressTypes)
|
||||
: this(names,
|
||||
null,
|
||||
null,
|
||||
phoneNumbers,
|
||||
phoneTypes,
|
||||
emails,
|
||||
emailTypes,
|
||||
null,
|
||||
null,
|
||||
addresses,
|
||||
addressTypes,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="names"></param>
|
||||
/// <param name="nicknames"></param>
|
||||
/// <param name="pronunciation"></param>
|
||||
/// <param name="phoneNumbers"></param>
|
||||
/// <param name="phoneTypes"></param>
|
||||
/// <param name="emails"></param>
|
||||
/// <param name="emailTypes"></param>
|
||||
/// <param name="instantMessenger"></param>
|
||||
/// <param name="note"></param>
|
||||
/// <param name="addresses"></param>
|
||||
/// <param name="addressTypes"></param>
|
||||
/// <param name="org"></param>
|
||||
/// <param name="birthday"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="urls"></param>
|
||||
/// <param name="geo"></param>
|
||||
public AddressBookParsedResult(String[] names,
|
||||
String[] nicknames,
|
||||
String pronunciation,
|
||||
String[] phoneNumbers,
|
||||
String[] phoneTypes,
|
||||
String[] emails,
|
||||
String[] emailTypes,
|
||||
String instantMessenger,
|
||||
String note,
|
||||
String[] addresses,
|
||||
String[] addressTypes,
|
||||
String org,
|
||||
String birthday,
|
||||
String title,
|
||||
String[] urls,
|
||||
String[] geo)
|
||||
: base(ParsedResultType.ADDRESSBOOK)
|
||||
{
|
||||
if (phoneNumbers != null && phoneTypes != null && phoneNumbers.Length != phoneTypes.Length)
|
||||
{
|
||||
throw new ArgumentException("Phone numbers and types lengths differ");
|
||||
}
|
||||
if (emails != null && emailTypes != null && emails.Length != emailTypes.Length)
|
||||
{
|
||||
throw new ArgumentException("Emails and types lengths differ");
|
||||
}
|
||||
if (addresses != null && addressTypes != null && addresses.Length != addressTypes.Length)
|
||||
{
|
||||
throw new ArgumentException("Addresses and types lengths differ");
|
||||
}
|
||||
|
||||
this.names = names;
|
||||
this.nicknames = nicknames;
|
||||
this.pronunciation = pronunciation;
|
||||
this.phoneNumbers = phoneNumbers;
|
||||
this.phoneTypes = phoneTypes;
|
||||
this.emails = emails;
|
||||
this.emailTypes = emailTypes;
|
||||
this.instantMessenger = instantMessenger;
|
||||
this.note = note;
|
||||
this.addresses = addresses;
|
||||
this.addressTypes = addressTypes;
|
||||
this.org = org;
|
||||
this.birthday = birthday;
|
||||
this.title = title;
|
||||
this.urls = urls;
|
||||
this.geo = geo;
|
||||
|
||||
displayResultValue = getDisplayResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the names
|
||||
/// </summary>
|
||||
public String[] Names
|
||||
{
|
||||
get { return names; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the nicknames
|
||||
/// </summary>
|
||||
public String[] Nicknames
|
||||
{
|
||||
get { return nicknames; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint
|
||||
/// is often provided, called furigana, which spells the name phonetically.
|
||||
/// </summary>
|
||||
/// <return>The pronunciation of the getNames() field, often in hiragana or katakana.</return>
|
||||
public String Pronunciation
|
||||
{
|
||||
get { return pronunciation; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the phone numbers
|
||||
/// </summary>
|
||||
public String[] PhoneNumbers
|
||||
{
|
||||
get { return phoneNumbers; }
|
||||
}
|
||||
|
||||
/// <return>optional descriptions of the type of each phone number. It could be like "HOME", but,
|
||||
/// there is no guaranteed or standard format.</return>
|
||||
public String[] PhoneTypes
|
||||
{
|
||||
get { return phoneTypes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the e-mail addresses
|
||||
/// </summary>
|
||||
public String[] Emails
|
||||
{
|
||||
get { return emails; }
|
||||
}
|
||||
|
||||
/// <return>optional descriptions of the type of each e-mail. It could be like "WORK", but,
|
||||
/// there is no guaranteed or standard format.</return>
|
||||
public String[] EmailTypes
|
||||
{
|
||||
get { return emailTypes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the instant messenger addresses
|
||||
/// </summary>
|
||||
public String InstantMessenger
|
||||
{
|
||||
get { return instantMessenger; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the note field
|
||||
/// </summary>
|
||||
public String Note
|
||||
{
|
||||
get { return note; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the addresses
|
||||
/// </summary>
|
||||
public String[] Addresses
|
||||
{
|
||||
get { return addresses; }
|
||||
}
|
||||
|
||||
/// <return>optional descriptions of the type of each e-mail. It could be like "WORK", but,
|
||||
/// there is no guaranteed or standard format.</return>
|
||||
public String[] AddressTypes
|
||||
{
|
||||
get { return addressTypes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the title
|
||||
/// </summary>
|
||||
public String Title
|
||||
{
|
||||
get { return title; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the organisations
|
||||
/// </summary>
|
||||
public String Org
|
||||
{
|
||||
get { return org; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the urls
|
||||
/// </summary>
|
||||
public String[] URLs
|
||||
{
|
||||
get { return urls; }
|
||||
}
|
||||
|
||||
/// <return>birthday formatted as yyyyMMdd (e.g. 19780917)</return>
|
||||
public String Birthday
|
||||
{
|
||||
get { return birthday; }
|
||||
}
|
||||
|
||||
/// <return>a location as a latitude/longitude pair</return>
|
||||
public String[] Geo
|
||||
{
|
||||
get { return geo; }
|
||||
}
|
||||
|
||||
private String getDisplayResult()
|
||||
{
|
||||
var result = new StringBuilder(100);
|
||||
maybeAppend(names, result);
|
||||
maybeAppend(nicknames, result);
|
||||
maybeAppend(pronunciation, result);
|
||||
maybeAppend(title, result);
|
||||
maybeAppend(org, result);
|
||||
maybeAppend(addresses, result);
|
||||
maybeAppend(phoneNumbers, result);
|
||||
maybeAppend(emails, result);
|
||||
maybeAppend(instantMessenger, result);
|
||||
maybeAppend(urls, result);
|
||||
maybeAppend(birthday, result);
|
||||
maybeAppend(geo, result);
|
||||
maybeAppend(note, result);
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Implements the "BIZCARD" address book entry format, though this has been
|
||||
/// largely reverse-engineered from examples observed in the wild -- still
|
||||
/// looking for a definitive reference.
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class BizcardResultParser : AbstractDoCoMoResultParser
|
||||
{
|
||||
// Yes, we extend AbstractDoCoMoResultParser since the format is very much
|
||||
// like the DoCoMo MECARD format, but this is not technically one of
|
||||
// DoCoMo's proposed formats
|
||||
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null || !rawText.StartsWith("BIZCARD:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String firstName = matchSingleDoCoMoPrefixedField("N:", rawText, true);
|
||||
String lastName = matchSingleDoCoMoPrefixedField("X:", rawText, true);
|
||||
String fullName = buildName(firstName, lastName);
|
||||
String title = matchSingleDoCoMoPrefixedField("T:", rawText, true);
|
||||
String org = matchSingleDoCoMoPrefixedField("C:", rawText, true);
|
||||
String[] addresses = matchDoCoMoPrefixedField("A:", rawText);
|
||||
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),
|
||||
null,
|
||||
null,
|
||||
buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3),
|
||||
null,
|
||||
maybeWrap(email),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addresses,
|
||||
null,
|
||||
org,
|
||||
null,
|
||||
title,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
private static String[] buildPhoneNumbers(String number1, String number2, String number3)
|
||||
{
|
||||
var numbers = new List<string>();
|
||||
if (number1 != null)
|
||||
{
|
||||
numbers.Add(number1);
|
||||
}
|
||||
if (number2 != null)
|
||||
{
|
||||
numbers.Add(number2);
|
||||
}
|
||||
if (number3 != null)
|
||||
{
|
||||
numbers.Add(number3);
|
||||
}
|
||||
var size = numbers.Count;
|
||||
if (size == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return SupportClass.toStringArray(numbers);
|
||||
}
|
||||
|
||||
private static String buildName(String firstName, String lastName)
|
||||
{
|
||||
if (firstName == null)
|
||||
{
|
||||
return lastName;
|
||||
}
|
||||
return lastName == null ? firstName : firstName + ' ' + lastName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class BookmarkDoCoMoResultParser : AbstractDoCoMoResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null || !rawText.StartsWith("MEBKM:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String title = matchSingleDoCoMoPrefixedField("TITLE:", rawText, true);
|
||||
String[] rawUri = matchDoCoMoPrefixedField("URL:", rawText);
|
||||
if (rawUri == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String uri = rawUri[0];
|
||||
if (!URIResultParser.isBasicallyValidURI(uri))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new URIParsedResult(uri, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a calendar event at a certain time, optionally with attendees and a location.
|
||||
/// </summary>
|
||||
///<author>Sean Owen</author>
|
||||
public sealed class CalendarParsedResult : ParsedResult
|
||||
{
|
||||
private static readonly Regex RFC2445_DURATION =
|
||||
new Regex(@"\A(?:" + "P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?" + @")\z"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
private static readonly long[] RFC2445_DURATION_FIELD_UNITS =
|
||||
{
|
||||
7*24*60*60*1000L, // 1 week
|
||||
24*60*60*1000L, // 1 day
|
||||
60*60*1000L, // 1 hour
|
||||
60*1000L, // 1 minute
|
||||
1000L, // 1 second
|
||||
};
|
||||
|
||||
private static readonly Regex DATE_TIME = new Regex(@"\A(?:" + "[0-9]{8}(T[0-9]{6}Z?)?" + @")\z"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
private readonly String summary;
|
||||
private readonly DateTime start;
|
||||
private readonly bool startAllDay;
|
||||
private readonly DateTime? end;
|
||||
private readonly bool endAllDay;
|
||||
private readonly String location;
|
||||
private readonly String organizer;
|
||||
private readonly String[] attendees;
|
||||
private readonly String description;
|
||||
private readonly double latitude;
|
||||
private readonly double longitude;
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="summary"></param>
|
||||
/// <param name="startString"></param>
|
||||
/// <param name="endString"></param>
|
||||
/// <param name="durationString"></param>
|
||||
/// <param name="location"></param>
|
||||
/// <param name="organizer"></param>
|
||||
/// <param name="attendees"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <param name="latitude"></param>
|
||||
/// <param name="longitude"></param>
|
||||
public CalendarParsedResult(String summary,
|
||||
String startString,
|
||||
String endString,
|
||||
String durationString,
|
||||
String location,
|
||||
String organizer,
|
||||
String[] attendees,
|
||||
String description,
|
||||
double latitude,
|
||||
double longitude)
|
||||
: base(ParsedResultType.CALENDAR)
|
||||
{
|
||||
this.summary = summary;
|
||||
try
|
||||
{
|
||||
this.start = parseDate(startString);
|
||||
}
|
||||
catch (Exception pe)
|
||||
{
|
||||
throw new ArgumentException(pe.ToString());
|
||||
}
|
||||
|
||||
if (endString == null)
|
||||
{
|
||||
long durationMS = parseDurationMS(durationString);
|
||||
end = durationMS < 0L ? null : (DateTime?)start + new TimeSpan(0, 0, 0, 0, (int)durationMS);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
this.end = parseDate(endString);
|
||||
}
|
||||
catch (Exception pe)
|
||||
{
|
||||
throw new ArgumentException(pe.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
this.startAllDay = startString.Length == 8;
|
||||
this.endAllDay = endString != null && endString.Length == 8;
|
||||
|
||||
this.location = location;
|
||||
this.organizer = organizer;
|
||||
this.attendees = attendees;
|
||||
this.description = description;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
|
||||
var result = new StringBuilder(100);
|
||||
maybeAppend(summary, result);
|
||||
maybeAppend(format(startAllDay, start), result);
|
||||
maybeAppend(format(endAllDay, end), result);
|
||||
maybeAppend(location, result);
|
||||
maybeAppend(organizer, result);
|
||||
maybeAppend(attendees, result);
|
||||
maybeAppend(description, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// summary
|
||||
/// </summary>
|
||||
public String Summary
|
||||
{
|
||||
get { return summary; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start.
|
||||
/// </summary>
|
||||
public DateTime Start
|
||||
{
|
||||
get { return start; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is start all day].
|
||||
/// </summary>
|
||||
/// <returns>if start time was specified as a whole day</returns>
|
||||
public bool isStartAllDay()
|
||||
{
|
||||
return startAllDay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// event end <see cref="DateTime"/>, or null if event has no duration
|
||||
/// </summary>
|
||||
public DateTime? End
|
||||
{
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is end all day.
|
||||
/// </summary>
|
||||
/// <value>true if end time was specified as a whole day</value>
|
||||
public bool isEndAllDay
|
||||
{
|
||||
get { return endAllDay; }
|
||||
}
|
||||
/// <summary>
|
||||
/// location
|
||||
/// </summary>
|
||||
public String Location
|
||||
{
|
||||
get { return location; }
|
||||
}
|
||||
/// <summary>
|
||||
/// organizer
|
||||
/// </summary>
|
||||
public String Organizer
|
||||
{
|
||||
get { return organizer; }
|
||||
}
|
||||
/// <summary>
|
||||
/// attendees
|
||||
/// </summary>
|
||||
public String[] Attendees
|
||||
{
|
||||
get { return attendees; }
|
||||
}
|
||||
/// <summary>
|
||||
/// description
|
||||
/// </summary>
|
||||
public String Description
|
||||
{
|
||||
get { return description; }
|
||||
}
|
||||
/// <summary>
|
||||
/// latitude
|
||||
/// </summary>
|
||||
public double Latitude
|
||||
{
|
||||
get { return latitude; }
|
||||
}
|
||||
/// <summary>
|
||||
/// longitude
|
||||
/// </summary>
|
||||
public double Longitude
|
||||
{
|
||||
get { return longitude; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
|
||||
/// or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
|
||||
/// </summary>
|
||||
/// <param name="when">The string to parse</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException">if not a date formatted string</exception>
|
||||
private static DateTime parseDate(String when)
|
||||
{
|
||||
if (!DATE_TIME.Match(when).Success)
|
||||
{
|
||||
throw new ArgumentException(String.Format("no date format: {0}", when));
|
||||
}
|
||||
if (when.Length == 8)
|
||||
{
|
||||
// Show only year/month/day
|
||||
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
|
||||
// needs to be midnight of that day in GMT. See:
|
||||
// http://code.google.com/p/android/issues/detail?id=8330
|
||||
// format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
return DateTime.ParseExact(when, "yyyyMMdd", CultureInfo.InvariantCulture);
|
||||
}
|
||||
// The when string can be local time, or UTC if it ends with a Z
|
||||
if (when.Length == 16 && when[15] == 'Z')
|
||||
{
|
||||
var milliseconds = parseDateTimeString(when.Substring(0, 15));
|
||||
//Calendar calendar = new GregorianCalendar();
|
||||
// Account for time zone difference
|
||||
//milliseconds += calendar.get(Calendar.ZONE_OFFSET);
|
||||
// Might need to correct for daylight savings time, but use target time since
|
||||
// now might be in DST but not then, or vice versa
|
||||
//calendar.setTime(new Date(milliseconds));
|
||||
//return milliseconds + calendar.get(Calendar.DST_OFFSET);
|
||||
milliseconds = TimeZoneInfo.ConvertTime(milliseconds, TimeZoneInfo.Local);
|
||||
return milliseconds;
|
||||
}
|
||||
return parseDateTimeString(when);
|
||||
}
|
||||
|
||||
private static String format(bool allDay, DateTime? date)
|
||||
{
|
||||
if (date == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (allDay)
|
||||
return date.Value.ToString("D", CultureInfo.CurrentCulture);
|
||||
return date.Value.ToString("F", CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
private static long parseDurationMS(String durationString)
|
||||
{
|
||||
if (durationString == null)
|
||||
{
|
||||
return -1L;
|
||||
}
|
||||
var m = RFC2445_DURATION.Match(durationString);
|
||||
if (!m.Success)
|
||||
{
|
||||
return -1L;
|
||||
}
|
||||
long durationMS = 0L;
|
||||
for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.Length; i++)
|
||||
{
|
||||
String fieldValue = m.Groups[i + 1].Value;
|
||||
if (!String.IsNullOrEmpty(fieldValue))
|
||||
{
|
||||
durationMS += RFC2445_DURATION_FIELD_UNITS[i] * Int32.Parse(fieldValue);
|
||||
}
|
||||
}
|
||||
return durationMS;
|
||||
}
|
||||
|
||||
private static DateTime parseDateTimeString(String dateTimeString)
|
||||
{
|
||||
return DateTime.ParseExact(dateTimeString, "yyyyMMdd'T'HHmmss", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes an email message including recipients, subject and body text.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class EmailAddressParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// the email address
|
||||
/// </summary>
|
||||
public String EmailAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
return Tos == null || Tos.Length == 0 ? null : Tos[0];
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the TOs
|
||||
/// </summary>
|
||||
public String[] Tos { get; private set; }
|
||||
/// <summary>
|
||||
/// the CCs
|
||||
/// </summary>
|
||||
public String[] CCs { get; private set; }
|
||||
/// <summary>
|
||||
/// the BCCs
|
||||
/// </summary>
|
||||
public String[] BCCs { get; private set; }
|
||||
/// <summary>
|
||||
/// the subject
|
||||
/// </summary>
|
||||
public String Subject { get; private set; }
|
||||
/// <summary>
|
||||
/// the body
|
||||
/// </summary>
|
||||
public String Body { get; private set; }
|
||||
/// <summary>
|
||||
/// the mailto: uri
|
||||
/// </summary>
|
||||
[Obsolete("deprecated without replacement")]
|
||||
public String MailtoURI { get { return "mailto:"; } }
|
||||
|
||||
internal EmailAddressParsedResult(String to)
|
||||
: this(new[] { to }, null, null, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal EmailAddressParsedResult(String[] tos,
|
||||
String[] ccs,
|
||||
String[] bccs,
|
||||
String subject,
|
||||
String body)
|
||||
: base(ParsedResultType.EMAIL_ADDRESS)
|
||||
{
|
||||
Tos = tos;
|
||||
CCs = ccs;
|
||||
BCCs = bccs;
|
||||
Subject = subject;
|
||||
Body = body;
|
||||
|
||||
var result = new StringBuilder(30);
|
||||
maybeAppend(Tos, result);
|
||||
maybeAppend(CCs, result);
|
||||
maybeAppend(BCCs, result);
|
||||
maybeAppend(Subject, result);
|
||||
maybeAppend(Body, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a result that encodes an e-mail address, either as a plain address
|
||||
/// like "joe@example.org" or a mailto: URL like "mailto:joe@example.org".
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
internal sealed class EmailAddressResultParser : ResultParser
|
||||
{
|
||||
private static readonly Regex COMMA = new Regex(","
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (rawText.ToLower().StartsWith("mailto:"))
|
||||
{
|
||||
// If it starts with mailto:, assume it is definitely trying to be an email address
|
||||
String hostEmail = rawText.Substring(7);
|
||||
int queryStart = hostEmail.IndexOf('?');
|
||||
if (queryStart >= 0)
|
||||
{
|
||||
hostEmail = hostEmail.Substring(0, queryStart);
|
||||
}
|
||||
hostEmail = urlDecode(hostEmail);
|
||||
String[] tos = null;
|
||||
if (!String.IsNullOrEmpty(hostEmail))
|
||||
{
|
||||
tos = COMMA.Split(hostEmail);
|
||||
}
|
||||
var nameValues = parseNameValuePairs(rawText);
|
||||
String[] ccs = null;
|
||||
String[] bccs = null;
|
||||
String subject = null;
|
||||
String body = null;
|
||||
if (nameValues != null)
|
||||
{
|
||||
if (tos == null)
|
||||
{
|
||||
String tosString;
|
||||
if (nameValues.TryGetValue("to", out tosString) && tosString != null)
|
||||
{
|
||||
tos = COMMA.Split(tosString);
|
||||
}
|
||||
}
|
||||
String ccString;
|
||||
if (nameValues.TryGetValue("cc", out ccString) && ccString != null)
|
||||
{
|
||||
ccs = COMMA.Split(ccString);
|
||||
}
|
||||
String bccString;
|
||||
if (nameValues.TryGetValue("bcc", out bccString) && bccString != null)
|
||||
{
|
||||
bccs = COMMA.Split(bccString);
|
||||
}
|
||||
nameValues.TryGetValue("subject", out subject);
|
||||
nameValues.TryGetValue("body", out body);
|
||||
}
|
||||
return new EmailAddressParsedResult(tos, ccs, bccs, subject, body);
|
||||
}
|
||||
if (!EmailDoCoMoResultParser.isBasicallyValidEmailAddress(rawText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new EmailAddressParsedResult(rawText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the "MATMSG" email message entry format.
|
||||
///
|
||||
/// Supported keys: TO, SUB, BODY
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
internal sealed class EmailDoCoMoResultParser : AbstractDoCoMoResultParser
|
||||
{
|
||||
private static readonly Regex ATEXT_ALPHANUMERIC = new Regex(@"\A(?:" + "[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+" + @")\z"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
var rawText = result.Text;
|
||||
if (!rawText.StartsWith("MATMSG:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var tos = matchDoCoMoPrefixedField("TO:", rawText);
|
||||
if (tos == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (var index = 0; index < tos.Length; index++)
|
||||
{
|
||||
var to = tos[index];
|
||||
if (!isBasicallyValidEmailAddress(to))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
var subject = matchSingleDoCoMoPrefixedField("SUB:", rawText, false);
|
||||
var body = matchSingleDoCoMoPrefixedField("BODY:", rawText, false);
|
||||
return new EmailAddressParsedResult(tos, null, null, subject, body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This implements only the most basic checking for an email address's validity -- that it contains
|
||||
/// an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of
|
||||
/// validity. We want to generally be lenient here since this class is only intended to encapsulate what's
|
||||
/// in a barcode, not "judge" it.
|
||||
/// </summary>
|
||||
/// <param name="email">The email.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if it is basically a valid email address; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
internal static bool isBasicallyValidEmailAddress(String email)
|
||||
{
|
||||
return email != null && ATEXT_ALPHANUMERIC.Match(email).Success && email.IndexOf('@') >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These authors would like to acknowledge the Spanish Ministry of Industry,
|
||||
* Tourism and Trade, for the support in the project TSI020301-2008-2
|
||||
* "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
|
||||
* Mobile Dynamic Environments", led by Treelogic
|
||||
* ( http://www.treelogic.com/ ):
|
||||
*
|
||||
* http://www.piramidepse.com/
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes extended product information as encoded by the RSS format, like weight, price, dates, etc.
|
||||
/// </summary>
|
||||
/// <author> Antonio Manuel Benjumea Conde, Servinform, S.A.</author>
|
||||
/// <author> Agustín Delgado, Servinform, S.A.</author>
|
||||
public class ExpandedProductParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// extension for kilogram weight type
|
||||
/// </summary>
|
||||
public static String KILOGRAM = "KG";
|
||||
/// <summary>
|
||||
/// extension for pounds weight type
|
||||
/// </summary>
|
||||
public static String POUND = "LB";
|
||||
|
||||
private readonly String rawText;
|
||||
private readonly String productID;
|
||||
private readonly String sscc;
|
||||
private readonly String lotNumber;
|
||||
private readonly String productionDate;
|
||||
private readonly String packagingDate;
|
||||
private readonly String bestBeforeDate;
|
||||
private readonly String expirationDate;
|
||||
private readonly String weight;
|
||||
private readonly String weightType;
|
||||
private readonly String weightIncrement;
|
||||
private readonly String price;
|
||||
private readonly String priceIncrement;
|
||||
private readonly String priceCurrency;
|
||||
// For AIS that not exist in this object
|
||||
private readonly IDictionary<String, String> uncommonAIs;
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="rawText"></param>
|
||||
/// <param name="productID"></param>
|
||||
/// <param name="sscc"></param>
|
||||
/// <param name="lotNumber"></param>
|
||||
/// <param name="productionDate"></param>
|
||||
/// <param name="packagingDate"></param>
|
||||
/// <param name="bestBeforeDate"></param>
|
||||
/// <param name="expirationDate"></param>
|
||||
/// <param name="weight"></param>
|
||||
/// <param name="weightType"></param>
|
||||
/// <param name="weightIncrement"></param>
|
||||
/// <param name="price"></param>
|
||||
/// <param name="priceIncrement"></param>
|
||||
/// <param name="priceCurrency"></param>
|
||||
/// <param name="uncommonAIs"></param>
|
||||
public ExpandedProductParsedResult(String rawText,
|
||||
String productID,
|
||||
String sscc,
|
||||
String lotNumber,
|
||||
String productionDate,
|
||||
String packagingDate,
|
||||
String bestBeforeDate,
|
||||
String expirationDate,
|
||||
String weight,
|
||||
String weightType,
|
||||
String weightIncrement,
|
||||
String price,
|
||||
String priceIncrement,
|
||||
String priceCurrency,
|
||||
IDictionary<String, String> uncommonAIs)
|
||||
: base(ParsedResultType.PRODUCT)
|
||||
{
|
||||
this.rawText = rawText;
|
||||
this.productID = productID;
|
||||
this.sscc = sscc;
|
||||
this.lotNumber = lotNumber;
|
||||
this.productionDate = productionDate;
|
||||
this.packagingDate = packagingDate;
|
||||
this.bestBeforeDate = bestBeforeDate;
|
||||
this.expirationDate = expirationDate;
|
||||
this.weight = weight;
|
||||
this.weightType = weightType;
|
||||
this.weightIncrement = weightIncrement;
|
||||
this.price = price;
|
||||
this.priceIncrement = priceIncrement;
|
||||
this.priceCurrency = priceCurrency;
|
||||
this.uncommonAIs = uncommonAIs;
|
||||
|
||||
displayResultValue = productID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Equals(Object o)
|
||||
{
|
||||
if (!(o is ExpandedProductParsedResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var other = (ExpandedProductParsedResult)o;
|
||||
|
||||
return equalsOrNull(productID, other.productID)
|
||||
&& equalsOrNull(sscc, other.sscc)
|
||||
&& equalsOrNull(lotNumber, other.lotNumber)
|
||||
&& equalsOrNull(productionDate, other.productionDate)
|
||||
&& equalsOrNull(bestBeforeDate, other.bestBeforeDate)
|
||||
&& equalsOrNull(expirationDate, other.expirationDate)
|
||||
&& equalsOrNull(weight, other.weight)
|
||||
&& equalsOrNull(weightType, other.weightType)
|
||||
&& equalsOrNull(weightIncrement, other.weightIncrement)
|
||||
&& equalsOrNull(price, other.price)
|
||||
&& equalsOrNull(priceIncrement, other.priceIncrement)
|
||||
&& equalsOrNull(priceCurrency, other.priceCurrency)
|
||||
&& equalsOrNull(uncommonAIs, other.uncommonAIs);
|
||||
}
|
||||
|
||||
private static bool equalsOrNull(Object o1, Object o2)
|
||||
{
|
||||
return o1 == null ? o2 == null : o1.Equals(o2);
|
||||
}
|
||||
|
||||
private static bool equalsOrNull(IDictionary<String, String> o1, IDictionary<String, String> o2)
|
||||
{
|
||||
if (o1 == null)
|
||||
return o2 == null;
|
||||
if (o1.Count != o2.Count)
|
||||
return false;
|
||||
foreach (var entry in o1)
|
||||
{
|
||||
if (!o2.ContainsKey(entry.Key))
|
||||
return false;
|
||||
if (!entry.Value.Equals(o2[entry.Key]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hash = 0;
|
||||
hash ^= hashNotNull(productID);
|
||||
hash ^= hashNotNull(sscc);
|
||||
hash ^= hashNotNull(lotNumber);
|
||||
hash ^= hashNotNull(productionDate);
|
||||
hash ^= hashNotNull(bestBeforeDate);
|
||||
hash ^= hashNotNull(expirationDate);
|
||||
hash ^= hashNotNull(weight);
|
||||
hash ^= hashNotNull(weightType);
|
||||
hash ^= hashNotNull(weightIncrement);
|
||||
hash ^= hashNotNull(price);
|
||||
hash ^= hashNotNull(priceIncrement);
|
||||
hash ^= hashNotNull(priceCurrency);
|
||||
hash ^= hashNotNull(uncommonAIs);
|
||||
return hash;
|
||||
}
|
||||
|
||||
private static int hashNotNull(Object o)
|
||||
{
|
||||
return o == null ? 0 : o.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the raw text
|
||||
/// </summary>
|
||||
public String RawText
|
||||
{
|
||||
get { return rawText; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the product id
|
||||
/// </summary>
|
||||
public String ProductID
|
||||
{
|
||||
get { return productID; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the sscc
|
||||
/// </summary>
|
||||
public String Sscc
|
||||
{
|
||||
get { return sscc; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the lot number
|
||||
/// </summary>
|
||||
public String LotNumber
|
||||
{
|
||||
get { return lotNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the production date
|
||||
/// </summary>
|
||||
public String ProductionDate
|
||||
{
|
||||
get { return productionDate; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the packaging date
|
||||
/// </summary>
|
||||
public String PackagingDate
|
||||
{
|
||||
get { return packagingDate; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the best before date
|
||||
/// </summary>
|
||||
public String BestBeforeDate
|
||||
{
|
||||
get { return bestBeforeDate; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the expiration date
|
||||
/// </summary>
|
||||
public String ExpirationDate
|
||||
{
|
||||
get { return expirationDate; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the weight
|
||||
/// </summary>
|
||||
public String Weight
|
||||
{
|
||||
get { return weight; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the weight type
|
||||
/// </summary>
|
||||
public String WeightType
|
||||
{
|
||||
get { return weightType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the weight increment
|
||||
/// </summary>
|
||||
public String WeightIncrement
|
||||
{
|
||||
get { return weightIncrement; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the price
|
||||
/// </summary>
|
||||
public String Price
|
||||
{
|
||||
get { return price; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the price increment
|
||||
/// </summary>
|
||||
public String PriceIncrement
|
||||
{
|
||||
get { return priceIncrement; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the price currency
|
||||
/// </summary>
|
||||
public String PriceCurrency
|
||||
{
|
||||
get { return priceCurrency; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the uncommon AIs
|
||||
/// </summary>
|
||||
public IDictionary<String, String> UncommonAIs
|
||||
{
|
||||
get { return uncommonAIs; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the display representation (raw text)
|
||||
/// </summary>
|
||||
public override string DisplayResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return rawText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These authors would like to acknowledge the Spanish Ministry of Industry,
|
||||
* Tourism and Trade, for the support in the project TSI020301-2008-2
|
||||
* "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
|
||||
* Mobile Dynamic Environments", led by Treelogic
|
||||
* ( http://www.treelogic.com/ ):
|
||||
*
|
||||
* http://www.piramidepse.com/
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses strings of digits that represent a RSS Extended code.
|
||||
/// </summary>
|
||||
/// <author>Antonio Manuel Benjumea Conde, Servinform, S.A.</author>
|
||||
/// <author>Agustín Delgado, Servinform, S.A.</author>
|
||||
public class ExpandedProductResultParser : ResultParser
|
||||
{
|
||||
/// <summary>
|
||||
/// tries to parse a text representation to a specific result object
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
BarcodeFormat format = result.BarcodeFormat;
|
||||
if (format != BarcodeFormat.RSS_EXPANDED)
|
||||
{
|
||||
// ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
|
||||
return null;
|
||||
}
|
||||
String rawText = result.Text;
|
||||
|
||||
String productID = null;
|
||||
String sscc = null;
|
||||
String lotNumber = null;
|
||||
String productionDate = null;
|
||||
String packagingDate = null;
|
||||
String bestBeforeDate = null;
|
||||
String expirationDate = null;
|
||||
String weight = null;
|
||||
String weightType = null;
|
||||
String weightIncrement = null;
|
||||
String price = null;
|
||||
String priceIncrement = null;
|
||||
String priceCurrency = null;
|
||||
var uncommonAIs = new Dictionary<String, String>();
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (i < rawText.Length)
|
||||
{
|
||||
String ai = findAIvalue(i, rawText);
|
||||
if (ai == null)
|
||||
{
|
||||
// Error. Code doesn't match with RSS expanded pattern
|
||||
// ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
|
||||
return null;
|
||||
}
|
||||
i += ai.Length + 2;
|
||||
String value = findValue(i, rawText);
|
||||
i += value.Length;
|
||||
|
||||
if ("00".Equals(ai))
|
||||
{
|
||||
sscc = value;
|
||||
}
|
||||
else if ("01".Equals(ai))
|
||||
{
|
||||
productID = value;
|
||||
}
|
||||
else if ("10".Equals(ai))
|
||||
{
|
||||
lotNumber = value;
|
||||
}
|
||||
else if ("11".Equals(ai))
|
||||
{
|
||||
productionDate = value;
|
||||
}
|
||||
else if ("13".Equals(ai))
|
||||
{
|
||||
packagingDate = value;
|
||||
}
|
||||
else if ("15".Equals(ai))
|
||||
{
|
||||
bestBeforeDate = value;
|
||||
}
|
||||
else if ("17".Equals(ai))
|
||||
{
|
||||
expirationDate = value;
|
||||
}
|
||||
else if ("3100".Equals(ai) || "3101".Equals(ai)
|
||||
|| "3102".Equals(ai) || "3103".Equals(ai)
|
||||
|| "3104".Equals(ai) || "3105".Equals(ai)
|
||||
|| "3106".Equals(ai) || "3107".Equals(ai)
|
||||
|| "3108".Equals(ai) || "3109".Equals(ai))
|
||||
{
|
||||
weight = value;
|
||||
weightType = ExpandedProductParsedResult.KILOGRAM;
|
||||
weightIncrement = ai.Substring(3);
|
||||
}
|
||||
else if ("3200".Equals(ai) || "3201".Equals(ai)
|
||||
|| "3202".Equals(ai) || "3203".Equals(ai)
|
||||
|| "3204".Equals(ai) || "3205".Equals(ai)
|
||||
|| "3206".Equals(ai) || "3207".Equals(ai)
|
||||
|| "3208".Equals(ai) || "3209".Equals(ai))
|
||||
{
|
||||
weight = value;
|
||||
weightType = ExpandedProductParsedResult.POUND;
|
||||
weightIncrement = ai.Substring(3);
|
||||
}
|
||||
else if ("3920".Equals(ai) || "3921".Equals(ai)
|
||||
|| "3922".Equals(ai) || "3923".Equals(ai))
|
||||
{
|
||||
price = value;
|
||||
priceIncrement = ai.Substring(3);
|
||||
}
|
||||
else if ("3930".Equals(ai) || "3931".Equals(ai)
|
||||
|| "3932".Equals(ai) || "3933".Equals(ai))
|
||||
{
|
||||
if (value.Length < 4)
|
||||
{
|
||||
// The value must have more of 3 symbols (3 for currency and
|
||||
// 1 at least for the price)
|
||||
// ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
|
||||
return null;
|
||||
}
|
||||
price = value.Substring(3);
|
||||
priceCurrency = value.Substring(0, 3);
|
||||
priceIncrement = ai.Substring(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match with common AIs
|
||||
uncommonAIs[ai] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return new ExpandedProductParsedResult(rawText,
|
||||
productID,
|
||||
sscc,
|
||||
lotNumber,
|
||||
productionDate,
|
||||
packagingDate,
|
||||
bestBeforeDate,
|
||||
expirationDate,
|
||||
weight,
|
||||
weightType,
|
||||
weightIncrement,
|
||||
price,
|
||||
priceIncrement,
|
||||
priceCurrency,
|
||||
uncommonAIs);
|
||||
}
|
||||
|
||||
private static String findAIvalue(int i, String rawText)
|
||||
{
|
||||
char c = rawText[i];
|
||||
// First character must be a open parenthesis.If not, ERROR
|
||||
if (c != '(')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var rawTextAux = rawText.Substring(i + 1);
|
||||
var buf = new StringBuilder();
|
||||
|
||||
for (int index = 0; index < rawTextAux.Length; index++)
|
||||
{
|
||||
char currentChar = rawTextAux[index];
|
||||
if (currentChar == ')')
|
||||
{
|
||||
return buf.ToString();
|
||||
}
|
||||
if (currentChar < '0' || currentChar > '9')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
buf.Append(currentChar);
|
||||
}
|
||||
return buf.ToString();
|
||||
}
|
||||
|
||||
private static String findValue(int i, String rawText)
|
||||
{
|
||||
var buf = new StringBuilder();
|
||||
var rawTextAux = rawText.Substring(i);
|
||||
|
||||
for (int index = 0; index < rawTextAux.Length; index++)
|
||||
{
|
||||
char c = rawTextAux[index];
|
||||
if (c == '(')
|
||||
{
|
||||
// We look for a new AI. If it doesn't exist (ERROR), we continue
|
||||
// with the iteration
|
||||
if (findAIvalue(index, rawTextAux) != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buf.Append('(');
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(c);
|
||||
}
|
||||
}
|
||||
return buf.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
136
Others/zxing.core/zxing.core/client/result/GeoParsedResult.cs
Normal file
136
Others/zxing.core/zxing.core/client/result/GeoParsedResult.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a geographic coordinate, with latitude, longitude and altitude.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class GeoParsedResult : ParsedResult
|
||||
{
|
||||
internal GeoParsedResult(double latitude, double longitude, double altitude, String query)
|
||||
: base(ParsedResultType.GEO)
|
||||
{
|
||||
Latitude = latitude;
|
||||
Longitude = longitude;
|
||||
Altitude = altitude;
|
||||
Query = query;
|
||||
GeoURI = getGeoURI();
|
||||
GoogleMapsURI = getGoogleMapsURI();
|
||||
displayResultValue = getDisplayResult();
|
||||
}
|
||||
|
||||
/// <returns> latitude in degrees
|
||||
/// </returns>
|
||||
public double Latitude { get; private set; }
|
||||
|
||||
/// <returns> longitude in degrees
|
||||
/// </returns>
|
||||
public double Longitude { get; private set; }
|
||||
|
||||
/// <returns> altitude in meters. If not specified, in the geo URI, returns 0.0
|
||||
/// </returns>
|
||||
public double Altitude { get; private set; }
|
||||
|
||||
/// <return> query string associated with geo URI or null if none exists</return>
|
||||
public String Query { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// the geo URI
|
||||
/// </summary>
|
||||
public String GeoURI { get; private set; }
|
||||
|
||||
/// <returns> a URI link to Google Maps which display the point on the Earth described
|
||||
/// by this instance, and sets the zoom level in a way that roughly reflects the
|
||||
/// altitude, if specified
|
||||
/// </returns>
|
||||
public String GoogleMapsURI { get; private set; }
|
||||
|
||||
private String getDisplayResult()
|
||||
{
|
||||
var result = new StringBuilder(20);
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Latitude);
|
||||
result.Append(", ");
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Longitude);
|
||||
if (Altitude > 0.0)
|
||||
{
|
||||
result.Append(", ");
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Altitude);
|
||||
result.Append('m');
|
||||
}
|
||||
if (Query != null)
|
||||
{
|
||||
result.Append(" (");
|
||||
result.Append(Query);
|
||||
result.Append(')');
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private String getGeoURI()
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
result.Append("geo:");
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Latitude);
|
||||
result.Append(',');
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Longitude);
|
||||
if (Altitude > 0)
|
||||
{
|
||||
result.Append(',');
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Altitude);
|
||||
}
|
||||
if (Query != null)
|
||||
{
|
||||
result.Append('?');
|
||||
result.Append(Query);
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private String getGoogleMapsURI()
|
||||
{
|
||||
var result = new StringBuilder(50);
|
||||
result.Append("http://maps.google.com/?ll=");
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Latitude);
|
||||
result.Append(',');
|
||||
result.AppendFormat(CultureInfo.InvariantCulture, "{0:0.0###########}", Longitude);
|
||||
if (Altitude > 0.0f)
|
||||
{
|
||||
// Map altitude to zoom level, cleverly. Roughly, zoom level 19 is like a
|
||||
// view from 1000ft, 18 is like 2000ft, 17 like 4000ft, and so on.
|
||||
double altitudeInFeet = Altitude * 3.28;
|
||||
int altitudeInKFeet = (int)(altitudeInFeet / 1000.0);
|
||||
// No Math.log() available here, so compute log base 2 the old fashioned way
|
||||
// Here logBaseTwo will take on a value between 0 and 18 actually
|
||||
int logBaseTwo = 0;
|
||||
while (altitudeInKFeet > 1 && logBaseTwo < 18)
|
||||
{
|
||||
altitudeInKFeet >>= 1;
|
||||
logBaseTwo++;
|
||||
}
|
||||
int zoom = 19 - logBaseTwo;
|
||||
result.Append("&z=");
|
||||
result.Append(zoom);
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
102
Others/zxing.core/zxing.core/client/result/GeoResultParser.cs
Normal file
102
Others/zxing.core/zxing.core/client/result/GeoResultParser.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Parses a "geo:" URI result, which specifies a location on the surface of
|
||||
/// the Earth as well as an optional altitude above the surface. See
|
||||
/// <a href="http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00">
|
||||
/// http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00</a>.
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class GeoResultParser : ResultParser
|
||||
{
|
||||
private static readonly Regex GEO_URL_PATTERN = new Regex(@"\A(?:" + "geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?" + @")\z"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
#else
|
||||
, RegexOptions.IgnoreCase);
|
||||
#endif
|
||||
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var matcher = GEO_URL_PATTERN.Match(rawText);
|
||||
if (!matcher.Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String query = matcher.Groups[4].Value;
|
||||
if (String.IsNullOrEmpty(query))
|
||||
query = null;
|
||||
|
||||
double latitude;
|
||||
double longitude;
|
||||
double altitude = 0.0;
|
||||
#if WindowsCE
|
||||
try { latitude = Double.Parse(matcher.Groups[1].Value, NumberStyles.Float, CultureInfo.InvariantCulture); }
|
||||
catch { return null; }
|
||||
#else
|
||||
if (!Double.TryParse(matcher.Groups[1].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out latitude))
|
||||
return null;
|
||||
#endif
|
||||
if (latitude > 90.0 || latitude < -90.0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#if WindowsCE
|
||||
try { longitude = Double.Parse(matcher.Groups[2].Value, NumberStyles.Float, CultureInfo.InvariantCulture); }
|
||||
catch { return null; }
|
||||
#else
|
||||
if (!Double.TryParse(matcher.Groups[2].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out longitude))
|
||||
return null;
|
||||
#endif
|
||||
if (longitude > 180.0 || longitude < -180.0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!String.IsNullOrEmpty(matcher.Groups[3].Value))
|
||||
{
|
||||
#if WindowsCE
|
||||
try { altitude = Double.Parse(matcher.Groups[3].Value, NumberStyles.Float, CultureInfo.InvariantCulture); }
|
||||
catch { return null; }
|
||||
#else
|
||||
if (!Double.TryParse(matcher.Groups[3].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out altitude))
|
||||
return null;
|
||||
#endif
|
||||
if (altitude < 0.0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new GeoParsedResult(latitude, longitude, altitude, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a product ISBN number.
|
||||
/// </summary>
|
||||
/// <author>jbreiden@google.com (Jeff Breidenbach)</author>
|
||||
public sealed class ISBNParsedResult : ParsedResult
|
||||
{
|
||||
internal ISBNParsedResult(String isbn)
|
||||
: base(ParsedResultType.ISBN)
|
||||
{
|
||||
ISBN = isbn;
|
||||
displayResultValue = isbn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the ISBN number
|
||||
/// </summary>
|
||||
public String ISBN { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Parses strings of digits that represent a ISBN.
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> jbreiden@google.com (Jeff Breidenbach)
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
public class ISBNResultParser : ResultParser
|
||||
{
|
||||
/// <summary>
|
||||
/// See <a href="http://www.bisg.org/isbn-13/for.dummies.html">ISBN-13 For Dummies</a>
|
||||
/// </summary>
|
||||
/// <param name="result">The result.</param>
|
||||
/// <returns></returns>
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
BarcodeFormat format = result.BarcodeFormat;
|
||||
if (format != BarcodeFormat.EAN_13)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String rawText = result.Text;
|
||||
int length = rawText.Length;
|
||||
if (length != 13)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!rawText.StartsWith("978") && !rawText.StartsWith("979"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ISBNParsedResult(rawText);
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Others/zxing.core/zxing.core/client/result/ParsedResult.cs
Normal file
114
Others/zxing.core/zxing.core/client/result/ParsedResult.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> <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 ResultParser#parseResult(Result)} 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>
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public abstract class ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// user friendly value
|
||||
/// </summary>
|
||||
protected string displayResultValue;
|
||||
/// <summary>
|
||||
/// gets the type of the parsed result
|
||||
/// </summary>
|
||||
public virtual ParsedResultType Type { get; private set; }
|
||||
/// <summary>
|
||||
/// user friendly value
|
||||
/// </summary>
|
||||
public virtual String DisplayResult { get { return displayResultValue; } }
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
protected ParsedResult(ParsedResultType type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
/// <summary>
|
||||
/// gets a user friendly value
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override String ToString()
|
||||
{
|
||||
return DisplayResult;
|
||||
}
|
||||
/// <summary>
|
||||
/// compare two objects
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as ParsedResult;
|
||||
if (other == null)
|
||||
return false;
|
||||
return other.Type.Equals(Type) && other.DisplayResult.Equals(DisplayResult);
|
||||
}
|
||||
/// <summary>
|
||||
/// gets the hashcode
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Type.GetHashCode() + DisplayResult.GetHashCode();
|
||||
}
|
||||
/// <summary>
|
||||
/// append to result if not null or empty
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="result"></param>
|
||||
public static void maybeAppend(String value, StringBuilder result)
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
return;
|
||||
|
||||
// Don't add a newline before the first value
|
||||
if (result.Length > 0)
|
||||
{
|
||||
result.Append('\n');
|
||||
}
|
||||
result.Append(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// append to result if not null or empty
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <param name="result"></param>
|
||||
public static void maybeAppend(String[] values, StringBuilder result)
|
||||
{
|
||||
if (values != null)
|
||||
{
|
||||
foreach (String value in values)
|
||||
{
|
||||
maybeAppend(value, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the type of data encoded by a barcode -- from plain text, to a
|
||||
/// URI, to an e-mail address, etc.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public enum ParsedResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// address book
|
||||
/// </summary>
|
||||
ADDRESSBOOK,
|
||||
/// <summary>
|
||||
/// email address
|
||||
/// </summary>
|
||||
EMAIL_ADDRESS,
|
||||
/// <summary>
|
||||
/// product
|
||||
/// </summary>
|
||||
PRODUCT,
|
||||
/// <summary>
|
||||
/// URI
|
||||
/// </summary>
|
||||
URI,
|
||||
/// <summary>
|
||||
/// Text
|
||||
/// </summary>
|
||||
TEXT,
|
||||
/// <summary>
|
||||
/// geo coordinates
|
||||
/// </summary>
|
||||
GEO,
|
||||
/// <summary>
|
||||
/// telefon
|
||||
/// </summary>
|
||||
TEL,
|
||||
/// <summary>
|
||||
/// sms
|
||||
/// </summary>
|
||||
SMS,
|
||||
/// <summary>
|
||||
/// calendar
|
||||
/// </summary>
|
||||
CALENDAR,
|
||||
/// <summary>
|
||||
/// wifi
|
||||
/// </summary>
|
||||
WIFI,
|
||||
/// <summary>
|
||||
/// ISBN
|
||||
/// </summary>
|
||||
ISBN,
|
||||
/// <summary>
|
||||
/// VIN
|
||||
/// </summary>
|
||||
VIN
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a product by an identifier of some kind.
|
||||
/// </summary>
|
||||
/// <author>dswitkin@google.com (Daniel Switkin)</author>
|
||||
public sealed class ProductParsedResult : ParsedResult
|
||||
{
|
||||
internal ProductParsedResult(String productID)
|
||||
: this(productID, productID)
|
||||
{
|
||||
}
|
||||
|
||||
internal ProductParsedResult(String productID, String normalizedProductID)
|
||||
: base(ParsedResultType.PRODUCT)
|
||||
{
|
||||
ProductID = productID;
|
||||
NormalizedProductID = normalizedProductID;
|
||||
displayResultValue = productID;
|
||||
}
|
||||
/// <summary>
|
||||
/// product id
|
||||
/// </summary>
|
||||
public String ProductID { get; private set; }
|
||||
/// <summary>
|
||||
/// normalized product id
|
||||
/// </summary>
|
||||
public String NormalizedProductID { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using ZXing.OneD;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses strings of digits that represent a UPC code.
|
||||
/// </summary>
|
||||
/// <author>dswitkin@google.com (Daniel Switkin)</author>
|
||||
internal sealed class ProductResultParser : ResultParser
|
||||
{
|
||||
// Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
BarcodeFormat format = result.BarcodeFormat;
|
||||
if (!(format == BarcodeFormat.UPC_A || format == BarcodeFormat.UPC_E ||
|
||||
format == BarcodeFormat.EAN_8 || format == BarcodeFormat.EAN_13))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Really neither of these should happen:
|
||||
String rawText = result.Text;
|
||||
if (rawText == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isStringOfDigits(rawText, rawText.Length))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Not actually checking the checksum again here
|
||||
|
||||
String normalizedProductID;
|
||||
// Expand UPC-E for purposes of searching
|
||||
if (format == BarcodeFormat.UPC_E && rawText.Length == 8)
|
||||
{
|
||||
normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalizedProductID = rawText;
|
||||
}
|
||||
|
||||
return new ProductParsedResult(rawText, normalizedProductID);
|
||||
}
|
||||
}
|
||||
}
|
||||
408
Others/zxing.core/zxing.core/client/result/ResultParser.cs
Normal file
408
Others/zxing.core/zxing.core/client/result/ResultParser.cs
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> <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 #parseResult(com.google.zxing.Result)} 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>
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public abstract class ResultParser
|
||||
{
|
||||
private static readonly ResultParser[] PARSERS =
|
||||
{
|
||||
new BookmarkDoCoMoResultParser(),
|
||||
new AddressBookDoCoMoResultParser(),
|
||||
new EmailDoCoMoResultParser(),
|
||||
new AddressBookAUResultParser(),
|
||||
new VCardResultParser(),
|
||||
new BizcardResultParser(),
|
||||
new VEventResultParser(),
|
||||
new EmailAddressResultParser(),
|
||||
new SMTPResultParser(),
|
||||
new TelResultParser(),
|
||||
new SMSMMSResultParser(),
|
||||
new SMSTOMMSTOResultParser(),
|
||||
new GeoResultParser(),
|
||||
new WifiResultParser(),
|
||||
new URLTOResultParser(),
|
||||
new URIResultParser(),
|
||||
new ISBNResultParser(),
|
||||
new ProductResultParser(),
|
||||
new ExpandedProductResultParser(),
|
||||
new VINResultParser(),
|
||||
};
|
||||
|
||||
#if SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
|
||||
private static readonly Regex DIGITS = new Regex(@"\A(?:" + "\\d+" + @")\z");
|
||||
private static readonly Regex AMPERSAND = new Regex("&");
|
||||
private static readonly Regex EQUALS = new Regex("=");
|
||||
#else
|
||||
private static readonly Regex DIGITS = new Regex(@"\A(?:" + "\\d+" + @")\z", RegexOptions.Compiled);
|
||||
private static readonly Regex AMPERSAND = new Regex("&", RegexOptions.Compiled);
|
||||
private static readonly Regex EQUALS = new Regex("=", RegexOptions.Compiled);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to parse the raw {@link Result}'s contents as a particular type
|
||||
/// of information (email, URL, etc.) and return a {@link ParsedResult} encapsulating
|
||||
/// the result of parsing.
|
||||
/// </summary>
|
||||
/// <param name="theResult">the raw <see cref="Result"/> to parse</param>
|
||||
/// <returns><see cref="ParsedResult" /> encapsulating the parsing result</returns>
|
||||
public abstract ParsedResult parse(ZXing.Result theResult);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the result.
|
||||
/// </summary>
|
||||
/// <param name="theResult">The result.</param>
|
||||
/// <returns></returns>
|
||||
public static ParsedResult parseResult(ZXing.Result theResult)
|
||||
{
|
||||
foreach (var parser in PARSERS)
|
||||
{
|
||||
var result = parser.parse(theResult);
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return new TextParsedResult(theResult.Text, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// append value to result, if not null
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="result"></param>
|
||||
protected static void maybeAppend(String value, System.Text.StringBuilder result)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
result.Append('\n');
|
||||
result.Append(value);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// append value to result, if not null
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="result"></param>
|
||||
protected static void maybeAppend(String[] value, System.Text.StringBuilder result)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
result.Append('\n');
|
||||
result.Append(value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// wrap, if not null
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
protected static String[] maybeWrap(String value)
|
||||
{
|
||||
return value == null ? null : new[] { value };
|
||||
}
|
||||
/// <summary>
|
||||
/// unescape backslash
|
||||
/// </summary>
|
||||
/// <param name="escaped"></param>
|
||||
/// <returns></returns>
|
||||
protected static String unescapeBackslash(String escaped)
|
||||
{
|
||||
if (escaped != null)
|
||||
{
|
||||
int backslash = escaped.IndexOf('\\');
|
||||
if (backslash >= 0)
|
||||
{
|
||||
int max = escaped.Length;
|
||||
var unescaped = new System.Text.StringBuilder(max - 1);
|
||||
unescaped.Append(escaped.ToCharArray(), 0, backslash);
|
||||
bool nextIsEscaped = false;
|
||||
for (int i = backslash; i < max; i++)
|
||||
{
|
||||
char c = escaped[i];
|
||||
if (nextIsEscaped || c != '\\')
|
||||
{
|
||||
unescaped.Append(c);
|
||||
nextIsEscaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextIsEscaped = true;
|
||||
}
|
||||
}
|
||||
return unescaped.ToString();
|
||||
}
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
/// <summary>
|
||||
/// parse hex digit
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
protected static int parseHexDigit(char c)
|
||||
{
|
||||
if (c >= 'a')
|
||||
{
|
||||
if (c <= 'f')
|
||||
{
|
||||
return 10 + (c - 'a');
|
||||
}
|
||||
}
|
||||
else if (c >= 'A')
|
||||
{
|
||||
if (c <= 'F')
|
||||
{
|
||||
return 10 + (c - 'A');
|
||||
}
|
||||
}
|
||||
else if (c >= '0')
|
||||
{
|
||||
if (c <= '9')
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal static bool isStringOfDigits(String value, int length)
|
||||
{
|
||||
return value != null && length > 0 && length == value.Length && DIGITS.Match(value).Success;
|
||||
}
|
||||
|
||||
internal static bool isSubstringOfDigits(String value, int offset, int length)
|
||||
{
|
||||
if (value == null || length <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int max = offset + length;
|
||||
return value.Length >= max && DIGITS.Match(value, offset, length).Success;
|
||||
}
|
||||
|
||||
internal static IDictionary<string, string> parseNameValuePairs(String uri)
|
||||
{
|
||||
int paramStart = uri.IndexOf('?');
|
||||
if (paramStart < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var result = new Dictionary<String, String>(3);
|
||||
foreach (var keyValue in AMPERSAND.Split(uri.Substring(paramStart + 1)))
|
||||
{
|
||||
appendKeyValue(keyValue, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void appendKeyValue(String keyValue, IDictionary<String, String> result)
|
||||
{
|
||||
String[] keyValueTokens = EQUALS.Split(keyValue, 2);
|
||||
if (keyValueTokens.Length == 2)
|
||||
{
|
||||
String key = keyValueTokens[0];
|
||||
String value = keyValueTokens[1];
|
||||
try
|
||||
{
|
||||
//value = URLDecoder.decode(value, "UTF-8");
|
||||
value = urlDecode(value);
|
||||
result[key] = value;
|
||||
}
|
||||
catch (Exception uee)
|
||||
{
|
||||
throw new InvalidOperationException("url decoding failed", uee); // can't happen
|
||||
}
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static String[] matchPrefixedField(String prefix, String rawText, char endChar, bool trim)
|
||||
{
|
||||
IList<string> matches = null;
|
||||
int i = 0;
|
||||
int max = rawText.Length;
|
||||
while (i < max)
|
||||
{
|
||||
i = rawText.IndexOf(prefix, i);
|
||||
if (i < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i += prefix.Length; // Skip past this prefix we found to start
|
||||
int start = i; // Found the start of a match here
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
i = rawText.IndexOf(endChar, i);
|
||||
if (i < 0)
|
||||
{
|
||||
// No terminating end character? uh, done. Set i such that loop terminates and break
|
||||
i = rawText.Length;
|
||||
done = true;
|
||||
}
|
||||
else if (countPrecedingBackslashes(rawText, i) % 2 != 0)
|
||||
{
|
||||
// semicolon was escaped (odd count of preceding backslashes) so continue
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// found a match
|
||||
if (matches == null)
|
||||
{
|
||||
matches = new List<string>();
|
||||
}
|
||||
String element = unescapeBackslash(rawText.Substring(start, (i) - (start)));
|
||||
if (trim)
|
||||
{
|
||||
element = element.Trim();
|
||||
}
|
||||
if (!String.IsNullOrEmpty(element))
|
||||
{
|
||||
matches.Add(element);
|
||||
}
|
||||
i++;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches == null || (matches.Count == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return SupportClass.toStringArray(matches);
|
||||
}
|
||||
|
||||
private static int countPrecedingBackslashes(String s, int pos)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = pos - 1; i >= 0; i--)
|
||||
{
|
||||
if (s[i] == '\\')
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
internal static String matchSinglePrefixedField(String prefix, String rawText, char endChar, bool trim)
|
||||
{
|
||||
String[] matches = matchPrefixedField(prefix, rawText, endChar, trim);
|
||||
return matches == null ? null : matches[0];
|
||||
}
|
||||
/// <summary>
|
||||
/// decodes url
|
||||
/// </summary>
|
||||
/// <param name="escaped"></param>
|
||||
/// <returns></returns>
|
||||
protected static String urlDecode(String escaped)
|
||||
{
|
||||
// Should we better use HttpUtility.UrlDecode?
|
||||
// Is HttpUtility.UrlDecode available for all platforms?
|
||||
// What about encoding like UTF8?
|
||||
|
||||
if (escaped == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
char[] escapedArray = escaped.ToCharArray();
|
||||
|
||||
int first = findFirstEscape(escapedArray);
|
||||
if (first < 0)
|
||||
{
|
||||
return escaped;
|
||||
}
|
||||
|
||||
int max = escapedArray.Length;
|
||||
// final length is at most 2 less than original due to at least 1 unescaping
|
||||
var unescaped = new System.Text.StringBuilder(max - 2);
|
||||
// Can append everything up to first escape character
|
||||
unescaped.Append(escapedArray, 0, first);
|
||||
|
||||
for (int i = first; i < max; i++)
|
||||
{
|
||||
char c = escapedArray[i];
|
||||
if (c == '+')
|
||||
{
|
||||
// + is translated directly into a space
|
||||
unescaped.Append(' ');
|
||||
}
|
||||
else if (c == '%')
|
||||
{
|
||||
// Are there even two more chars? if not we will just copy the escaped sequence and be done
|
||||
if (i >= max - 2)
|
||||
{
|
||||
unescaped.Append('%'); // append that % and move on
|
||||
}
|
||||
else
|
||||
{
|
||||
int firstDigitValue = parseHexDigit(escapedArray[++i]);
|
||||
int secondDigitValue = parseHexDigit(escapedArray[++i]);
|
||||
if (firstDigitValue < 0 || secondDigitValue < 0)
|
||||
{
|
||||
// bad digit, just move on
|
||||
unescaped.Append('%');
|
||||
unescaped.Append(escapedArray[i - 1]);
|
||||
unescaped.Append(escapedArray[i]);
|
||||
}
|
||||
unescaped.Append((char)((firstDigitValue << 4) + secondDigitValue));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unescaped.Append(c);
|
||||
}
|
||||
}
|
||||
return unescaped.ToString();
|
||||
}
|
||||
|
||||
private static int findFirstEscape(char[] escapedArray)
|
||||
{
|
||||
int max = escapedArray.Length;
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
char c = escapedArray[i];
|
||||
if (c == '+' || c == '%')
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Others/zxing.core/zxing.core/client/result/SMSMMSResultParser.cs
Normal file
118
Others/zxing.core/zxing.core/client/result/SMSMMSResultParser.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> <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>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class SMSMMSResultParser : ResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null ||
|
||||
!(rawText.StartsWith("sms:") || rawText.StartsWith("SMS:") ||
|
||||
rawText.StartsWith("mms:") || rawText.StartsWith("MMS:")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check up front if this is a URI syntax string with query arguments
|
||||
var nameValuePairs = parseNameValuePairs(rawText);
|
||||
String subject = null;
|
||||
String body = null;
|
||||
var querySyntax = false;
|
||||
if (nameValuePairs != null && nameValuePairs.Count != 0)
|
||||
{
|
||||
subject = nameValuePairs["subject"];
|
||||
body = nameValuePairs["body"];
|
||||
querySyntax = true;
|
||||
}
|
||||
|
||||
// Drop sms, query portion
|
||||
//UPGRADE_WARNING: Method 'java.lang.String.indexOf' was converted to 'System.String.IndexOf' which may throw an exception. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1101'"
|
||||
var queryStart = rawText.IndexOf('?', 4);
|
||||
String smsURIWithoutQuery;
|
||||
// If it's not query syntax, the question mark is part of the subject or message
|
||||
if (queryStart < 0 || !querySyntax)
|
||||
{
|
||||
smsURIWithoutQuery = rawText.Substring(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
smsURIWithoutQuery = rawText.Substring(4, (queryStart) - (4));
|
||||
}
|
||||
|
||||
int lastComma = -1;
|
||||
int comma;
|
||||
var numbers = new List<String>(1);
|
||||
var vias = new List<String>(1);
|
||||
while ((comma = smsURIWithoutQuery.IndexOf(',', lastComma + 1)) > lastComma)
|
||||
{
|
||||
String numberPart = smsURIWithoutQuery.Substring(lastComma + 1, comma);
|
||||
addNumberVia(numbers, vias, numberPart);
|
||||
lastComma = comma;
|
||||
}
|
||||
addNumberVia(numbers, vias, smsURIWithoutQuery.Substring(lastComma + 1));
|
||||
|
||||
return new SMSParsedResult(SupportClass.toStringArray(numbers),
|
||||
SupportClass.toStringArray(vias),
|
||||
subject,
|
||||
body);
|
||||
}
|
||||
|
||||
private static void addNumberVia(ICollection<String> numbers,
|
||||
ICollection<String> vias,
|
||||
String numberPart)
|
||||
{
|
||||
int numberEnd = numberPart.IndexOf(';');
|
||||
if (numberEnd < 0)
|
||||
{
|
||||
numbers.Add(numberPart);
|
||||
vias.Add(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
numbers.Add(numberPart.Substring(0, numberEnd));
|
||||
String maybeVia = numberPart.Substring(numberEnd + 1);
|
||||
String via;
|
||||
if (maybeVia.StartsWith("via="))
|
||||
{
|
||||
via = maybeVia.Substring(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
via = null;
|
||||
}
|
||||
vias.Add(via);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
Others/zxing.core/zxing.core/client/result/SMSParsedResult.cs
Normal file
134
Others/zxing.core/zxing.core/client/result/SMSParsedResult.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes an SMS message, including recipients, subject and body text.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class SMSParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="via"></param>
|
||||
/// <param name="subject"></param>
|
||||
/// <param name="body"></param>
|
||||
public SMSParsedResult(String number,
|
||||
String via,
|
||||
String subject,
|
||||
String body)
|
||||
: this(new[] { number }, new[] { via }, subject, body)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="numbers"></param>
|
||||
/// <param name="vias"></param>
|
||||
/// <param name="subject"></param>
|
||||
/// <param name="body"></param>
|
||||
public SMSParsedResult(String[] numbers,
|
||||
String[] vias,
|
||||
String subject,
|
||||
String body)
|
||||
: base(ParsedResultType.SMS)
|
||||
{
|
||||
Numbers = numbers;
|
||||
Vias = vias;
|
||||
Subject = subject;
|
||||
Body = body;
|
||||
SMSURI = getSMSURI();
|
||||
|
||||
var result = new StringBuilder(100);
|
||||
maybeAppend(Numbers, result);
|
||||
maybeAppend(Subject, result);
|
||||
maybeAppend(Body, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
|
||||
private String getSMSURI()
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
result.Append("sms:");
|
||||
bool first = true;
|
||||
for (int i = 0; i < Numbers.Length; i++)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Append(',');
|
||||
}
|
||||
result.Append(Numbers[i]);
|
||||
if (Vias != null && Vias[i] != null)
|
||||
{
|
||||
result.Append(";via=");
|
||||
result.Append(Vias[i]);
|
||||
}
|
||||
}
|
||||
bool hasBody = Body != null;
|
||||
bool hasSubject = Subject != null;
|
||||
if (hasBody || hasSubject)
|
||||
{
|
||||
result.Append('?');
|
||||
if (hasBody)
|
||||
{
|
||||
result.Append("body=");
|
||||
result.Append(Body);
|
||||
}
|
||||
if (hasSubject)
|
||||
{
|
||||
if (hasBody)
|
||||
{
|
||||
result.Append('&');
|
||||
}
|
||||
result.Append("subject=");
|
||||
result.Append(Subject);
|
||||
}
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// numbers
|
||||
/// </summary>
|
||||
public String[] Numbers { get; private set; }
|
||||
/// <summary>
|
||||
/// vias
|
||||
/// </summary>
|
||||
public String[] Vias { get; private set; }
|
||||
/// <summary>
|
||||
/// subject
|
||||
/// </summary>
|
||||
public String Subject { get; private set; }
|
||||
/// <summary>
|
||||
/// body
|
||||
/// </summary>
|
||||
public String Body { get; private set; }
|
||||
/// <summary>
|
||||
/// sms uri
|
||||
/// </summary>
|
||||
public String SMSURI { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// <p>Parses an "smsto:" URI result, whose format is not standardized but appears to be like:
|
||||
/// {@code smsto:number(:body)}.</p>
|
||||
/// <p>This actually also parses URIs starting with "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>
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public class SMSTOMMSTOResultParser : ResultParser
|
||||
{
|
||||
/// <summary>
|
||||
/// attempt to parse the raw result to the specific type
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (!(rawText.StartsWith("smsto:") || rawText.StartsWith("SMSTO:") ||
|
||||
rawText.StartsWith("mmsto:") || rawText.StartsWith("MMSTO:")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Thanks to dominik.wild for suggesting this enhancement to support
|
||||
// smsto:number:body URIs
|
||||
String number = rawText.Substring(6);
|
||||
String body = null;
|
||||
int bodyStart = number.IndexOf(':');
|
||||
if (bodyStart >= 0)
|
||||
{
|
||||
body = number.Substring(bodyStart + 1);
|
||||
number = number.Substring(0, bodyStart);
|
||||
}
|
||||
return new SMSParsedResult(number, null, null, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// <p>Parses an "smtp:" URI result, whose format is not standardized but appears to be like:
|
||||
/// <code>smtp[:subject[:body]]}</code>.</p>
|
||||
/// <p>See http://code.google.com/p/zxing/issues/detail?id=536</p>
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public class SMTPResultParser : ResultParser
|
||||
{
|
||||
/// <summary>
|
||||
/// attempt to parse the raw result to the specific type
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (!(rawText.StartsWith("smtp:") || rawText.StartsWith("SMTP:")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String emailAddress = rawText.Substring(5);
|
||||
String subject = null;
|
||||
String body = null;
|
||||
int colon = emailAddress.IndexOf(':');
|
||||
if (colon >= 0)
|
||||
{
|
||||
subject = emailAddress.Substring(colon + 1);
|
||||
emailAddress = emailAddress.Substring(0, colon);
|
||||
colon = subject.IndexOf(':');
|
||||
if (colon >= 0)
|
||||
{
|
||||
body = subject.Substring(colon + 1);
|
||||
subject = subject.Substring(0, colon);
|
||||
}
|
||||
}
|
||||
return new EmailAddressParsedResult(new[] { emailAddress },
|
||||
null,
|
||||
null,
|
||||
subject,
|
||||
body);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a telephone number.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class TelParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <param name="telURI"></param>
|
||||
/// <param name="title"></param>
|
||||
public TelParsedResult(String number, String telURI, String title)
|
||||
: base(ParsedResultType.TEL)
|
||||
{
|
||||
Number = number;
|
||||
TelURI = telURI;
|
||||
Title = title;
|
||||
|
||||
var result = new System.Text.StringBuilder(20);
|
||||
maybeAppend(number, result);
|
||||
maybeAppend(title, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// number
|
||||
/// </summary>
|
||||
public String Number { get; private set; }
|
||||
/// <summary>
|
||||
/// URI
|
||||
/// </summary>
|
||||
public String TelURI { get; private set; }
|
||||
/// <summary>
|
||||
/// title
|
||||
/// </summary>
|
||||
public String Title { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses a "tel:" URI result, which specifies a phone number.
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class TelResultParser : ResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null ||
|
||||
(!rawText.StartsWith("tel:") && !rawText.StartsWith("TEL:")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Normalize "TEL:" to "tel:"
|
||||
String telURI = rawText.StartsWith("TEL:") ? "tel:" + rawText.Substring(4) : rawText;
|
||||
// Drop tel, query portion
|
||||
//UPGRADE_WARNING: Method 'java.lang.String.indexOf' was converted to 'System.String.IndexOf' which may throw an exception. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1101'"
|
||||
int queryStart = rawText.IndexOf('?', 4);
|
||||
String number = queryStart < 0 ? rawText.Substring(4) : rawText.Substring(4, (queryStart) - (4));
|
||||
return new TelParsedResult(number, telURI, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple result type encapsulating a string that has no further interpretation.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class TextParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="language"></param>
|
||||
public TextParsedResult(String text, String language)
|
||||
: base(ParsedResultType.TEXT)
|
||||
{
|
||||
Text = text;
|
||||
Language = language;
|
||||
displayResultValue = text;
|
||||
}
|
||||
/// <summary>
|
||||
/// text
|
||||
/// </summary>
|
||||
public String Text { get; private set; }
|
||||
/// <summary>
|
||||
/// language
|
||||
/// </summary>
|
||||
public String Language { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple result type encapsulating a URI that has no further interpretation.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
public sealed class URIParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// URI
|
||||
/// </summary>
|
||||
public String URI { get; private set; }
|
||||
/// <summary>
|
||||
/// title
|
||||
/// </summary>
|
||||
public String Title { get; private set; }
|
||||
|
||||
/// <returns> true if the URI contains suspicious patterns that may suggest it intends to
|
||||
/// mislead the user about its true nature. At the moment this looks for the presence
|
||||
/// of user/password syntax in the host/authority portion of a URI which may be used
|
||||
/// in attempts to make the URI's host appear to be other than it is. Example:
|
||||
/// http://yourbank.com@phisher.com This URI connects to phisher.com but may appear
|
||||
/// to connect to yourbank.com at first glance.
|
||||
/// </returns>
|
||||
[Obsolete("deprecated, see {@link URIResultParser#isPossiblyMaliciousURI(String)")]
|
||||
public bool PossiblyMaliciousURI { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
/// <param name="title"></param>
|
||||
public URIParsedResult(String uri, String title)
|
||||
: base(ParsedResultType.URI)
|
||||
{
|
||||
URI = massageURI(uri);
|
||||
Title = title;
|
||||
PossiblyMaliciousURI = URIResultParser.isPossiblyMaliciousURI(uri);
|
||||
|
||||
var result = new System.Text.StringBuilder(30);
|
||||
maybeAppend(Title, result);
|
||||
maybeAppend(URI, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
|
||||
/// <summary> Transforms a string that represents a URI into something more proper, by adding or canonicalizing
|
||||
/// the protocol.
|
||||
/// </summary>
|
||||
private static String massageURI(String uri)
|
||||
{
|
||||
int protocolEnd = uri.IndexOf(':');
|
||||
if (protocolEnd < 0 || isColonFollowedByPortNumber(uri, protocolEnd))
|
||||
{
|
||||
// No protocol, or found a colon, but it looks like it is after the host, so the protocol is still missing,
|
||||
// so assume http
|
||||
uri = "http://" + uri;
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
private static bool isColonFollowedByPortNumber(String uri, int protocolEnd)
|
||||
{
|
||||
int start = protocolEnd + 1;
|
||||
int nextSlash = uri.IndexOf('/', start);
|
||||
if (nextSlash < 0)
|
||||
{
|
||||
nextSlash = uri.Length;
|
||||
}
|
||||
return ResultParser.isSubstringOfDigits(uri, start, nextSlash - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Others/zxing.core/zxing.core/client/result/URIResultParser.cs
Normal file
105
Others/zxing.core/zxing.core/client/result/URIResultParser.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to parse results that are a URI of some kind.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
sealed class URIResultParser : ResultParser
|
||||
{
|
||||
private static readonly Regex ALLOWED_URI_CHARS_PATTERN = new Regex("^[-._~:/?#\\[\\]@!$&'()*+,;=%A-Za-z0-9]+$"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
private static readonly Regex USER_IN_HOST = new Regex(":/*([^/@]+)@[^/]+"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
// See http://www.ietf.org/rfc/rfc2396.txt
|
||||
private static readonly Regex URL_WITH_PROTOCOL_PATTERN = new Regex("[a-zA-Z][a-zA-Z0-9+-.]+:"
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
private static readonly Regex URL_WITHOUT_PROTOCOL_PATTERN = new Regex(
|
||||
"([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}" + // host name elements
|
||||
"(:\\d{1,5})?" + // maybe port
|
||||
"(/|\\?|$)" // query, path or nothing
|
||||
#if !(SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2)
|
||||
, RegexOptions.Compiled);
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
// We specifically handle the odd "URL" scheme here for simplicity and add "URI" for fun
|
||||
// Assume anything starting this way really means to be a URI
|
||||
if (rawText.StartsWith("URL:") || rawText.StartsWith("URI:"))
|
||||
{
|
||||
return new URIParsedResult(rawText.Substring(4).Trim(), null);
|
||||
}
|
||||
rawText = rawText.Trim();
|
||||
if (!isBasicallyValidURI(rawText) || isPossiblyMaliciousURI(rawText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new URIParsedResult(rawText, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the URI contains suspicious patterns that may suggest it intends to
|
||||
* mislead the user about its true nature. At the moment this looks for the presence
|
||||
* of user/password syntax in the host/authority portion of a URI which may be used
|
||||
* in attempts to make the URI's host appear to be other than it is. Example:
|
||||
* http://yourbank.com@phisher.com This URI connects to phisher.com but may appear
|
||||
* to connect to yourbank.com at first glance.
|
||||
*/
|
||||
internal static bool isPossiblyMaliciousURI(String uri)
|
||||
{
|
||||
return !ALLOWED_URI_CHARS_PATTERN.Match(uri).Success || USER_IN_HOST.Match(uri).Success;
|
||||
}
|
||||
|
||||
internal static bool isBasicallyValidURI(String uri)
|
||||
{
|
||||
if (uri.IndexOf(" ") >= 0)
|
||||
{
|
||||
// Quick hack check for a common case
|
||||
return false;
|
||||
}
|
||||
var m = URL_WITH_PROTOCOL_PATTERN.Match(uri);
|
||||
if (m.Success && m.Index == 0)
|
||||
{
|
||||
// match at start only
|
||||
return true;
|
||||
}
|
||||
m = URL_WITHOUT_PROTOCOL_PATTERN.Match(uri);
|
||||
return m.Success && m.Index == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary> Parses the "URLTO" result format, which is of the form "URLTO:[title]:[url]".
|
||||
/// This seems to be used sometimes, but I am not able to find documentation
|
||||
/// on its origin or official format?
|
||||
///
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class URLTOResultParser : ResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
var rawText = result.Text;
|
||||
if (rawText == null ||
|
||||
(!rawText.StartsWith("urlto:") && !rawText.StartsWith("URLTO:")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//UPGRADE_WARNING: Method 'java.lang.String.indexOf' was converted to 'System.String.IndexOf' which may throw an exception. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1101'"
|
||||
int titleEnd = rawText.IndexOf(':', 6);
|
||||
if (titleEnd < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var title = titleEnd <= 6 ? null : rawText.Substring(6, (titleEnd) - (6));
|
||||
var uri = rawText.Substring(titleEnd + 1);
|
||||
return new URIParsedResult(uri, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
490
Others/zxing.core/zxing.core/client/result/VCardResultParser.cs
Normal file
490
Others/zxing.core/zxing.core/client/result/VCardResultParser.cs
Normal file
@@ -0,0 +1,490 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses contact information formatted according to the VCard (2.1) format. This is not a complete
|
||||
/// implementation but should parse information as commonly encoded in 2D barcodes.
|
||||
/// </summary>
|
||||
/// <author>Sean Owen</author>
|
||||
sealed class VCardResultParser : ResultParser
|
||||
{
|
||||
#if SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
|
||||
private static readonly Regex BEGIN_VCARD = new Regex("BEGIN:VCARD", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex VCARD_LIKE_DATE = new Regex(@"\A(?:" + "\\d{4}-?\\d{2}-?\\d{2}" + @")\z");
|
||||
private static readonly Regex CR_LF_SPACE_TAB = new Regex("\r\n[ \t]");
|
||||
private static readonly Regex NEWLINE_ESCAPE = new Regex("\\\\[nN]");
|
||||
private static readonly Regex VCARD_ESCAPES = new Regex("\\\\([,;\\\\])");
|
||||
private static readonly Regex EQUALS = new Regex("=");
|
||||
private static readonly Regex SEMICOLON = new Regex(";");
|
||||
private static readonly Regex UNESCAPED_SEMICOLONS = new Regex("(?<!\\\\);+");
|
||||
private static readonly Regex COMMA = new Regex(",");
|
||||
private static readonly Regex SEMICOLON_OR_COMMA = new Regex("[;,]");
|
||||
#else
|
||||
private static readonly Regex BEGIN_VCARD = new Regex("BEGIN:VCARD", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex VCARD_LIKE_DATE = new Regex(@"\A(?:" + "\\d{4}-?\\d{2}-?\\d{2}" + @")\z", RegexOptions.Compiled);
|
||||
private static readonly Regex CR_LF_SPACE_TAB = new Regex("\r\n[ \t]", RegexOptions.Compiled);
|
||||
private static readonly Regex NEWLINE_ESCAPE = new Regex("\\\\[nN]", RegexOptions.Compiled);
|
||||
private static readonly Regex VCARD_ESCAPES = new Regex("\\\\([,;\\\\])", RegexOptions.Compiled);
|
||||
private static readonly Regex EQUALS = new Regex("=", RegexOptions.Compiled);
|
||||
private static readonly Regex SEMICOLON = new Regex(";", RegexOptions.Compiled);
|
||||
private static readonly Regex UNESCAPED_SEMICOLONS = new Regex("(?<!\\\\);+", RegexOptions.Compiled);
|
||||
private static readonly Regex COMMA = new Regex(",", RegexOptions.Compiled);
|
||||
private static readonly Regex SEMICOLON_OR_COMMA = new Regex("[;,]", RegexOptions.Compiled);
|
||||
#endif
|
||||
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
// Although we should insist on the raw text ending with "END:VCARD", there's no reason
|
||||
// to throw out everything else we parsed just because this was omitted. In fact, Eclair
|
||||
// is doing just that, and we can't parse its contacts without this leniency.
|
||||
String rawText = result.Text;
|
||||
var m = BEGIN_VCARD.Match(rawText);
|
||||
if (!m.Success || m.Index != 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<List<String>> names = matchVCardPrefixedField("FN", rawText, true, false);
|
||||
if (names == null)
|
||||
{
|
||||
// If no display names found, look for regular name fields and format them
|
||||
names = matchVCardPrefixedField("N", rawText, true, false);
|
||||
formatNames(names);
|
||||
}
|
||||
List<String> nicknameString = matchSingleVCardPrefixedField("NICKNAME", rawText, true, false);
|
||||
String[] nicknames = nicknameString == null ? null : COMMA.Split(nicknameString[0]);
|
||||
List<List<String>> phoneNumbers = matchVCardPrefixedField("TEL", rawText, true, false);
|
||||
List<List<String>> emails = matchVCardPrefixedField("EMAIL", rawText, true, false);
|
||||
List<String> note = matchSingleVCardPrefixedField("NOTE", rawText, false, false);
|
||||
List<List<String>> addresses = matchVCardPrefixedField("ADR", rawText, true, true);
|
||||
List<String> org = matchSingleVCardPrefixedField("ORG", rawText, true, true);
|
||||
List<String> birthday = matchSingleVCardPrefixedField("BDAY", rawText, true, false);
|
||||
if (birthday != null && !isLikeVCardDate(birthday[0]))
|
||||
{
|
||||
birthday = null;
|
||||
}
|
||||
List<String> title = matchSingleVCardPrefixedField("TITLE", rawText, true, false);
|
||||
List<List<String>> urls = matchVCardPrefixedField("URL", rawText, true, false);
|
||||
List<String> instantMessenger = matchSingleVCardPrefixedField("IMPP", rawText, true, false);
|
||||
List<String> geoString = matchSingleVCardPrefixedField("GEO", rawText, true, false);
|
||||
String[] geo = geoString == null ? null : SEMICOLON_OR_COMMA.Split(geoString[0]);
|
||||
if (geo != null && geo.Length != 2)
|
||||
{
|
||||
geo = null;
|
||||
}
|
||||
return new AddressBookParsedResult(toPrimaryValues(names),
|
||||
nicknames,
|
||||
null,
|
||||
toPrimaryValues(phoneNumbers),
|
||||
toTypes(phoneNumbers),
|
||||
toPrimaryValues(emails),
|
||||
toTypes(emails),
|
||||
toPrimaryValue(instantMessenger),
|
||||
toPrimaryValue(note),
|
||||
toPrimaryValues(addresses),
|
||||
toTypes(addresses),
|
||||
toPrimaryValue(org),
|
||||
toPrimaryValue(birthday),
|
||||
toPrimaryValue(title),
|
||||
toPrimaryValues(urls),
|
||||
geo);
|
||||
}
|
||||
|
||||
public static List<List<String>> matchVCardPrefixedField(String prefix,
|
||||
String rawText,
|
||||
bool trim,
|
||||
bool parseFieldDivider)
|
||||
{
|
||||
List<List<String>> matches = null;
|
||||
int i = 0;
|
||||
int max = rawText.Length;
|
||||
|
||||
while (i < max)
|
||||
{
|
||||
// At start or after newline, match prefix, followed by optional metadata
|
||||
// (led by ;) ultimately ending in colon
|
||||
var matcher = new Regex("(?:^|\n)" + prefix + "(?:;([^:]*))?:", RegexOptions.IgnoreCase);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
i--; // Find from i-1 not i since looking at the preceding character
|
||||
}
|
||||
var match = matcher.Match(rawText, i);
|
||||
if (!match.Success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i = match.Index + match.Length;
|
||||
|
||||
String metadataString = match.Groups[1].Value; // group 1 = metadata substring
|
||||
List<String> metadata = null;
|
||||
bool quotedPrintable = false;
|
||||
String quotedPrintableCharset = null;
|
||||
String valueType = null;
|
||||
if (metadataString != null)
|
||||
{
|
||||
foreach (String metadatum in SEMICOLON.Split(metadataString))
|
||||
{
|
||||
if (metadata == null)
|
||||
{
|
||||
metadata = new List<String>(1);
|
||||
}
|
||||
metadata.Add(metadatum);
|
||||
String[] metadatumTokens = EQUALS.Split(metadatum, 2);
|
||||
if (metadatumTokens.Length > 1)
|
||||
{
|
||||
String key = metadatumTokens[0];
|
||||
String value = metadatumTokens[1];
|
||||
if (String.Compare("ENCODING", key, StringComparison.OrdinalIgnoreCase) == 0 &&
|
||||
String.Compare("QUOTED-PRINTABLE", value, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
quotedPrintable = true;
|
||||
}
|
||||
else if (String.Compare("CHARSET", key, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
quotedPrintableCharset = value;
|
||||
}
|
||||
else if (String.Compare("VALUE", key, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
valueType = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int matchStart = i; // Found the start of a match here
|
||||
|
||||
while ((i = rawText.IndexOf('\n', i)) >= 0)
|
||||
{
|
||||
// Really, end in \r\n
|
||||
if (i < rawText.Length - 1 && // But if followed by tab or space,
|
||||
(rawText[i + 1] == ' ' || // this is only a continuation
|
||||
rawText[i + 1] == '\t'))
|
||||
{
|
||||
i += 2; // Skip \n and continutation whitespace
|
||||
}
|
||||
else if (quotedPrintable && // If preceded by = in quoted printable
|
||||
((i >= 1 && rawText[i - 1] == '=') || // this is a continuation
|
||||
(i >= 2 && rawText[i - 2] == '=')))
|
||||
{
|
||||
i++; // Skip \n
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
// No terminating end character? uh, done. Set i such that loop terminates and break
|
||||
i = max;
|
||||
}
|
||||
else if (i > matchStart)
|
||||
{
|
||||
// found a match
|
||||
if (matches == null)
|
||||
{
|
||||
matches = new List<List<String>>(1); // lazy init
|
||||
}
|
||||
if (i >= 1 && rawText[i - 1] == '\r')
|
||||
{
|
||||
i--; // Back up over \r, which really should be there
|
||||
}
|
||||
String element = rawText.Substring(matchStart, i - matchStart);
|
||||
if (trim)
|
||||
{
|
||||
element = element.Trim();
|
||||
}
|
||||
if (quotedPrintable)
|
||||
{
|
||||
element = decodeQuotedPrintable(element, quotedPrintableCharset);
|
||||
if (parseFieldDivider)
|
||||
{
|
||||
element = UNESCAPED_SEMICOLONS.Replace(element, "\n").Trim();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parseFieldDivider)
|
||||
{
|
||||
element = UNESCAPED_SEMICOLONS.Replace(element, "\n").Trim();
|
||||
}
|
||||
element = CR_LF_SPACE_TAB.Replace(element, "");
|
||||
element = NEWLINE_ESCAPE.Replace(element, "\n");
|
||||
element = VCARD_ESCAPES.Replace(element, "$1");
|
||||
}
|
||||
// Only handle VALUE=uri specially
|
||||
if ("uri".Equals(valueType))
|
||||
{
|
||||
// Don't actually support dereferencing URIs, but use scheme-specific part not URI
|
||||
// as value, to support tel: and mailto:
|
||||
try
|
||||
{
|
||||
Uri uri;
|
||||
if (Uri.TryCreate(element, UriKind.RelativeOrAbsolute, out uri))
|
||||
{
|
||||
element = uri.AbsoluteUri.Replace(uri.Scheme + ':', "");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (metadata == null)
|
||||
{
|
||||
var matched = new List<String>(1);
|
||||
matched.Add(element);
|
||||
matches.Add(matched);
|
||||
}
|
||||
else
|
||||
{
|
||||
metadata.Insert(0, element);
|
||||
matches.Add(metadata);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
private static String decodeQuotedPrintable(String value, String charset)
|
||||
{
|
||||
int length = value.Length;
|
||||
var result = new StringBuilder(length);
|
||||
var fragmentBuffer = new MemoryStream();
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = value[i];
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
break;
|
||||
case '=':
|
||||
if (i < length - 2)
|
||||
{
|
||||
char nextChar = value[i + 1];
|
||||
if (nextChar == '\r' || nextChar == '\n')
|
||||
{
|
||||
// Ignore, it's just a continuation symbol
|
||||
}
|
||||
else
|
||||
{
|
||||
char nextNextChar = value[i + 2];
|
||||
int firstDigit = parseHexDigit(nextChar);
|
||||
int secondDigit = parseHexDigit(nextNextChar);
|
||||
if (firstDigit >= 0 && secondDigit >= 0)
|
||||
{
|
||||
fragmentBuffer.WriteByte((byte)((firstDigit << 4) | secondDigit));
|
||||
} // else ignore it, assume it was incorrectly encoded
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
maybeAppendFragment(fragmentBuffer, charset, result);
|
||||
result.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
maybeAppendFragment(fragmentBuffer, charset, result);
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private static void maybeAppendFragment(MemoryStream fragmentBuffer,
|
||||
String charset,
|
||||
StringBuilder result)
|
||||
{
|
||||
if (fragmentBuffer.Length > 0)
|
||||
{
|
||||
byte[] fragmentBytes = fragmentBuffer.ToArray();
|
||||
String fragment;
|
||||
if (charset == null)
|
||||
{
|
||||
#if WindowsCE
|
||||
fragment = Encoding.Default.GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
#else
|
||||
fragment = Encoding.UTF8.GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
fragment = Encoding.GetEncoding(charset).GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if WindowsCE
|
||||
// WindowsCE doesn't support all encodings. But it is device depended.
|
||||
// So we try here the some different ones
|
||||
if (charset == "ISO-8859-1")
|
||||
{
|
||||
fragment = Encoding.GetEncoding(1252).GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragment = Encoding.Default.GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
}
|
||||
fragment = Encoding.Default.GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
#else
|
||||
fragment = Encoding.UTF8.GetString(fragmentBytes, 0, fragmentBytes.Length);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
fragmentBuffer.Seek(0, SeekOrigin.Begin);
|
||||
fragmentBuffer.SetLength(0);
|
||||
result.Append(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<String> matchSingleVCardPrefixedField(String prefix,
|
||||
String rawText,
|
||||
bool trim,
|
||||
bool parseFieldDivider)
|
||||
{
|
||||
List<List<String>> values = matchVCardPrefixedField(prefix, rawText, trim, parseFieldDivider);
|
||||
return values == null || values.Count == 0 ? null : values[0];
|
||||
}
|
||||
|
||||
private static String toPrimaryValue(List<String> list)
|
||||
{
|
||||
return list == null || list.Count == 0 ? null : list[0];
|
||||
}
|
||||
|
||||
private static String[] toPrimaryValues(ICollection<List<String>> lists)
|
||||
{
|
||||
if (lists == null || lists.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var result = new List<String>(lists.Count);
|
||||
foreach (var list in lists)
|
||||
{
|
||||
String value = list[0];
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
{
|
||||
result.Add(value);
|
||||
}
|
||||
}
|
||||
return SupportClass.toStringArray(result);
|
||||
}
|
||||
|
||||
private static String[] toTypes(ICollection<List<String>> lists)
|
||||
{
|
||||
if (lists == null || lists.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<String> result = new List<String>(lists.Count);
|
||||
foreach (var list in lists)
|
||||
{
|
||||
String value = list[0];
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
{
|
||||
String type = null;
|
||||
for (int i = 1; i < list.Count; i++)
|
||||
{
|
||||
String metadatum = list[i];
|
||||
int equals = metadatum.IndexOf('=');
|
||||
if (equals < 0)
|
||||
{
|
||||
// take the whole thing as a usable label
|
||||
type = metadatum;
|
||||
break;
|
||||
}
|
||||
if (String.Compare("TYPE", metadatum.Substring(0, equals), StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
type = metadatum.Substring(equals + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.Add(type);
|
||||
}
|
||||
}
|
||||
return SupportClass.toStringArray(result);
|
||||
}
|
||||
|
||||
private static bool isLikeVCardDate(String value)
|
||||
{
|
||||
return value == null || VCARD_LIKE_DATE.Match(value).Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats name fields of the form "Public;John;Q.;Reverend;III" into a form like
|
||||
* "Reverend John Q. Public III".
|
||||
*
|
||||
* @param names name values to format, in place
|
||||
*/
|
||||
private static void formatNames(IEnumerable<List<String>> names)
|
||||
{
|
||||
if (names != null)
|
||||
{
|
||||
foreach (var list in names)
|
||||
{
|
||||
String name = list[0];
|
||||
String[] components = new String[5];
|
||||
int start = 0;
|
||||
int end;
|
||||
int componentIndex = 0;
|
||||
while (componentIndex < components.Length - 1 && (end = name.IndexOf(';', start)) >= 0)
|
||||
{
|
||||
components[componentIndex] = name.Substring(start, end - start);
|
||||
|
||||
|
||||
componentIndex++;
|
||||
start = end + 1;
|
||||
}
|
||||
components[componentIndex] = name.Substring(start);
|
||||
StringBuilder newName = new StringBuilder(100);
|
||||
maybeAppendComponent(components, 3, newName);
|
||||
maybeAppendComponent(components, 1, newName);
|
||||
maybeAppendComponent(components, 2, newName);
|
||||
maybeAppendComponent(components, 0, newName);
|
||||
maybeAppendComponent(components, 4, newName);
|
||||
list.Insert(0, newName.ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void maybeAppendComponent(String[] components, int i, StringBuilder newName)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(components[i]))
|
||||
{
|
||||
if (newName.Length > 0)
|
||||
{
|
||||
newName.Append(' ');
|
||||
}
|
||||
newName.Append(components[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Others/zxing.core/zxing.core/client/result/VEventResultParser.cs
Normal file
146
Others/zxing.core/zxing.core/client/result/VEventResultParser.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Partially implements the iCalendar format's "VEVENT" format for specifying a
|
||||
/// calendar event. See RFC 2445. This supports SUMMARY, DTSTART and DTEND fields.
|
||||
/// </summary>
|
||||
/// <author> Sean Owen
|
||||
/// </author>
|
||||
/// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
|
||||
/// </author>
|
||||
sealed class VEventResultParser : ResultParser
|
||||
{
|
||||
override public ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
String rawText = result.Text;
|
||||
if (rawText == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int vEventStart = rawText.IndexOf("BEGIN:VEVENT");
|
||||
if (vEventStart < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String summary = matchSingleVCardPrefixedField("SUMMARY", rawText);
|
||||
String start = matchSingleVCardPrefixedField("DTSTART", rawText);
|
||||
if (start == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String end = matchSingleVCardPrefixedField("DTEND", rawText);
|
||||
String duration = matchSingleVCardPrefixedField("DURATION", rawText);
|
||||
String location = matchSingleVCardPrefixedField("LOCATION", rawText);
|
||||
String organizer = stripMailto(matchSingleVCardPrefixedField("ORGANIZER", rawText));
|
||||
|
||||
String[] attendees = matchVCardPrefixedField("ATTENDEE", rawText);
|
||||
if (attendees != null)
|
||||
{
|
||||
for (int i = 0; i < attendees.Length; i++)
|
||||
{
|
||||
attendees[i] = stripMailto(attendees[i]);
|
||||
}
|
||||
}
|
||||
String description = matchSingleVCardPrefixedField("DESCRIPTION", rawText);
|
||||
|
||||
String geoString = matchSingleVCardPrefixedField("GEO", rawText);
|
||||
double latitude;
|
||||
double longitude;
|
||||
if (geoString == null)
|
||||
{
|
||||
latitude = Double.NaN;
|
||||
longitude = Double.NaN;
|
||||
}
|
||||
else
|
||||
{
|
||||
int semicolon = geoString.IndexOf(';');
|
||||
if (semicolon < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#if WindowsCE
|
||||
try { latitude = Double.Parse(geoString.Substring(0, semicolon), NumberStyles.Float, CultureInfo.InvariantCulture); }
|
||||
catch { return null; }
|
||||
try { longitude = Double.Parse(geoString.Substring(semicolon + 1), NumberStyles.Float, CultureInfo.InvariantCulture); }
|
||||
catch { return null; }
|
||||
#else
|
||||
if (!Double.TryParse(geoString.Substring(0, semicolon), NumberStyles.Float, CultureInfo.InvariantCulture, out latitude))
|
||||
return null;
|
||||
if (!Double.TryParse(geoString.Substring(semicolon + 1), NumberStyles.Float, CultureInfo.InvariantCulture, out longitude))
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new CalendarParsedResult(summary,
|
||||
start,
|
||||
end,
|
||||
duration,
|
||||
location,
|
||||
organizer,
|
||||
attendees,
|
||||
description,
|
||||
latitude,
|
||||
longitude);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String matchSingleVCardPrefixedField(String prefix,
|
||||
String rawText)
|
||||
{
|
||||
var values = VCardResultParser.matchSingleVCardPrefixedField(prefix, rawText, true, false);
|
||||
return values == null || values.Count == 0 ? null : values[0];
|
||||
}
|
||||
|
||||
private static String[] matchVCardPrefixedField(String prefix, String rawText)
|
||||
{
|
||||
List<List<String>> values = VCardResultParser.matchVCardPrefixedField(prefix, rawText, true, false);
|
||||
if (values == null || values.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int size = values.Count;
|
||||
String[] result = new String[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
result[i] = values[i][0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String stripMailto(String s)
|
||||
{
|
||||
if (s != null && (s.StartsWith("mailto:") || s.StartsWith("MAILTO:")))
|
||||
{
|
||||
s = s.Substring(7);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
119
Others/zxing.core/zxing.core/client/result/VINParsedResult.cs
Normal file
119
Others/zxing.core/zxing.core/client/result/VINParsedResult.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes a Vehicle Identification Number (VIN).
|
||||
/// </summary>
|
||||
public class VINParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// VIN
|
||||
/// </summary>
|
||||
public String VIN { get; private set; }
|
||||
/// <summary>
|
||||
/// manufacturer id
|
||||
/// </summary>
|
||||
public String WorldManufacturerID { get; private set; }
|
||||
/// <summary>
|
||||
/// vehicle descriptor section
|
||||
/// </summary>
|
||||
public String VehicleDescriptorSection { get; private set; }
|
||||
/// <summary>
|
||||
/// vehicle identifier section
|
||||
/// </summary>
|
||||
public String VehicleIdentifierSection { get; private set; }
|
||||
/// <summary>
|
||||
/// country code
|
||||
/// </summary>
|
||||
public String CountryCode { get; private set; }
|
||||
/// <summary>
|
||||
/// vehicle attributes
|
||||
/// </summary>
|
||||
public String VehicleAttributes { get; private set; }
|
||||
/// <summary>
|
||||
/// model year
|
||||
/// </summary>
|
||||
public int ModelYear { get; private set; }
|
||||
/// <summary>
|
||||
/// plant code
|
||||
/// </summary>
|
||||
public char PlantCode { get; private set; }
|
||||
/// <summary>
|
||||
/// sequential number
|
||||
/// </summary>
|
||||
public String SequentialNumber { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="vin"></param>
|
||||
/// <param name="worldManufacturerID"></param>
|
||||
/// <param name="vehicleDescriptorSection"></param>
|
||||
/// <param name="vehicleIdentifierSection"></param>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <param name="vehicleAttributes"></param>
|
||||
/// <param name="modelYear"></param>
|
||||
/// <param name="plantCode"></param>
|
||||
/// <param name="sequentialNumber"></param>
|
||||
public VINParsedResult(String vin,
|
||||
String worldManufacturerID,
|
||||
String vehicleDescriptorSection,
|
||||
String vehicleIdentifierSection,
|
||||
String countryCode,
|
||||
String vehicleAttributes,
|
||||
int modelYear,
|
||||
char plantCode,
|
||||
String sequentialNumber)
|
||||
: base(ParsedResultType.VIN)
|
||||
{
|
||||
VIN = vin;
|
||||
WorldManufacturerID = worldManufacturerID;
|
||||
VehicleDescriptorSection = vehicleDescriptorSection;
|
||||
VehicleIdentifierSection = vehicleIdentifierSection;
|
||||
CountryCode = countryCode;
|
||||
VehicleAttributes = vehicleAttributes;
|
||||
ModelYear = modelYear;
|
||||
PlantCode = plantCode;
|
||||
SequentialNumber = sequentialNumber;
|
||||
}
|
||||
/// <summary>
|
||||
/// a user friendly representation
|
||||
/// </summary>
|
||||
public override string DisplayResult
|
||||
{
|
||||
get
|
||||
{
|
||||
var result = new StringBuilder(50);
|
||||
result.Append(WorldManufacturerID).Append(' ');
|
||||
result.Append(VehicleDescriptorSection).Append(' ');
|
||||
result.Append(VehicleIdentifierSection).Append('\n');
|
||||
if (CountryCode != null)
|
||||
{
|
||||
result.Append(CountryCode).Append(' ');
|
||||
}
|
||||
result.Append(ModelYear).Append(' ');
|
||||
result.Append(PlantCode).Append(' ');
|
||||
result.Append(SequentialNumber).Append('\n');
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
260
Others/zxing.core/zxing.core/client/result/VINResultParser.cs
Normal file
260
Others/zxing.core/zxing.core/client/result/VINResultParser.cs
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Detects a result that is likely a vehicle identification number.
|
||||
/// @author Sean Owen
|
||||
/// </summary>
|
||||
public class VINResultParser : ResultParser
|
||||
{
|
||||
#if SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE || UNITY || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
|
||||
private static readonly Regex IOQ = new Regex("[IOQ]");
|
||||
private static readonly Regex AZ09 = new Regex(@"\A(?:" + "[A-Z0-9]{17}" + @")\z");
|
||||
#else
|
||||
private static readonly Regex IOQ = new Regex("[IOQ]", RegexOptions.Compiled);
|
||||
private static readonly Regex AZ09 = new Regex(@"\A(?:" + "[A-Z0-9]{17}" + @")\z", RegexOptions.Compiled);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// attempt to parse the raw result to the specific type
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (result.BarcodeFormat != BarcodeFormat.CODE_39)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var rawText = result.Text;
|
||||
rawText = IOQ.Replace(rawText, "").Trim();
|
||||
var az09Match = AZ09.Match(rawText);
|
||||
if (!az09Match.Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!checkChecksum(rawText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var wmi = rawText.Substring(0, 3);
|
||||
return new VINParsedResult(rawText,
|
||||
wmi,
|
||||
rawText.Substring(3, 6),
|
||||
rawText.Substring(9, 8),
|
||||
countryCode(wmi),
|
||||
rawText.Substring(3, 5),
|
||||
modelYear(rawText[9]),
|
||||
rawText[10],
|
||||
rawText.Substring(11));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool checkChecksum(String vin)
|
||||
{
|
||||
var sum = 0;
|
||||
for (var i = 0; i < vin.Length; i++)
|
||||
{
|
||||
sum += vinPositionWeight(i + 1) * vinCharValue(vin[i]);
|
||||
}
|
||||
var currentCheckChar = vin[8];
|
||||
var expectedCheckChar = checkChar(sum % 11);
|
||||
return currentCheckChar == expectedCheckChar;
|
||||
}
|
||||
|
||||
private static int vinCharValue(char c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'I')
|
||||
{
|
||||
return (c - 'A') + 1;
|
||||
}
|
||||
if (c >= 'J' && c <= 'R')
|
||||
{
|
||||
return (c - 'J') + 1;
|
||||
}
|
||||
if (c >= 'S' && c <= 'Z')
|
||||
{
|
||||
return (c - 'S') + 2;
|
||||
}
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
throw new ArgumentException(c.ToString());
|
||||
}
|
||||
|
||||
private static int vinPositionWeight(int position)
|
||||
{
|
||||
if (position >= 1 && position <= 7)
|
||||
{
|
||||
return 9 - position;
|
||||
}
|
||||
if (position == 8)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
if (position == 9)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (position >= 10 && position <= 17)
|
||||
{
|
||||
return 19 - position;
|
||||
}
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
private static char checkChar(int remainder)
|
||||
{
|
||||
if (remainder < 10)
|
||||
{
|
||||
return (char)('0' + remainder);
|
||||
}
|
||||
if (remainder == 10)
|
||||
{
|
||||
return 'X';
|
||||
}
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
private static int modelYear(char c)
|
||||
{
|
||||
if (c >= 'E' && c <= 'H')
|
||||
{
|
||||
return (c - 'E') + 1984;
|
||||
}
|
||||
if (c >= 'J' && c <= 'N')
|
||||
{
|
||||
return (c - 'J') + 1988;
|
||||
}
|
||||
if (c == 'P')
|
||||
{
|
||||
return 1993;
|
||||
}
|
||||
if (c >= 'R' && c <= 'T')
|
||||
{
|
||||
return (c - 'R') + 1994;
|
||||
}
|
||||
if (c >= 'V' && c <= 'Y')
|
||||
{
|
||||
return (c - 'V') + 1997;
|
||||
}
|
||||
if (c >= '1' && c <= '9')
|
||||
{
|
||||
return (c - '1') + 2001;
|
||||
}
|
||||
if (c >= 'A' && c <= 'D')
|
||||
{
|
||||
return (c - 'A') + 2010;
|
||||
}
|
||||
throw new ArgumentException(c.ToString());
|
||||
}
|
||||
|
||||
private static String countryCode(String wmi)
|
||||
{
|
||||
char c1 = wmi[0];
|
||||
char c2 = wmi[1];
|
||||
switch (c1)
|
||||
{
|
||||
case '1':
|
||||
case '4':
|
||||
case '5':
|
||||
return "US";
|
||||
case '2':
|
||||
return "CA";
|
||||
case '3':
|
||||
if (c2 >= 'A' && c2 <= 'W')
|
||||
{
|
||||
return "MX";
|
||||
}
|
||||
break;
|
||||
case '9':
|
||||
if ((c2 >= 'A' && c2 <= 'E') || (c2 >= '3' && c2 <= '9'))
|
||||
{
|
||||
return "BR";
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if (c2 >= 'A' && c2 <= 'T')
|
||||
{
|
||||
return "JP";
|
||||
}
|
||||
break;
|
||||
case 'K':
|
||||
if (c2 >= 'L' && c2 <= 'R')
|
||||
{
|
||||
return "KO";
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
return "CN";
|
||||
case 'M':
|
||||
if (c2 >= 'A' && c2 <= 'E')
|
||||
{
|
||||
return "IN";
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (c2 >= 'A' && c2 <= 'M')
|
||||
{
|
||||
return "UK";
|
||||
}
|
||||
if (c2 >= 'N' && c2 <= 'T')
|
||||
{
|
||||
return "DE";
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
if (c2 >= 'F' && c2 <= 'R')
|
||||
{
|
||||
return "FR";
|
||||
}
|
||||
if (c2 >= 'S' && c2 <= 'W')
|
||||
{
|
||||
return "ES";
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
return "DE";
|
||||
case 'X':
|
||||
if (c2 == '0' || (c2 >= '3' && c2 <= '9'))
|
||||
{
|
||||
return "RU";
|
||||
}
|
||||
break;
|
||||
case 'Z':
|
||||
if (c2 >= 'A' && c2 <= 'R')
|
||||
{
|
||||
return "IT";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Others/zxing.core/zxing.core/client/result/WifiParsedResult.cs
Normal file
121
Others/zxing.core/zxing.core/client/result/WifiParsedResult.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2010 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a parsed result that encodes wifi network information, like SSID and password.
|
||||
/// </summary>
|
||||
/// <author>Vikram Aggarwal</author>
|
||||
public class WifiParsedResult : ParsedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="networkEncryption"></param>
|
||||
/// <param name="ssid"></param>
|
||||
/// <param name="password"></param>
|
||||
public WifiParsedResult(String networkEncryption, String ssid, String password)
|
||||
: this(networkEncryption, ssid, password, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="networkEncryption"></param>
|
||||
/// <param name="ssid"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="hidden"></param>
|
||||
public WifiParsedResult(String networkEncryption, String ssid, String password, bool hidden)
|
||||
: this(networkEncryption, ssid, password, hidden, null, null, null, null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initializing constructor
|
||||
/// </summary>
|
||||
/// <param name="networkEncryption"></param>
|
||||
/// <param name="ssid"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="hidden"></param>
|
||||
/// <param name="identity"></param>
|
||||
/// <param name="anonymousIdentity"></param>
|
||||
/// <param name="eapMethod"></param>
|
||||
/// <param name="phase2Method"></param>
|
||||
public WifiParsedResult(String networkEncryption, String ssid, String password, bool hidden, String identity, String anonymousIdentity, String eapMethod, String phase2Method)
|
||||
: base(ParsedResultType.WIFI)
|
||||
{
|
||||
Ssid = ssid;
|
||||
NetworkEncryption = networkEncryption;
|
||||
Password = password;
|
||||
Hidden = hidden;
|
||||
Identity = identity;
|
||||
AnonymousIdentity = anonymousIdentity;
|
||||
EapMethod = eapMethod;
|
||||
Phase2Method = phase2Method;
|
||||
|
||||
var result = new StringBuilder(80);
|
||||
maybeAppend(Ssid, result);
|
||||
maybeAppend(NetworkEncryption, result);
|
||||
maybeAppend(Password, result);
|
||||
maybeAppend(Hidden.ToString(), result);
|
||||
maybeAppend(Identity, result);
|
||||
maybeAppend(AnonymousIdentity, result);
|
||||
maybeAppend(EapMethod, result);
|
||||
maybeAppend(Phase2Method, result);
|
||||
displayResultValue = result.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SSID
|
||||
/// </summary>
|
||||
public String Ssid { get; private set; }
|
||||
/// <summary>
|
||||
/// network encryption
|
||||
/// </summary>
|
||||
public String NetworkEncryption { get; private set; }
|
||||
/// <summary>
|
||||
/// password
|
||||
/// </summary>
|
||||
public String Password { get; private set; }
|
||||
/// <summary>
|
||||
/// hidden flag
|
||||
/// </summary>
|
||||
public bool Hidden { get; private set; }
|
||||
/// <summary>
|
||||
/// identity
|
||||
/// </summary>
|
||||
public String Identity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// anonymous
|
||||
/// </summary>
|
||||
public String AnonymousIdentity { get; private set; }
|
||||
/// <summary>
|
||||
/// eap
|
||||
/// </summary>
|
||||
public String EapMethod { get; private set; }
|
||||
/// <summary>
|
||||
/// phase 2 method
|
||||
/// </summary>
|
||||
public String Phase2Method { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010 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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Client.Result
|
||||
{
|
||||
/// <summary>
|
||||
/// <p>Parses a WIFI configuration string. Strings will be of the form:</p>
|
||||
/// <p>{@code WIFI:T:[network type];S:[network SSID];P:[network password];H:[hidden?];;}</p>
|
||||
/// <p>The fields can appear in any order. Only "S:" is required.</p>
|
||||
/// <p>For WPA2 enterprise(EAP), strings will be of the form:</p>
|
||||
/// <p>{@code WIFI:T:WPA2-EAP;S:[network SSID];H:[hidden?];E:[EAP method];PH2:[Phase 2 method];A:[anonymous identity];I:[username];P:[password];;}</p>
|
||||
/// <p>"EAP method" can e.g.be "TTLS" or "PWD" or one of the other fields in <a href = "https://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.Eap.html"> WifiEnterpriseConfig.Eap </a> and "Phase 2 method" can e.g.be "MSCHAPV2" or any of the other fields in <a href = "https://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.Phase2.html"> WifiEnterpriseConfig.Phase2 </a></p>
|
||||
/// </summary>
|
||||
/// <author>Vikram Aggarwal</author>
|
||||
/// <author>Sean Owen</author>
|
||||
/// <author>Steffen Kieß</author>
|
||||
public class WifiResultParser : ResultParser
|
||||
{
|
||||
/// <summary>
|
||||
/// attempt to parse the raw result to the specific type
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public override ParsedResult parse(ZXing.Result result)
|
||||
{
|
||||
var rawText = result.Text;
|
||||
if (!rawText.StartsWith("WIFI:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
rawText = rawText.Substring("WIFI:".Length);
|
||||
var ssid = matchSinglePrefixedField("S:", rawText, ';', false);
|
||||
if (string.IsNullOrEmpty(ssid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var pass = matchSinglePrefixedField("P:", rawText, ';', false);
|
||||
var type = matchSinglePrefixedField("T:", rawText, ';', false) ?? "nopass";
|
||||
|
||||
// Unfortunately, in the past, H: was not just used for boolean 'hidden', but 'phase 2 method'.
|
||||
// To try to retain backwards compatibility, we set one or the other based on whether the string
|
||||
// is 'true' or 'false':
|
||||
bool hidden = false;
|
||||
String phase2Method = matchSinglePrefixedField("PH2:", rawText, ';', false);
|
||||
String hValue = matchSinglePrefixedField("H:", rawText, ';', false);
|
||||
if (hValue != null)
|
||||
{
|
||||
// If PH2 was specified separately, or if the value is clearly boolean, interpret it as 'hidden'
|
||||
if (phase2Method != null || String.Compare("true", hValue, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare("false", hValue, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
#if WindowsCE
|
||||
try { hidden = Boolean.Parse(hValue); } catch { }
|
||||
#else
|
||||
Boolean.TryParse(hValue, out hidden);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
phase2Method = hValue;
|
||||
}
|
||||
}
|
||||
|
||||
var identity = matchSinglePrefixedField("I:", rawText, ';', false);
|
||||
var anonymousIdentity = matchSinglePrefixedField("A:", rawText, ';', false);
|
||||
var eapMethod = matchSinglePrefixedField("E:", rawText, ';', false);
|
||||
|
||||
return new WifiParsedResult(type, ssid, pass, hidden, identity, anonymousIdentity, eapMethod, phase2Method);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user