From 2d7ef9faf4a148a80b8b3449fe335bdcf5f8553a Mon Sep 17 00:00:00 2001 From: srowen Date: Fri, 20 May 2011 07:12:49 +0000 Subject: [PATCH] Issue 742 at least parse iCal GEO in core library git-svn-id: https://zxing.googlecode.com/svn/trunk@1787 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../client/result/CalendarParsedResult.java | 23 ++++++++ .../client/result/VEventResultParser.java | 17 +++++- .../result/CalendarParsedResultTestCase.java | 57 ++++++++++++++++--- 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/core/src/com/google/zxing/client/result/CalendarParsedResult.java b/core/src/com/google/zxing/client/result/CalendarParsedResult.java index e2e4531ca..0300b475e 100644 --- a/core/src/com/google/zxing/client/result/CalendarParsedResult.java +++ b/core/src/com/google/zxing/client/result/CalendarParsedResult.java @@ -27,6 +27,8 @@ public final class CalendarParsedResult extends ParsedResult { private final String location; private final String attendee; private final String description; + private final double latitude; + private final double longitude; public CalendarParsedResult(String summary, String start, @@ -34,6 +36,17 @@ public final class CalendarParsedResult extends ParsedResult { String location, String attendee, String description) { + this(summary, start, end, location, attendee, description, Double.NaN, Double.NaN); + } + + public CalendarParsedResult(String summary, + String start, + String end, + String location, + String attendee, + String description, + double latitude, + double longitude) { super(ParsedResultType.CALENDAR); // Start is required, end is not if (start == null) { @@ -51,6 +64,8 @@ public final class CalendarParsedResult extends ParsedResult { this.location = location; this.attendee = attendee; this.description = description; + this.latitude = latitude; + this.longitude = longitude; } public String getSummary() { @@ -87,6 +102,14 @@ public final class CalendarParsedResult extends ParsedResult { return description; } + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + public String getDisplayResult() { StringBuffer result = new StringBuffer(100); maybeAppend(summary, result); diff --git a/core/src/com/google/zxing/client/result/VEventResultParser.java b/core/src/com/google/zxing/client/result/VEventResultParser.java index 2dd3ac663..b6278f2d9 100644 --- a/core/src/com/google/zxing/client/result/VEventResultParser.java +++ b/core/src/com/google/zxing/client/result/VEventResultParser.java @@ -20,7 +20,7 @@ import com.google.zxing.Result; /** * Partially implements the iCalendar format's "VEVENT" format for specifying a - * calendar event. See RFC 2445. This supports SUMMARY, LOCATION, DTSTART and DTEND fields. + * calendar event. See RFC 2445. This supports SUMMARY, LOCATION, GEO, DTSTART and DTEND fields. * * @author Sean Owen */ @@ -44,8 +44,21 @@ final class VEventResultParser extends ResultParser { String end = VCardResultParser.matchSingleVCardPrefixedField("DTEND", rawText, true); String location = VCardResultParser.matchSingleVCardPrefixedField("LOCATION", rawText, true); String description = VCardResultParser.matchSingleVCardPrefixedField("DESCRIPTION", rawText, true); + + String geoString = VCardResultParser.matchSingleVCardPrefixedField("GEO", rawText, true); + double latitude; + double longitude; + if (geoString == null) { + latitude = Double.NaN; + longitude = Double.NaN; + } else { + int semicolon = geoString.indexOf(';'); + latitude = Double.parseDouble(geoString.substring(0, semicolon)); + longitude = Double.parseDouble(geoString.substring(semicolon + 1)); + } + try { - return new CalendarParsedResult(summary, start, end, location, null, description); + return new CalendarParsedResult(summary, start, end, location, null, description, latitude, longitude); } catch (IllegalArgumentException iae) { return null; } diff --git a/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java b/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java index d8bdb368a..7e0f79287 100644 --- a/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java +++ b/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java @@ -28,6 +28,8 @@ import org.junit.Test; */ public final class CalendarParsedResultTestCase extends Assert { + private static final double EPSILON = 0.0000000001; + @Test public void testStartEnd() { doTest( @@ -35,7 +37,17 @@ public final class CalendarParsedResultTestCase extends Assert { "DTSTART:20080504T123456Z\r\n" + "DTEND:20080505T234555Z\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - null, null, null, "20080504T123456Z", "20080505T234555Z", null); + null, null, null, "20080504T123456Z", "20080505T234555Z"); + } + + @Test + public void testNoVCalendar() { + doTest( + "BEGIN:VEVENT\r\n" + + "DTSTART:20080504T123456Z\r\n" + + "DTEND:20080505T234555Z\r\n" + + "END:VEVENT", + null, null, null, "20080504T123456Z", "20080505T234555Z"); } @Test @@ -44,7 +56,7 @@ public final class CalendarParsedResultTestCase extends Assert { "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" + "DTSTART:20080504T123456Z\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - null, null, null, "20080504T123456Z", "20080504T123456Z", null); + null, null, null, "20080504T123456Z", "20080504T123456Z"); } @Test @@ -54,7 +66,7 @@ public final class CalendarParsedResultTestCase extends Assert { "SUMMARY:foo\r\n" + "DTSTART:20080504T123456Z\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - null, "foo", null, "20080504T123456Z", "20080504T123456Z", null); + null, "foo", null, "20080504T123456Z", "20080504T123456Z"); } @Test @@ -64,7 +76,7 @@ public final class CalendarParsedResultTestCase extends Assert { "LOCATION:Miami\r\n" + "DTSTART:20080504T123456Z\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - null, null, "Miami", "20080504T123456Z", "20080504T123456Z", null); + null, null, "Miami", "20080504T123456Z", "20080504T123456Z"); } @Test @@ -74,13 +86,32 @@ public final class CalendarParsedResultTestCase extends Assert { "DTSTART:20080504T123456Z\r\n" + "DESCRIPTION:This is a test\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - "This is a test", null, null, "20080504T123456Z", "20080504T123456Z", null); + "This is a test", null, null, "20080504T123456Z", "20080504T123456Z"); doTest( "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" + "DTSTART:20080504T123456Z\r\n" + "DESCRIPTION:This is a test\r\n\t with a continuation\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - "This is a test with a continuation", null, null, "20080504T123456Z", "20080504T123456Z", null); + "This is a test with a continuation", null, null, "20080504T123456Z", "20080504T123456Z"); + } + + @Test + public void testGeo() { + doTest( + "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" + + "DTSTART:20080504T123456Z\r\n" + + "GEO:-12.345;-45.678\r\n" + + "END:VEVENT\r\nEND:VCALENDAR", + null, null, null, "20080504T123456Z", "20080504T123456Z", null, -12.345, -45.678); + } + + private static void doTest(String contents, + String description, + String summary, + String location, + String start, + String end) { + doTest(contents, description, summary, location, start, end, null, Double.NaN, Double.NaN); } private static void doTest(String contents, @@ -89,7 +120,9 @@ public final class CalendarParsedResultTestCase extends Assert { String location, String start, String end, - String attendee) { + String attendee, + double latitude, + double longitude) { Result fakeResult = new Result(contents, null, null, BarcodeFormat.QR_CODE); ParsedResult result = ResultParser.parseResult(fakeResult); assertSame(ParsedResultType.CALENDAR, result.getType()); @@ -100,6 +133,16 @@ public final class CalendarParsedResultTestCase extends Assert { assertEquals(start, calResult.getStart()); assertEquals(end, calResult.getEnd()); assertEquals(attendee, calResult.getAttendee()); + assertEqualOrNaN(latitude, calResult.getLatitude()); + assertEqualOrNaN(longitude, calResult.getLongitude()); + } + + private static void assertEqualOrNaN(double expected, double actual) { + if (Double.isNaN(expected)) { + assertTrue(Double.isNaN(actual)); + } else { + assertEquals(expected, actual, EPSILON); + } } } \ No newline at end of file