From 103f9c225778383fb94559644b7b016e2c5df512 Mon Sep 17 00:00:00 2001 From: Anatol Pomazau Date: Tue, 12 Oct 2010 13:19:44 -0700 Subject: [PATCH] Add a util function that converts Text ndef record to text. Add a unit test for it. Change-Id: I5ce2020669150e3768a19354e951b6a54cc550d4 --- .../src/com/android/apps/tag/NdefUtil.java | 41 +++++++++++++++ .../com/android/apps/tag/NdefUtilTest.java | 51 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 apps/Tag/tests/src/com/android/apps/tag/NdefUtilTest.java diff --git a/apps/Tag/src/com/android/apps/tag/NdefUtil.java b/apps/Tag/src/com/android/apps/tag/NdefUtil.java index f2b01bbbe..3035c849b 100644 --- a/apps/Tag/src/com/android/apps/tag/NdefUtil.java +++ b/apps/Tag/src/com/android/apps/tag/NdefUtil.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableBiMap; import com.google.common.primitives.Bytes; import com.trustedlogic.trustednfc.android.NdefRecord; +import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charsets; @@ -147,4 +148,44 @@ public class NdefUtil { return false; } } + + /** + * Extracts payload text from Text type ndef record. + * + * @param record A ndef record. Must be {@link NdefRecord#TYPE_TEXT}. + * @return text payload. + */ + public static String toText(NdefRecord record) { + Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN_TYPE); + Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.TYPE_TEXT)); + try { + + byte[] payload = record.getPayload(); + + /* + * payload[0] contains the "Status Byte Encodings" field, per + * the NFC Forum "Text Record Type Definition" section 3.2.1. + * + * bit7 is the Text Encoding Field. + * + * if (Bit_7 == 0): The text is encoded in UTF-8 + * if (Bit_7 == 1): The text is encoded in UTF16 + * + * Bit_6 is reserved for future use and must be set to zero. + * + * Bits 5 to 0 are the length of the IANA language code. + */ + + String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16"; + int languageCodeLength = payload[0] & 0077; + + return new String(payload, + languageCodeLength + 1, + payload.length - languageCodeLength - 1, + textEncoding); + } catch (UnsupportedEncodingException e) { + // should never happen unless we get a malformed tag. + throw new RuntimeException(e); + } + } } diff --git a/apps/Tag/tests/src/com/android/apps/tag/NdefUtilTest.java b/apps/Tag/tests/src/com/android/apps/tag/NdefUtilTest.java new file mode 100644 index 000000000..ee6e56b7a --- /dev/null +++ b/apps/Tag/tests/src/com/android/apps/tag/NdefUtilTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apps.tag; + +import android.test.AndroidTestCase; +import com.google.common.primitives.Bytes; +import com.trustedlogic.trustednfc.android.NdefRecord; + +import java.io.UnsupportedEncodingException; + +public class NdefUtilTest extends AndroidTestCase { + public void testToText() throws UnsupportedEncodingException { + checkWord("Hello", "en-US", true); + checkWord("Hello", "en-US", false); + checkWord("abc\\u5639\\u563b", "cp1251", true); + checkWord("abc\\u5639\\u563b", "cp1251", false); + } + + private static void checkWord(String word, String encoding, boolean isUtf8) throws UnsupportedEncodingException { + String utfEncoding = isUtf8 ? "UTF-8" : "UTF-16"; + + byte[] encodingBytes = encoding.getBytes("US-ASCII"); + byte[] text = word.getBytes(utfEncoding); + + int utfBit = isUtf8 ? 0 : (1 << 7); + char status = (char) (utfBit + encodingBytes.length); + + byte[] data = Bytes.concat( + new byte[] { (byte) status }, + encodingBytes, + text + ); + + NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN_TYPE, NdefRecord.TYPE_TEXT, new byte[0], data); + assertEquals(word, NdefUtil.toText(record)); + } +}