/** * */ package com.intel.bluetooth; import java.io.IOException; import java.util.Enumeration; import java.util.Map; import javax.bluetooth.DataElement; import javax.bluetooth.UUID; import junit.framework.TestCase; /** * @author vlads * */ public class BlueZServiceRecordXMLTest extends TestCase { public static final String stringUTFData = "TODO";//"\u0413\u043E\u043B\u0443\u0431\u043E\u0439\u0417\u0443\u0431"; @SuppressWarnings("unchecked") public static boolean equals(DataElement de1, DataElement de2) { if ((de1 == null) || (de2 == null)) { return false; } try { if (de1.getDataType() != de2.getDataType()) { return false; } switch (de1.getDataType()) { case DataElement.U_INT_1: case DataElement.U_INT_2: case DataElement.U_INT_4: case DataElement.INT_1: case DataElement.INT_2: case DataElement.INT_4: case DataElement.INT_8: return (de1.getLong() == de2.getLong()); case DataElement.URL: case DataElement.STRING: case DataElement.UUID: return de1.getValue().equals(de2.getValue()); case DataElement.INT_16: case DataElement.U_INT_8: case DataElement.U_INT_16: byte[] byteAray1 = (byte[]) de1.getValue(); byte[] byteAray2 = (byte[]) de2.getValue(); if (byteAray1.length != byteAray2.length) { return false; } for (int k = 0; k < byteAray1.length; k++) { if (byteAray1[k] != byteAray2[k]) { return false; } } return true; case DataElement.NULL: return true; case DataElement.BOOL: return (de1.getBoolean() == de2.getBoolean()); case DataElement.DATSEQ: case DataElement.DATALT: Enumeration en1 = (Enumeration) de1.getValue(); Enumeration en2 = (Enumeration) de2.getValue(); for (; en1.hasMoreElements() && en2.hasMoreElements();) { DataElement d1 = (DataElement) en1.nextElement(); DataElement d2 = (DataElement) en2.nextElement(); if (!equals(d1, d2)) { return false; } } if (en1.hasMoreElements() || en2.hasMoreElements()) { return false; } return true; default: return false; } } catch (Throwable e) { e.printStackTrace(); return false; } } static public void assertEquals(String message, DataElement expected, DataElement actual) { if (equals(expected, actual)) { return; } fail(message + " expected:[" + expected + "] actual:" + actual + "]"); } private void assertParser(DataElement expected, int id, String[] xml) throws IOException { StringBuffer b = new StringBuffer(); for (String x : xml) { b.append(x).append('\n'); } Map<Integer, DataElement> elements = BlueZServiceRecordXML.parsXMLRecord(b.toString()); DataElement actual = elements.get(id); assertEquals(b.toString(), expected, actual); } public void testParserINT() throws IOException { assertParser(new DataElement(DataElement.U_INT_1, 0x4), 0, new String[] { "<record>", "<attribute id=\"0x0000\">", "<uint8 value=\"4\" />", "</attribute>", "</record>" }); assertParser(new DataElement(DataElement.U_INT_2, 0x2794), 0, new String[] { "<record>", "<attribute id=\"0x0000\">", "<uint16 value=\"0x2794\" />", "</attribute>", "</record>" }); assertParser(new DataElement(DataElement.U_INT_4, 0xabcdef40L), 0, new String[] { "<record>", "<attribute id=\"0x0000\">", "<uint32 value=\"0xabcdef40\" />", "</attribute>", "</record>" }); assertParser(new DataElement(DataElement.INT_1, 0x4), 0, new String[] { "<record>", "<attribute id=\"0x0000\">", "<int8 value=\"0x4\" />", "</attribute>", "</record>" }); assertParser(new DataElement(DataElement.INT_2, 0x584A), 0, new String[] { "<record>", "<attribute id=\"0x0000\">", "<int16 value=\"0x584A\" />", "</attribute>", "</record>" }); } private DataElement doubleCovert(DataElement element, StringBuffer b) throws Exception { b.append("<record>"); int id = 100; b.append("<attribute id=\"").append(id).append("\" >"); BlueZServiceRecordXML.appendDataElement(b, element); b.append("</attribute>"); b.append("</record>"); Map<Integer, DataElement> elements = BlueZServiceRecordXML.parsXMLRecord(b.toString()); assertEquals("Parsed elements", 1, elements.size()); return elements.get(id); } private void validateConversion(DataElement element) throws Exception { StringBuffer b = new StringBuffer(); boolean passed = false; DataElement elementConverted = null; try { elementConverted = doubleCovert(element, b); assertEquals("", element, elementConverted); passed = true; } finally { if (!passed) { System.out.println("ERROR: in " + ((Object) element).toString()); System.out.println("ERROR: out " + ((elementConverted == null)?"null":((Object) elementConverted).toString())); System.out.println("ERROR: in xml + " + b.toString()); } } } public void testIntTypes() throws Exception { validateConversion(new DataElement(DataElement.U_INT_1, 1)); validateConversion(new DataElement(DataElement.U_INT_2, 60)); validateConversion(new DataElement(DataElement.U_INT_4, 77839)); validateConversion(new DataElement(DataElement.INT_1, -7)); validateConversion(new DataElement(DataElement.INT_2, -5)); validateConversion(new DataElement(DataElement.INT_4, -25678)); validateConversion(new DataElement(DataElement.INT_8, 998652497)); validateConversion(new DataElement(DataElement.U_INT_1, 0)); validateConversion(new DataElement(DataElement.U_INT_1, 0xBC)); validateConversion(new DataElement(DataElement.U_INT_2, 0)); validateConversion(new DataElement(DataElement.U_INT_2, 0xABCD)); validateConversion(new DataElement(DataElement.U_INT_4, 0)); validateConversion(new DataElement(DataElement.U_INT_4, 0xABCDEF40l)); validateConversion(new DataElement(DataElement.INT_1, 0)); validateConversion(new DataElement(DataElement.INT_1, 0x4C)); validateConversion(new DataElement(DataElement.INT_1, -0x1E)); validateConversion(new DataElement(DataElement.INT_2, 0)); validateConversion(new DataElement(DataElement.INT_2, 0x5BCD)); validateConversion(new DataElement(DataElement.INT_2, -0x7EFD)); validateConversion(new DataElement(DataElement.INT_4, 0)); validateConversion(new DataElement(DataElement.INT_4, 0x1BCDEF35l)); validateConversion(new DataElement(DataElement.INT_4, -0x2BC7EF35l)); validateConversion(new DataElement(DataElement.INT_8, 0)); validateConversion(new DataElement(DataElement.INT_8, 0x3eC6EF355892EA8Cl)); validateConversion(new DataElement(DataElement.INT_8, -0x7F893012AB39FB72l)); validateConversion(new DataElement(DataElement.U_INT_8, new byte[] { 1, -2, 3, 4, -5, 6, 7, -8 })); validateConversion(new DataElement(DataElement.INT_16, new byte[] { 11, -22, 33, 44, -5, 6, 77, 88, 9, -10, 11, 12, -13, 14, 15, 16 })); validateConversion(new DataElement(DataElement.U_INT_16, new byte[] { 21, -32, 43, 54, -65, 76, 87, 98, 11, -110, 111, 112, -113, 114, 115, 16 })); } public void testUUID() throws Exception { validateConversion(new DataElement(DataElement.UUID, new UUID("0100", true))); validateConversion(new DataElement(DataElement.UUID, new UUID("B10C0BE1111111111111111111110001", false))); // This is the same UUIDs validateConversion(new DataElement(DataElement.UUID, new UUID("0000110500001000800000805f9b34fb", false))); validateConversion(new DataElement(DataElement.UUID, new UUID(0x1105))); // UUID 32-bit validateConversion(new DataElement(DataElement.UUID, new UUID(0x21301107))); } public void testString() throws Exception { validateConversion(new DataElement(DataElement.STRING, "")); validateConversion(new DataElement(DataElement.STRING, "12345")); validateConversion(new DataElement(DataElement.STRING, stringUTFData)); } public void testDATSEQ() throws Exception { DataElement seq1 = new DataElement(DataElement.DATSEQ); seq1.addElement(new DataElement(DataElement.STRING, "BlueCove-seq1")); seq1.addElement(new DataElement(DataElement.U_INT_1, 0x12)); seq1.addElement(new DataElement(DataElement.URL, "http://blueCove/")); seq1.addElement(new DataElement(DataElement.STRING, "AData")); seq1.addElement(new DataElement(DataElement.UUID, new UUID("B10C0BE1111111111111111111110001", false))); DataElement seq2 = new DataElement(DataElement.DATSEQ); seq2.addElement(new DataElement(DataElement.U_INT_8, new byte[] { 1, -2, 3, 4, -5, 6, 7, -8 })); seq2.addElement(new DataElement(DataElement.STRING, "DataData")); seq2.addElement(new DataElement(DataElement.U_INT_2, 0x14)); DataElement seq3 = new DataElement(DataElement.DATSEQ); seq3.addElement(new DataElement(DataElement.U_INT_4, 0x15)); seq3.addElement(new DataElement(DataElement.STRING, "MoreDataData")); seq3.addElement(new DataElement(DataElement.UUID, new UUID(0x1105))); seq3.addElement(new DataElement(DataElement.INT_8, 0x16)); seq1.addElement(seq2); seq1.addElement(seq3); seq1.addElement(new DataElement(DataElement.INT_4, 0x1BCDEF35l)); validateConversion(seq1); } public void testDATSEQ16() throws Exception { DataElement seq = new DataElement(DataElement.DATSEQ); // INT_8 = 9 bytes; int nElements = (0xFF / 9) + 1; for (int i = 0; i < nElements; i++) { seq.addElement(new DataElement(DataElement.INT_8, i)); } int l = SDPOutputStream.getLength(seq); assertTrue("DATSEQ16 len(" + l + ")>0xFF", l > 0xFF); assertTrue("DATSEQ16 len(" + l + ")<0xFFFF", l < 0xFFFF); validateConversion(seq); } public void testDATSEQ32() throws Exception { DataElement seq = new DataElement(DataElement.DATSEQ); // INT_8 = 9 bytes; int nElements = (0xFFFF / 9) + 1; for (int i = 0; i < nElements; i++) { seq.addElement(new DataElement(DataElement.INT_8, i)); } int l = SDPOutputStream.getLength(seq); assertTrue("DATSEQ32 len(" + l + ")>0xFFFF", l > 0xFFFF); validateConversion(seq); } public void testOtherAttributes() throws Exception { validateConversion(new DataElement(true)); validateConversion(new DataElement(false)); validateConversion(new DataElement(DataElement.NULL)); } }